diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000000..f0c8c7f4c5 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,5 @@ +{ + "permissions": { + "defaultMode": "bypassPermissions" + } +} \ No newline at end of file diff --git a/.github/actions/setup-node-env/action.yml b/.github/actions/setup-node-env/action.yml index 334cd3c24f..9c4ba4be07 100644 --- a/.github/actions/setup-node-env/action.yml +++ b/.github/actions/setup-node-env/action.yml @@ -52,7 +52,8 @@ runs: if: inputs.install-bun == 'true' uses: oven-sh/setup-bun@v2 with: - bun-version: "1.3.9+cf6cdbbba" + bun-version: latest + github-token: ${{ github.token }} - name: Runtime versions shell: bash diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 60e42dd572..d3dba157ff 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -379,6 +379,11 @@ jobs: pnpm-version: "10.23.0" cache-key-suffix: "node22" + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + github-token: ${{ github.token }} - name: Runtime versions run: | node -v diff --git a/.gitignore b/.gitignore index 4278a24b0f..d74944aa78 100644 --- a/.gitignore +++ b/.gitignore @@ -72,16 +72,43 @@ apps/ios/*.dSYM.zip # provisioning profiles (local) apps/ios/*.mobileprovision +# Test scripts and folder (local use, not for distribution) +test/ + +# Docs research/analysis (internal use, not for distribution) +docs/research/ +docs/WEB_API_TESTS_STATUS.md +docs/WEB_PLATFORMS_RESEARCH.md + +# Local commit notes +COMMIT_SUMMARY.md + # Local untracked files .local/ +.openclaw-state/ +.openclaw-zero-state/ +.kiro/ docs/.local/ -IDENTITY.md -USER.md .tgz .idea +# User-specific config files (but allow templates) +IDENTITY.md +USER.md +# Exception: allow template files +!docs/reference/templates/IDENTITY.md +!docs/reference/templates/USER.md + +# Gateway PID file +.gateway.pid + +# Claude cookie files (sensitive) +claudecookie.txt +*.cookie.txt + # local tooling .serena/ +dev-debug.sh # Agent credentials and memory (NEVER COMMIT) /memory/ @@ -93,3 +120,22 @@ package-lock.json # Local iOS signing overrides apps/ios/LocalSigning.xcconfig + +# Temporary logs and test outputs +*.log +lint_output*.txt +ts_errors*.txt +test-*.mjs +test-doubao-*.js +analyze-doubao*.ts +scripts/analyze-doubao*.ts +scripts/analyze-doubao*.js +solve-wasm.mjs +verify-final.mjs +patch-client.mjs +research-deepseek.mjs +sha3_wasm_b64.txt +sha3_wasm_bg.wasm +solve-wasm.mjs +FILES_TO_CLEANUP.md +.vscode/settings.json diff --git a/.openclaw-state.example/README.en.md b/.openclaw-state.example/README.en.md new file mode 100644 index 0000000000..026165a15a --- /dev/null +++ b/.openclaw-state.example/README.en.md @@ -0,0 +1,237 @@ +# OpenClaw State Directory Example + +English | [简体中文](README.md) + +Example configuration files for the `.openclaw-zero-state/` directory. + +## Directory Structure + +``` +.openclaw-zero-state/ +├── openclaw.json # Main config file +└── agents/ + └── main/ + └── agent/ + └── auth-profiles.json # Auth credentials (sensitive) +``` + +## Important Notes + +⚠️ **The `.openclaw-zero-state/` directory contains sensitive information and should NOT be committed to Git!** + +- Excluded in `.gitignore` +- Contains auth credentials (sessionKey, cookies, etc.) +- Contains personal config and workspace data + +## First Run + +The `.openclaw-zero-state/` directory is created automatically on first run. + +⚠️ **Important:** `openclaw.json` must not be empty, or the Gateway will fail to start. On first run, the full config template is automatically copied from `.openclaw-state.example/openclaw.json`. + +### Auto-Create (Recommended) + +When running the config wizard or `server.sh`, if `.openclaw-zero-state/openclaw.json` does not exist, it is automatically copied from the example: + +```bash +./onboard.sh +# or +./server.sh start +``` + +**What gets created:** +1. ✅ `.openclaw-zero-state/` directory +2. ✅ `openclaw.json` config file (copied from `.openclaw-state.example/openclaw.json`, not empty) +3. ✅ `agents/main/agent/` subdirectory +4. ✅ `agents/main/sessions/` sessions directory +5. ✅ `credentials/` directory +6. ✅ `auth-profiles.json` auth file (after config completes) + +**What you need to do:** +1. Run `./onboard.sh` or `./server.sh start` +2. Select AI provider (e.g. Claude Web) +3. Log in via the browser +4. Wait for the system to save credentials + +**No manual file or directory creation required!** + +### Manual Create (Optional) + +If auto-copy does not work (e.g. example file missing), copy manually: + +```bash +mkdir -p .openclaw-zero-state +cp .openclaw-state.example/openclaw.json .openclaw-zero-state/openclaw.json +``` + +Then edit `.openclaw-zero-state/openclaw.json` and at least update: +- `workspace` path (to your actual path) +- `gateway.auth.token` (generate a random token) + +## Config File Reference + +### openclaw.json + +Main config file (minimal template), includes: + +- **browser**: Browser config (CDP connection) +- **models**: AI model config (initially empty) +- **agents**: Agent defaults +- **gateway**: Gateway service config + +### Onboard Incremental Write (Important) + +`openclaw.json` uses **on-demand incremental writes**, not a single full write: + +1. Initial template has empty `models.providers` and `agents.defaults.models` +2. Each time you complete a platform auth in `./onboard.sh` +3. Only that platform’s provider/models/alias are written + +**Platforms not completed in onboard will not appear in the runtime `openclaw.json`.** + +Minimal template example: + +```json +{ + "models": { "mode": "merge", "providers": {} }, + "agents": { "defaults": { "models": {} } } +} +``` + +### auth-profiles.json + +Auth credentials file, contains: + +- Claude Web sessionKey +- DeepSeek Web cookie +- Doubao Web sessionid +- Other API keys + +**Example format:** + +```json +{ + "version": 1, + "profiles": { + "claude-web:default": { + "type": "api_key", + "provider": "claude-web", + "key": "{\"sessionKey\":\"sk-ant-sid02-...\",\"userAgent\":\"...\"}" + } + } +} +``` + +## Path Configuration + +### macOS + +```json +{ + "agents": { + "defaults": { + "workspace": "/Users/YOUR_USERNAME/Documents/openclaw-zero-token/.openclaw-zero-state/workspace" + } + } +} +``` + +### Linux + +```json +{ + "agents": { + "defaults": { + "workspace": "/home/YOUR_USERNAME/Documents/openclaw-zero-token/.openclaw-zero-state/workspace" + } + } +} +``` + +## Security Recommendations + +1. ✅ Ensure `.openclaw-zero-state/` is in `.gitignore` +2. ✅ Do not share `auth-profiles.json` +3. ✅ Rotate expired credentials regularly +4. ✅ Use a strong random Gateway Token + +## Troubleshooting + +### First Run: Use Config Wizard (Recommended) + +**On first run, start the config wizard:** + +```bash +./onboard.sh +``` + +**The wizard will create:** +- ✅ `.openclaw-zero-state/` directory +- ✅ `openclaw.json` config file (copied from example if missing) +- ✅ `agents/main/agent/` directory +- ✅ `agents/main/sessions/` directory +- ✅ `credentials/` directory +- ✅ `auth-profiles.json` auth file (after config completes) + +**No manual creation needed!** + +### Fix Issues: Use Doctor Command + +**If the project has run before but directories/files are missing:** + +```bash +node dist/index.mjs doctor +``` + +**⚠️ Note: The `doctor` command will only:** +- ✅ Check and create missing **directories** +- ✅ Fix file permissions +- ❌ **Not** create config file (`openclaw.json`) +- ❌ **Not** create auth file (`auth-profiles.json`) + +**Use when:** +- Directories were accidentally deleted +- File permission issues +- Config file corrupted (re-run `onboard.sh`) +- Verifying environment + +**Example output:** +``` +State integrity +- CRITICAL: Sessions dir missing (~/.openclaw-zero/agents/main/sessions) +? Create Sessions dir at ~/.openclaw-zero/agents/main/sessions? (Y/n) + +Doctor changes +- Created Sessions dir: ~/.openclaw-zero/agents/main/sessions +- Tightened permissions on ~/.openclaw-zero to 700 +``` + +### Config File Missing or Corrupted + +```bash +# Running onboard or server will auto-copy config from .openclaw-state.example/openclaw.json +./onboard.sh +# or +./server.sh start +``` + +### Path Errors + +Check and update the `workspace` path in `openclaw.json`: + +```bash +# macOS +sed -i '' 's|/home/|/Users/|g' .openclaw-zero-state/openclaw.json + +# Linux +sed -i 's|/Users/|/home/|g' .openclaw-zero-state/openclaw.json +``` + +### Auth Failure + +Remove old auth file and reconfigure: + +```bash +rm .openclaw-zero-state/agents/main/agent/auth-profiles.json +./onboard.sh +``` diff --git a/.openclaw-state.example/README.md b/.openclaw-state.example/README.md new file mode 100644 index 0000000000..416d6e8695 --- /dev/null +++ b/.openclaw-state.example/README.md @@ -0,0 +1,237 @@ +# OpenClaw State Directory Example + +[English](README.en.md) | 简体中文 + +这是 `.openclaw-zero-state/` 目录的示例配置文件。 + +## 目录结构 + +``` +.openclaw-zero-state/ +├── openclaw.json # 主配置文件 +└── agents/ + └── main/ + └── agent/ + └── auth-profiles.json # 认证凭证(敏感信息) +``` + +## 重要说明 + +⚠️ **`.openclaw-zero-state/` 目录包含敏感信息,不应该提交到 Git!** + +- 已在 `.gitignore` 中排除 +- 包含认证凭证(sessionKey、cookie 等) +- 包含个人配置和工作空间数据 + +## 首次运行 + +首次运行时,`.openclaw-zero-state/` 目录会自动创建。 + +⚠️ **重要**:`openclaw.json` 不能为空,否则 Gateway 无法正常启动。首次运行时会自动从 `.openclaw-state.example/openclaw.json` 复制完整配置模板。 + +### 自动创建(推荐) + +运行配置向导或 `server.sh` 时,若 `.openclaw-zero-state/openclaw.json` 不存在,会自动从示例复制: + +```bash +./onboard.sh +# 或 +./server.sh start +``` + +**自动创建的内容:** +1. ✅ `.openclaw-zero-state/` 目录 +2. ✅ `openclaw.json` 配置文件(从 `.openclaw-state.example/openclaw.json` 复制,非空) +3. ✅ `agents/main/agent/` 子目录 +4. ✅ `agents/main/sessions/` 会话目录 +5. ✅ `credentials/` 认证目录 +6. ✅ `auth-profiles.json` 认证凭证文件(配置完成后) + +**你需要做的:** +1. 运行 `./onboard.sh` 或 `./server.sh start` +2. 选择 AI 提供商(如 Claude Web) +3. 在浏览器中登录账号 +4. 等待系统自动保存凭证 + +**完全不需要手动创建任何文件或目录!** + +### 手动创建(可选) + +若自动复制未生效(例如示例文件不存在),可手动复制: + +```bash +mkdir -p .openclaw-zero-state +cp .openclaw-state.example/openclaw.json .openclaw-zero-state/openclaw.json +``` + +然后编辑 `.openclaw-zero-state/openclaw.json`,至少修改: +- `workspace` 路径(改为你的实际路径) +- `gateway.auth.token`(生成一个随机 token) + +## 配置文件说明 + +### openclaw.json + +主配置文件(最小模板),包含: + +- **browser**: 浏览器配置(CDP 连接) +- **models**: AI 模型配置(初始为空) +- **agents**: Agent 默认配置 +- **gateway**: Gateway 服务配置 + +### onboard 增量写入机制(重要) + +`openclaw.json` 采用**按需增量写入**,不是一次性写入所有平台: + +1. 初始模板里 `models.providers` 和 `agents.defaults.models` 为空 +2. 每次你在 `./onboard.sh` 里选择并完成一个平台认证 +3. 系统仅写入该平台对应的 provider/models/alias + +也就是说:**没有在 onboard 里选过的平台,不会出现在运行态 `openclaw.json` 中。** + +最小模板示意: + +```json +{ + "models": { "mode": "merge", "providers": {} }, + "agents": { "defaults": { "models": {} } } +} +``` + +### auth-profiles.json + +认证凭证文件,包含: + +- Claude Web sessionKey +- DeepSeek Web cookie +- Doubao Web sessionid +- 其他 API keys + +**格式示例:** + +```json +{ + "version": 1, + "profiles": { + "claude-web:default": { + "type": "api_key", + "provider": "claude-web", + "key": "{\"sessionKey\":\"sk-ant-sid02-...\",\"userAgent\":\"...\"}" + } + } +} +``` + +## 路径配置 + +### macOS + +```json +{ + "agents": { + "defaults": { + "workspace": "/Users/YOUR_USERNAME/Documents/openclaw-zero-token/.openclaw-zero-state/workspace" + } + } +} +``` + +### Linux + +```json +{ + "agents": { + "defaults": { + "workspace": "/home/YOUR_USERNAME/Documents/openclaw-zero-token/.openclaw-zero-state/workspace" + } + } +} +``` + +## 安全建议 + +1. ✅ 确保 `.openclaw-zero-state/` 在 `.gitignore` 中 +2. ✅ 不要分享 `auth-profiles.json` 文件 +3. ✅ 定期更新过期的认证凭证 +4. ✅ 使用强随机 Gateway Token + +## 故障排查 + +### 首次运行:使用配置向导(推荐) + +**首次运行项目时,直接运行配置向导:** + +```bash +./onboard.sh +``` + +**配置向导会自动创建:** +- ✅ `.openclaw-zero-state/` 目录 +- ✅ `openclaw.json` 配置文件(从示例复制,若不存在) +- ✅ `agents/main/agent/` 目录 +- ✅ `agents/main/sessions/` 目录 +- ✅ `credentials/` 目录 +- ✅ `auth-profiles.json` 认证文件(配置完成后) + +**完全不需要手动创建任何文件或目录!** + +### 修复问题:使用诊断命令 + +**如果项目已经运行过,但遇到目录或文件缺失问题,运行诊断命令:** + +```bash +node dist/index.mjs doctor +``` + +**⚠️ 注意:`doctor` 命令只会:** +- ✅ 检查和创建缺失的**目录** +- ✅ 修复文件权限问题 +- ❌ **不会**创建配置文件(`openclaw.json`) +- ❌ **不会**创建认证文件(`auth-profiles.json`) + +**使用场景:** +- 目录被意外删除 +- 文件权限出现问题 +- 配置文件损坏(需要重新运行 `onboard.sh`) +- 验证环境是否正常 + +**示例输出:** +``` +State integrity +- CRITICAL: Sessions dir missing (~/.openclaw-zero/agents/main/sessions) +? Create Sessions dir at ~/.openclaw-zero/agents/main/sessions? (Y/n) + +Doctor changes +- Created Sessions dir: ~/.openclaw-zero/agents/main/sessions +- Tightened permissions on ~/.openclaw-zero to 700 +``` + +### 配置文件不存在或损坏 + +```bash +# 运行 onboard 或 server 会自动从 .openclaw-state.example/openclaw.json 复制配置 +./onboard.sh +# 或 +./server.sh start +``` + +### 路径错误 + +检查并修改 `openclaw.json` 中的 `workspace` 路径: + +```bash +# macOS +sed -i '' 's|/home/|/Users/|g' .openclaw-zero-state/openclaw.json + +# Linux +sed -i 's|/Users/|/home/|g' .openclaw-zero-state/openclaw.json +``` + +### 认证失败 + +删除旧的认证文件,重新配置: + +```bash +rm .openclaw-zero-state/agents/main/agent/auth-profiles.json +./onboard.sh +``` diff --git a/.openclaw-state.example/openclaw.json b/.openclaw-state.example/openclaw.json new file mode 100644 index 0000000000..6ec87fb62a --- /dev/null +++ b/.openclaw-state.example/openclaw.json @@ -0,0 +1,63 @@ +{ + "meta": { + "lastTouchedVersion": "2026.2.19", + "lastTouchedAt": "2026-03-06T23:04:03.000Z" + }, + "wizard": { + "lastRunAt": "2026-03-06T23:04:03.000Z", + "lastRunVersion": "2026.2.19", + "lastRunCommand": "onboard", + "lastRunMode": "local" + }, + "browser": { + "attachOnly": true, + "defaultProfile": "openclaw", + "profiles": { + "openclaw": { + "cdpUrl": "http://127.0.0.1:9222", + "color": "#4285F4" + } + } + }, + "models": { + "mode": "merge", + "providers": {} + }, + "agents": { + "defaults": { + "models": {}, + "workspace": "~/.openclaw-zero/workspace" + } + }, + "ui": { + "assistant": { + "name": "OpenClaw", + "avatar": "🦞" + } + }, + "commands": { + "native": "auto", + "nativeSkills": "auto", + "restart": true + }, + "gateway": { + "port": 3001, + "mode": "local", + "bind": "loopback", + "auth": { + "mode": "token", + "token": "62b791625fa441be036acd3c206b7e14e2bb13c803355823" + }, + "tailscale": { + "mode": "off", + "resetOnExit": false + }, + "http": { + "endpoints": { + "chatCompletions": { + "enabled": true + } + } + } + } +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index 99e2f7ddf7..0000000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "recommendations": ["oxc.oxc-vscode"] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index e291954cfc..0000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "editor.formatOnSave": true, - "files.insertFinalNewline": true, - "files.trimFinalNewlines": true, - "[javascript]": { - "editor.defaultFormatter": "oxc.oxc-vscode" - }, - "[typescriptreact]": { - "editor.defaultFormatter": "oxc.oxc-vscode" - }, - "[typescript]": { - "editor.defaultFormatter": "oxc.oxc-vscode" - }, - "[json]": { - "editor.defaultFormatter": "oxc.oxc-vscode" - }, - "typescript.preferences.importModuleSpecifierEnding": "js", - "typescript.reportStyleChecksAsWarnings": false, - "typescript.updateImportsOnFileMove.enabled": "always", - "typescript.tsdk": "node_modules/typescript/lib", - "typescript.experimental.useTsgo": true -} diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index 5e589d336d..0000000000 --- a/AGENTS.md +++ /dev/null @@ -1,239 +0,0 @@ -# Repository Guidelines - -- Repo: https://github.com/openclaw/openclaw -- GitHub issues/comments/PR comments: use literal multiline strings or `-F - <<'EOF'` (or $'...') for real newlines; never embed "\\n". - -## Project Structure & Module Organization - -- Source code: `src/` (CLI wiring in `src/cli`, commands in `src/commands`, web provider in `src/provider-web.ts`, infra in `src/infra`, media pipeline in `src/media`). -- Tests: colocated `*.test.ts`. -- Docs: `docs/` (images, queue, Pi config). Built output lives in `dist/`. -- Plugins/extensions: live under `extensions/*` (workspace packages). Keep plugin-only deps in the extension `package.json`; do not add them to the root `package.json` unless core uses them. -- Plugins: install runs `npm install --omit=dev` in plugin dir; runtime deps must live in `dependencies`. Avoid `workspace:*` in `dependencies` (npm install breaks); put `openclaw` in `devDependencies` or `peerDependencies` instead (runtime resolves `openclaw/plugin-sdk` via jiti alias). -- Installers served from `https://openclaw.ai/*`: live in the sibling repo `../openclaw.ai` (`public/install.sh`, `public/install-cli.sh`, `public/install.ps1`). -- Messaging channels: always consider **all** built-in + extension channels when refactoring shared logic (routing, allowlists, pairing, command gating, onboarding, docs). - - Core channel docs: `docs/channels/` - - Core channel code: `src/telegram`, `src/discord`, `src/slack`, `src/signal`, `src/imessage`, `src/web` (WhatsApp web), `src/channels`, `src/routing` - - Extensions (channel plugins): `extensions/*` (e.g. `extensions/msteams`, `extensions/matrix`, `extensions/zalo`, `extensions/zalouser`, `extensions/voice-call`) -- When adding channels/extensions/apps/docs, update `.github/labeler.yml` and create matching GitHub labels (use existing channel/extension label colors). - -## Docs Linking (Mintlify) - -- Docs are hosted on Mintlify (docs.openclaw.ai). -- Internal doc links in `docs/**/*.md`: root-relative, no `.md`/`.mdx` (example: `[Config](/configuration)`). -- When working with documentation, read the mintlify skill. -- Section cross-references: use anchors on root-relative paths (example: `[Hooks](/configuration#hooks)`). -- Doc headings and anchors: avoid em dashes and apostrophes in headings because they break Mintlify anchor links. -- When Peter asks for links, reply with full `https://docs.openclaw.ai/...` URLs (not root-relative). -- When you touch docs, end the reply with the `https://docs.openclaw.ai/...` URLs you referenced. -- README (GitHub): keep absolute docs URLs (`https://docs.openclaw.ai/...`) so links work on GitHub. -- Docs content must be generic: no personal device names/hostnames/paths; use placeholders like `user@gateway-host` and “gateway host”. - -## Docs i18n (zh-CN) - -- `docs/zh-CN/**` is generated; do not edit unless the user explicitly asks. -- Pipeline: update English docs → adjust glossary (`docs/.i18n/glossary.zh-CN.json`) → run `scripts/docs-i18n` → apply targeted fixes only if instructed. -- Translation memory: `docs/.i18n/zh-CN.tm.jsonl` (generated). -- See `docs/.i18n/README.md`. -- The pipeline can be slow/inefficient; if it’s dragging, ping @jospalmbier on Discord instead of hacking around it. - -## exe.dev VM ops (general) - -- Access: stable path is `ssh exe.dev` then `ssh vm-name` (assume SSH key already set). -- SSH flaky: use exe.dev web terminal or Shelley (web agent); keep a tmux session for long ops. -- Update: `sudo npm i -g openclaw@latest` (global install needs root on `/usr/lib/node_modules`). -- Config: use `openclaw config set ...`; ensure `gateway.mode=local` is set. -- Discord: store raw token only (no `DISCORD_BOT_TOKEN=` prefix). -- Restart: stop old gateway and run: - `pkill -9 -f openclaw-gateway || true; nohup openclaw gateway run --bind loopback --port 18789 --force > /tmp/openclaw-gateway.log 2>&1 &` -- Verify: `openclaw channels status --probe`, `ss -ltnp | rg 18789`, `tail -n 120 /tmp/openclaw-gateway.log`. - -## Build, Test, and Development Commands - -- Runtime baseline: Node **22+** (keep Node + Bun paths working). -- Install deps: `pnpm install` -- If deps are missing (for example `node_modules` missing, `vitest not found`, or `command not found`), run the repo’s package-manager install command (prefer lockfile/README-defined PM), then rerun the exact requested command once. Apply this to test/build/lint/typecheck/dev commands; if retry still fails, report the command and first actionable error. -- Pre-commit hooks: `prek install` (runs same checks as CI) -- Also supported: `bun install` (keep `pnpm-lock.yaml` + Bun patching in sync when touching deps/patches). -- Prefer Bun for TypeScript execution (scripts, dev, tests): `bun ` / `bunx `. -- Run CLI in dev: `pnpm openclaw ...` (bun) or `pnpm dev`. -- Node remains supported for running built output (`dist/*`) and production installs. -- Mac packaging (dev): `scripts/package-mac-app.sh` defaults to current arch. Release checklist: `docs/platforms/mac/release.md`. -- Type-check/build: `pnpm build` -- TypeScript checks: `pnpm tsgo` -- Lint/format: `pnpm check` -- Format check: `pnpm format` (oxfmt --check) -- Format fix: `pnpm format:fix` (oxfmt --write) -- Tests: `pnpm test` (vitest); coverage: `pnpm test:coverage` - -## Coding Style & Naming Conventions - -- Language: TypeScript (ESM). Prefer strict typing; avoid `any`. -- Formatting/linting via Oxlint and Oxfmt; run `pnpm check` before commits. -- Never add `@ts-nocheck` and do not disable `no-explicit-any`; fix root causes and update Oxlint/Oxfmt config only when required. -- Never share class behavior via prototype mutation (`applyPrototypeMixins`, `Object.defineProperty` on `.prototype`, or exporting `Class.prototype` for merges). Use explicit inheritance/composition (`A extends B extends C`) or helper composition so TypeScript can typecheck. -- If this pattern is needed, stop and get explicit approval before shipping; default behavior is to split/refactor into an explicit class hierarchy and keep members strongly typed. -- In tests, prefer per-instance stubs over prototype mutation (`SomeClass.prototype.method = ...`) unless a test explicitly documents why prototype-level patching is required. -- Add brief code comments for tricky or non-obvious logic. -- Keep files concise; extract helpers instead of “V2” copies. Use existing patterns for CLI options and dependency injection via `createDefaultDeps`. -- Aim to keep files under ~700 LOC; guideline only (not a hard guardrail). Split/refactor when it improves clarity or testability. -- Naming: use **OpenClaw** for product/app/docs headings; use `openclaw` for CLI command, package/binary, paths, and config keys. - -## Release Channels (Naming) - -- stable: tagged releases only (e.g. `vYYYY.M.D`), npm dist-tag `latest`. -- beta: prerelease tags `vYYYY.M.D-beta.N`, npm dist-tag `beta` (may ship without macOS app). -- dev: moving head on `main` (no tag; git checkout main). - -## Testing Guidelines - -- Framework: Vitest with V8 coverage thresholds (70% lines/branches/functions/statements). -- Naming: match source names with `*.test.ts`; e2e in `*.e2e.test.ts`. -- Run `pnpm test` (or `pnpm test:coverage`) before pushing when you touch logic. -- Do not set test workers above 16; tried already. -- Live tests (real keys): `CLAWDBOT_LIVE_TEST=1 pnpm test:live` (OpenClaw-only) or `LIVE=1 pnpm test:live` (includes provider live tests). Docker: `pnpm test:docker:live-models`, `pnpm test:docker:live-gateway`. Onboarding Docker E2E: `pnpm test:docker:onboard`. -- Full kit + what’s covered: `docs/testing.md`. -- Changelog: user-facing changes only; no internal/meta notes (version alignment, appcast reminders, release process). -- Pure test additions/fixes generally do **not** need a changelog entry unless they alter user-facing behavior or the user asks for one. -- Mobile: before using a simulator, check for connected real devices (iOS + Android) and prefer them when available. - -## Commit & Pull Request Guidelines - -**Full maintainer PR workflow (optional):** If you want the repo's end-to-end maintainer workflow (triage order, quality bar, rebase rules, commit/changelog conventions, co-contributor policy, and the `review-pr` > `prepare-pr` > `merge-pr` pipeline), see `.agents/skills/PR_WORKFLOW.md`. Maintainers may use other workflows; when a maintainer specifies a workflow, follow that. If no workflow is specified, default to PR_WORKFLOW. - -- Create commits with `scripts/committer "" `; avoid manual `git add`/`git commit` so staging stays scoped. -- Follow concise, action-oriented commit messages (e.g., `CLI: add verbose flag to send`). -- Group related changes; avoid bundling unrelated refactors. -- PR submission template (canonical): `.github/pull_request_template.md` -- Issue submission templates (canonical): `.github/ISSUE_TEMPLATE/` - -## Shorthand Commands - -- `sync`: if working tree is dirty, commit all changes (pick a sensible Conventional Commit message), then `git pull --rebase`; if rebase conflicts and cannot resolve, stop; otherwise `git push`. - -## Git Notes - -- If `git branch -d/-D ` is policy-blocked, delete the local ref directly: `git update-ref -d refs/heads/`. -- Bulk PR close/reopen safety: if a close action would affect more than 5 PRs, first ask for explicit user confirmation with the exact PR count and target scope/query. - -## Security & Configuration Tips - -- Web provider stores creds at `~/.openclaw/credentials/`; rerun `openclaw login` if logged out. -- Pi sessions live under `~/.openclaw/sessions/` by default; the base directory is not configurable. -- Environment variables: see `~/.profile`. -- Never commit or publish real phone numbers, videos, or live configuration values. Use obviously fake placeholders in docs, tests, and examples. -- Release flow: always read `docs/reference/RELEASING.md` and `docs/platforms/mac/release.md` before any release work; do not ask routine questions once those docs answer them. - -## GHSA (Repo Advisory) Patch/Publish - -- Before reviewing security advisories, read `SECURITY.md`. -- Fetch: `gh api /repos/openclaw/openclaw/security-advisories/` -- Latest npm: `npm view openclaw version --userconfig "$(mktemp)"` -- Private fork PRs must be closed: - `fork=$(gh api /repos/openclaw/openclaw/security-advisories/ | jq -r .private_fork.full_name)` - `gh pr list -R "$fork" --state open` (must be empty) -- Description newline footgun: write Markdown via heredoc to `/tmp/ghsa.desc.md` (no `"\\n"` strings) -- Build patch JSON via jq: `jq -n --rawfile desc /tmp/ghsa.desc.md '{summary,severity,description:$desc,vulnerabilities:[...]}' > /tmp/ghsa.patch.json` -- Patch + publish: `gh api -X PATCH /repos/openclaw/openclaw/security-advisories/ --input /tmp/ghsa.patch.json` (publish = include `"state":"published"`; no `/publish` endpoint) -- If publish fails (HTTP 422): missing `severity`/`description`/`vulnerabilities[]`, or private fork has open PRs -- Verify: re-fetch; ensure `state=published`, `published_at` set; `jq -r .description | rg '\\\\n'` returns nothing - -## Troubleshooting - -- Rebrand/migration issues or legacy config/service warnings: run `openclaw doctor` (see `docs/gateway/doctor.md`). - -## Agent-Specific Notes - -- Vocabulary: "makeup" = "mac app". -- Never edit `node_modules` (global/Homebrew/npm/git installs too). Updates overwrite. Skill notes go in `tools.md` or `AGENTS.md`. -- When adding a new `AGENTS.md` anywhere in the repo, also add a `CLAUDE.md` symlink pointing to it (example: `ln -s AGENTS.md CLAUDE.md`). -- Signal: "update fly" => `fly ssh console -a flawd-bot -C "bash -lc 'cd /data/clawd/openclaw && git pull --rebase origin main'"` then `fly machines restart e825232f34d058 -a flawd-bot`. -- When working on a GitHub Issue or PR, print the full URL at the end of the task. -- When answering questions, respond with high-confidence answers only: verify in code; do not guess. -- Never update the Carbon dependency. -- Any dependency with `pnpm.patchedDependencies` must use an exact version (no `^`/`~`). -- Patching dependencies (pnpm patches, overrides, or vendored changes) requires explicit approval; do not do this by default. -- CLI progress: use `src/cli/progress.ts` (`osc-progress` + `@clack/prompts` spinner); don’t hand-roll spinners/bars. -- Status output: keep tables + ANSI-safe wrapping (`src/terminal/table.ts`); `status --all` = read-only/pasteable, `status --deep` = probes. -- Gateway currently runs only as the menubar app; there is no separate LaunchAgent/helper label installed. Restart via the OpenClaw Mac app or `scripts/restart-mac.sh`; to verify/kill use `launchctl print gui/$UID | grep openclaw` rather than assuming a fixed label. **When debugging on macOS, start/stop the gateway via the app, not ad-hoc tmux sessions; kill any temporary tunnels before handoff.** -- macOS logs: use `./scripts/clawlog.sh` to query unified logs for the OpenClaw subsystem; it supports follow/tail/category filters and expects passwordless sudo for `/usr/bin/log`. -- If shared guardrails are available locally, review them; otherwise follow this repo's guidance. -- SwiftUI state management (iOS/macOS): prefer the `Observation` framework (`@Observable`, `@Bindable`) over `ObservableObject`/`@StateObject`; don’t introduce new `ObservableObject` unless required for compatibility, and migrate existing usages when touching related code. -- Connection providers: when adding a new connection, update every UI surface and docs (macOS app, web UI, mobile if applicable, onboarding/overview docs) and add matching status + configuration forms so provider lists and settings stay in sync. -- Version locations: `package.json` (CLI), `apps/android/app/build.gradle.kts` (versionName/versionCode), `apps/ios/Sources/Info.plist` + `apps/ios/Tests/Info.plist` (CFBundleShortVersionString/CFBundleVersion), `apps/macos/Sources/OpenClaw/Resources/Info.plist` (CFBundleShortVersionString/CFBundleVersion), `docs/install/updating.md` (pinned npm version), `docs/platforms/mac/release.md` (APP_VERSION/APP_BUILD examples), Peekaboo Xcode projects/Info.plists (MARKETING_VERSION/CURRENT_PROJECT_VERSION). -- "Bump version everywhere" means all version locations above **except** `appcast.xml` (only touch appcast when cutting a new macOS Sparkle release). -- **Restart apps:** “restart iOS/Android apps” means rebuild (recompile/install) and relaunch, not just kill/launch. -- **Device checks:** before testing, verify connected real devices (iOS/Android) before reaching for simulators/emulators. -- iOS Team ID lookup: `security find-identity -p codesigning -v` → use Apple Development (…) TEAMID. Fallback: `defaults read com.apple.dt.Xcode IDEProvisioningTeamIdentifiers`. -- A2UI bundle hash: `src/canvas-host/a2ui/.bundle.hash` is auto-generated; ignore unexpected changes, and only regenerate via `pnpm canvas:a2ui:bundle` (or `scripts/bundle-a2ui.sh`) when needed. Commit the hash as a separate commit. -- Release signing/notary keys are managed outside the repo; follow internal release docs. -- Notary auth env vars (`APP_STORE_CONNECT_ISSUER_ID`, `APP_STORE_CONNECT_KEY_ID`, `APP_STORE_CONNECT_API_KEY_P8`) are expected in your environment (per internal release docs). -- **Multi-agent safety:** do **not** create/apply/drop `git stash` entries unless explicitly requested (this includes `git pull --rebase --autostash`). Assume other agents may be working; keep unrelated WIP untouched and avoid cross-cutting state changes. -- **Multi-agent safety:** when the user says "push", you may `git pull --rebase` to integrate latest changes (never discard other agents' work). When the user says "commit", scope to your changes only. When the user says "commit all", commit everything in grouped chunks. -- **Multi-agent safety:** do **not** create/remove/modify `git worktree` checkouts (or edit `.worktrees/*`) unless explicitly requested. -- **Multi-agent safety:** do **not** switch branches / check out a different branch unless explicitly requested. -- **Multi-agent safety:** running multiple agents is OK as long as each agent has its own session. -- **Multi-agent safety:** when you see unrecognized files, keep going; focus on your changes and commit only those. -- Lint/format churn: - - If staged+unstaged diffs are formatting-only, auto-resolve without asking. - - If commit/push already requested, auto-stage and include formatting-only follow-ups in the same commit (or a tiny follow-up commit if needed), no extra confirmation. - - Only ask when changes are semantic (logic/data/behavior). -- Lobster seam: use the shared CLI palette in `src/terminal/palette.ts` (no hardcoded colors); apply palette to onboarding/config prompts and other TTY UI output as needed. -- **Multi-agent safety:** focus reports on your edits; avoid guard-rail disclaimers unless truly blocked; when multiple agents touch the same file, continue if safe; end with a brief “other files present” note only if relevant. -- Bug investigations: read source code of relevant npm dependencies and all related local code before concluding; aim for high-confidence root cause. -- Code style: add brief comments for tricky logic; keep files under ~500 LOC when feasible (split/refactor as needed). -- Tool schema guardrails (google-antigravity): avoid `Type.Union` in tool input schemas; no `anyOf`/`oneOf`/`allOf`. Use `stringEnum`/`optionalStringEnum` (Type.Unsafe enum) for string lists, and `Type.Optional(...)` instead of `... | null`. Keep top-level tool schema as `type: "object"` with `properties`. -- Tool schema guardrails: avoid raw `format` property names in tool schemas; some validators treat `format` as a reserved keyword and reject the schema. -- When asked to open a “session” file, open the Pi session logs under `~/.openclaw/agents//sessions/*.jsonl` (use the `agent=` value in the Runtime line of the system prompt; newest unless a specific ID is given), not the default `sessions.json`. If logs are needed from another machine, SSH via Tailscale and read the same path there. -- Do not rebuild the macOS app over SSH; rebuilds must be run directly on the Mac. -- Never send streaming/partial replies to external messaging surfaces (WhatsApp, Telegram); only final replies should be delivered there. Streaming/tool events may still go to internal UIs/control channel. -- Voice wake forwarding tips: - - Command template should stay `openclaw-mac agent --message "${text}" --thinking low`; `VoiceWakeForwarder` already shell-escapes `${text}`. Don’t add extra quotes. - - launchd PATH is minimal; ensure the app’s launch agent PATH includes standard system paths plus your pnpm bin (typically `$HOME/Library/pnpm`) so `pnpm`/`openclaw` binaries resolve when invoked via `openclaw-mac`. -- For manual `openclaw message send` messages that include `!`, use the heredoc pattern noted below to avoid the Bash tool’s escaping. -- Release guardrails: do not change version numbers without operator’s explicit consent; always ask permission before running any npm publish/release step. - -## NPM + 1Password (publish/verify) - -- Use the 1password skill; all `op` commands must run inside a fresh tmux session. -- Sign in: `eval "$(op signin --account my.1password.com)"` (app unlocked + integration on). -- OTP: `op read 'op://Private/Npmjs/one-time password?attribute=otp'`. -- Publish: `npm publish --access public --otp=""` (run from the package dir). -- Verify without local npmrc side effects: `npm view version --userconfig "$(mktemp)"`. -- Kill the tmux session after publish. - -## Plugin Release Fast Path (no core `openclaw` publish) - -- Release only already-on-npm plugins. Source list is in `docs/reference/RELEASING.md` under "Current npm plugin list". -- Run all CLI `op` calls and `npm publish` inside tmux to avoid hangs/interruption: - - `tmux new -d -s release-plugins-$(date +%Y%m%d-%H%M%S)` - - `eval "$(op signin --account my.1password.com)"` -- 1Password helpers: - - password used by `npm login`: - `op item get Npmjs --format=json | jq -r '.fields[] | select(.id=="password").value'` - - OTP: - `op read 'op://Private/Npmjs/one-time password?attribute=otp'` -- Fast publish loop (local helper script in `/tmp` is fine; keep repo clean): - - compare local plugin `version` to `npm view version` - - only run `npm publish --access public --otp=""` when versions differ - - skip if package is missing on npm or version already matches. -- Keep `openclaw` untouched: never run publish from repo root unless explicitly requested. -- Post-check for each release: - - per-plugin: `npm view @openclaw/ version --userconfig "$(mktemp)"` should be `2026.2.17` - - core guard: `npm view openclaw version --userconfig "$(mktemp)"` should stay at previous version unless explicitly requested. - -## Changelog Release Notes - -- When cutting a mac release with beta GitHub prerelease: - - Tag `vYYYY.M.D-beta.N` from the release commit (example: `v2026.2.15-beta.1`). - - Create prerelease with title `openclaw YYYY.M.D-beta.N`. - - Use release notes from `CHANGELOG.md` version section (`Changes` + `Fixes`, no title duplicate). - - Attach at least `OpenClaw-YYYY.M.D.zip` and `OpenClaw-YYYY.M.D.dSYM.zip`; include `.dmg` if available. - -- Keep top version entries in `CHANGELOG.md` sorted by impact: - - `### Changes` first. - - `### Fixes` deduped and ranked with user-facing fixes first. -- Before tagging/publishing, run: - - `node --import tsx scripts/release-check.ts` - - `pnpm release:check` - - `pnpm test:install:smoke` or `OPENCLAW_INSTALL_SMOKE_SKIP_NONROOT=1 pnpm test:install:smoke` for non-root smoke path. diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md new file mode 100644 index 0000000000..bd86554eff --- /dev/null +++ b/ARCHITECTURE.md @@ -0,0 +1,405 @@ +# OpenClaw 架构流程图 + +## Web UI 模型列表的完整数据来源 + +--- + +## 第一阶段:浏览器环境准备 + +### start-chrome-debug.sh + +``` +┌─────────────────────────────────────────────────────────────────────────────────────────────┐ +│ start-chrome-debug.sh │ +├─────────────────────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ 1. 检测操作系统 (mac/win/wsl/linux) │ +│ └─→ 自动查找 Chrome/Chromium 路径 │ +│ │ +│ 2. 检查端口 9222 │ +│ └─→ 若已占用 → 关闭旧进程 │ +│ │ +│ 3. 启动 Chrome 调试模式 │ +│ chrome --remote-debugging-port=9222 \ │ +│ --user-data-dir=~/.config/chrome-openclaw-debug \ │ +│ --remote-allow-origins=* │ +│ │ +│ 4. 打开各平台登录页: │ +│ • https://claude.ai/new │ +│ • https://chatgpt.com │ +│ • https://www.doubao.com/chat/ │ +│ • https://chat.qwen.ai │ +│ • https://www.kimi.com │ +│ • https://gemini.google.com/app │ +│ • https://grok.com │ +│ • https://chatglm.cn │ +│ │ +└───────────────────────────────────┬─────────────────────────────────────────────────────────┘ + │ + ▼ + ┌──────────────────────────────┐ + │ Chrome 调试模式运行中 │ + │ 端口: 9222 │ + │ CDP URL: http://127.0.0.1:9222 + │ │ + │ 用户在浏览器中登录各平台 │ + │ (建立登录会话/cookies) │ + └──────────────┬───────────────┘ +``` + +--- + +## 第二阶段:认证捕获 + +### onboard.sh + +``` +┌─────────────────────────────────────────────────────────────────────────────────────────────┐ +│ onboard.sh │ +├─────────────────────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ $ ./onboard.sh │ +│ │ +│ 1. 设置环境变量 │ +│ OPENCLAW_CONFIG_PATH=.openclaw-state/openclaw.json │ +│ OPENCLAW_STATE_DIR=.openclaw-state │ +│ │ +│ 2. 运行 dist/index.mjs onboard │ +│ └─→ 显示平台选择菜单 │ +│ │ +│ 用户选择平台 (如 deepseek-web) │ +│ │ +│ 3. 执行认证流程 │ +│ ┌──────────────────────────────────────────────────────────────────────┐ │ +│ │ src/providers/{provider}-auth.ts │ │ +│ │ │ │ +│ │ • 连接 Chrome CDP (http://127.0.0.1:9222) │ │ +│ │ • 导航到平台页面 │ │ +│ │ • 等待用户登录 (检测登录 cookie) │ │ +│ │ • 提取 cookies + userAgent │ │ +│ └──────────────────────────────────────────────────────────────────────┘ │ +│ │ +│ 4. 保存认证信息 │ +│ ┌──────────────────────────────────────────────────────────────────────┐ │ +│ │ src/commands/onboard-auth.credentials.ts │ │ +│ │ → upsertAuthProfile() │ │ +│ │ │ │ +│ │ 写入: .openclaw-state/agents/main/agent/auth-profiles.json │ │ +│ │ │ │ +│ │ { │ │ +│ │ "profiles": { │ │ +│ │ "deepseek-web:default": { │ │ +│ │ "key": { "cookie": "...", "userAgent": "..." } │ │ +│ │ } │ │ +│ │ } │ │ +│ │ } │ │ +│ └──────────────────────────────────────────────────────────────────────┘ │ +│ │ +└───────────────────────────────────┬─────────────────────────────────────────────────────────┘ + │ + │ 对每个平台重复 + ▼ + ┌──────────────────────────────┐ + │ auth-profiles.json 已填充 │ + │ (包含所有平台的认证信息) │ + └──────────────────────────────┘ +``` + +--- + +## 第三阶段:启动 Gateway + +### server.sh + +``` +┌─────────────────────────────────────────────────────────────────────────────────────────────┐ +│ server.sh │ +├─────────────────────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ $ ./server.sh start │ +│ │ +│ 1. 设置环境变量 │ +│ OPENCLAW_CONFIG_PATH=.openclaw-state/openclaw.json │ +│ OPENCLAW_STATE_DIR=.openclaw-state │ +│ OPENCLAW_GATEWAY_PORT=3001 │ +│ │ +│ 2. 启动 Gateway 进程 │ +│ nohup node dist/index.mjs gateway --port 3001 │ +│ │ +│ 3. 等待就绪 (curl http://127.0.0.1:3001/) │ +│ │ +│ 4. 打开浏览器 │ +│ http://127.0.0.1:3001/#token=xxx │ +│ │ +└───────────────────────────────────┬─────────────────────────────────────────────────────────┘ + │ + ▼ + ┌──────────────────────────────┐ + │ Gateway 进程启动 │ + │ 端口: 3001 │ + └──────────────────────────────┘ +``` + +--- + +## 第四阶段:Gateway 初始化 → 生成模型目录 + +### dist/index.mjs gateway + +``` +┌─────────────────────────────────────────────────────────────────────────────────────────────┐ +│ dist/index.mjs gateway │ +├─────────────────────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ Gateway 启动时执行: │ +│ │ +│ ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ +│ │ src/agents/models-config.ts │ │ +│ │ │ │ +│ │ ensureOpenClawModelsJson(cfg) │ │ +│ │ │ │ +│ │ 1. 读取 openclaw.json 中的 models.providers │ │ +│ │ ┌─────────────────────────────────────────────────────────────────────────┐ │ │ +│ │ │ .openclaw-state/openclaw.json │ │ │ +│ │ │ │ │ │ +│ │ │ models.providers: │ │ │ +│ │ │ deepseek-web: { baseUrl, api, models: [...] } │ │ │ +│ │ │ claude-web: { baseUrl, api, models: [...] } │ │ │ +│ │ │ chatgpt-web: { baseUrl, api, models: [...] } │ │ │ +│ │ │ doubao-web: { baseUrl, api, models: [...] } │ │ │ +│ │ │ gemini-web: { baseUrl, api, models: [...] } │ │ │ +│ │ │ grok-web: { baseUrl, api, models: [...] } │ │ │ +│ │ │ kimi-web: { baseUrl, api, models: [...] } │ │ │ +│ │ │ manus-api: { baseUrl, api, models: [...] } │ │ │ +│ │ │ qwen-web: { baseUrl, api, models: [...] } │ │ │ +│ │ │ glm-web: { baseUrl, api, models: [...] } │ │ │ +│ │ └─────────────────────────────────────────────────────────────────────────┘ │ │ +│ │ │ │ +│ │ 2. resolveImplicitProviders() - 解析隐式 providers (检查 auth-profiles.json) │ │ +│ │ ┌─────────────────────────────────────────────────────────────────────────┐ │ │ +│ │ │ .openclaw-state/agents/main/agent/auth-profiles.json │ │ │ +│ │ │ │ │ │ +│ │ │ 为已认证的 provider 设置 apiKey 字段 │ │ │ +│ │ └─────────────────────────────────────────────────────────────────────────┘ │ │ +│ │ │ │ +│ │ 3. mergeProviders() - 合并显式 + 隐式 providers │ │ +│ │ │ │ +│ │ 4. 写入 models.json │ │ +│ │ ┌─────────────────────────────────────────────────────────────────────────┐ │ │ +│ │ │ .openclaw-state/agents/main/agent/models.json │ │ │ +│ │ │ │ │ │ +│ │ │ providers: │ │ │ +│ │ │ deepseek-web: { apiKey: "...", models: [...] } │ │ │ +│ │ │ claude-web: { apiKey: "...", models: [...] } │ │ │ +│ │ │ ... │ │ │ +│ │ └─────────────────────────────────────────────────────────────────────────┘ │ │ +│ │ │ │ +│ └─────────────────────────────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 第五阶段:Web UI 请求模型列表 + +``` +┌──────────────┐ RPC: models.list {} ┌──────────────────────────────────────────────┐ +│ │ ─────────────────────────► │ src/gateway/server-methods/models.ts │ +│ Web UI │ │ │ +│ (浏览器) │ │ modelsHandlers["models.list"] │ +│ │ │ → context.loadGatewayModelCatalog() │ +│ │ ◄───────────────────────── │ │ +│ │ { models: [...] } └───────────────────┬──────────────────────────┘ +└──────────────┘ │ + ▼ + ┌──────────────────────────────────────────────────────────────────┐ + │ src/gateway/server-model-catalog.ts │ + │ │ + │ loadGatewayModelCatalog() │ + │ → loadModelCatalog({ config: loadConfig() }) │ + │ │ + └───────────────────────────┬──────────────────────────────────────┘ + │ + ▼ + ┌──────────────────────────────────────────────────────────────────┐ + │ src/agents/model-catalog.ts │ + │ │ + │ loadModelCatalog() │ + │ │ + │ ┌────────────────────────────────────────────────────────────┐ │ + │ │ 1. ensureOpenClawModelsJson(cfg) │ │ + │ │ → 确保 models.json 存在且是最新的 │ │ + │ │ │ │ + │ │ 2. ensurePiAuthJsonFromAuthProfiles() │ │ + │ │ → 同步 auth-profiles.json → auth.json │ │ + │ │ │ │ + │ │ 3. new ModelRegistry(authStorage, "models.json") │ │ + │ │ → pi-coding-agent 读取 models.json │ │ + │ │ → 返回所有发现的模型 (~800 个,来自 20+ providers) │ │ + │ │ │ │ + │ │ 4. ★ 关键过滤步骤 ★ │ │ + │ │ configuredProviders = Set( │ │ + │ │ Object.keys(cfg.models?.providers ?? {}) │ │ + │ │ .map(p => p.toLowerCase()) │ │ + │ │ ) │ │ + │ │ │ │ + │ │ for (entry of registry.getAll()) { │ │ + │ │ if (!configuredProviders.has(entry.provider)) { │ │ + │ │ continue // 跳过未在 openclaw.json 中配置的 │ │ + │ │ } │ │ + │ │ models.push(entry) │ │ + │ │ } │ │ + │ │ │ │ + │ │ 5. 返回过滤后的 ModelCatalogEntry[] (~23 个模型) │ │ + │ └────────────────────────────────────────────────────────────┘ │ + │ │ + └──────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 完整数据流总结 + +``` +┌─────────────────────────────────────────────────────────────────────────────────────────────┐ +│ │ +│ ┌─────────────────────┐ │ +│ │ start-chrome-debug.sh│──► Chrome :9222 ──► 用户登录各平台 │ +│ └─────────────────────┘ │ │ +│ │ │ +│ ▼ │ +│ ┌─────────────────────┐ ┌─────────────────────┐ │ +│ │ onboard.sh │──► 连接 Chrome :9222 ────────────►│ 提取 cookies │ │ +│ └─────────────────────┘ └─────────┬───────────┘ │ +│ │ │ +│ ▼ │ +│ ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ +│ │ .openclaw-state/agents/main/agent/ │ │ +│ │ │ │ +│ │ auth-profiles.json models.json auth.json │ │ +│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │ +│ │ │ profiles: { │ │ providers: { │ │ (pi-coding-agent │ │ │ +│ │ │ "deepseek-web │ │ deepseek-web │ │ 内部格式) │ │ │ +│ │ │ :default": { │ │ claude-web │ │ │ │ │ +│ │ │ key: { │ │ chatgpt-web │ │ 同步自 │ │ │ +│ │ │ cookie │ ────── │ ... │ ◄── │ auth-profiles │ │ │ +│ │ │ } │ 生成 │ glm-web │ │ .json │ │ │ +│ │ │ } │ │ } │ │ │ │ │ +│ │ │ } │ └─────────────────┘ └─────────────────┘ │ │ +│ │ └─────────────────┘ │ │ +│ │ ▲ │ │ │ +│ └──────────│────────────────────────────────────│──────────────────────────────────────┘ │ +│ │ │ │ +│ ┌──────────┴─────────┐ │ │ +│ │ .openclaw-state/ │ │ │ +│ │ openclaw.json │ │ │ +│ │ │ │ │ +│ │ models.providers: │──────────────────────────┘ │ +│ │ 定义要使用的 │ (配置 + 认证 → models.json) │ +│ │ 10 个 providers │ │ +│ │ │ │ +│ │ agents.defaults. │ │ +│ │ models: │ │ +│ │ 定义模型别名 │ │ +│ └────────────────────┘ │ +│ │ │ +│ │ server.sh 读取配置启动 Gateway │ +│ ▼ │ +│ ┌─────────────────────┐ │ +│ │ server.sh │──► Gateway :3001 ──► Web UI │ +│ └─────────────────────┘ │ │ +│ │ │ +│ ▼ │ +│ ┌─────────────────┐ │ +│ │ /models 命令 │ │ +│ │ │ │ +│ │ 只显示配置的 │ │ +│ │ 10 个 providers │ │ +│ │ 23 个模型 │ │ +│ └─────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 文件关系图 + +``` + ┌────────────────────────────────────────────────────────────┐ + │ 用户操作 │ + │ │ + │ ./start-chrome-debug.sh ──► ./onboard.sh ──► ./server.sh start + │ │ │ │ │ + │ ▼ ▼ ▼ │ + │ Chrome :9222 auth-profiles.json Gateway │ + │ │ :3001 │ + │ │ │ │ + └────────────────────────────────────┼─────────────────────┼───────┘ + │ │ + ┌────────────────────────────────────┼─────────────────────┼───────┐ + │ 配置文件 │ │ │ + │ ▼ ▼ │ + │ openclaw.json ◄───────────┬── models.json ◄──── ModelRegistry │ + │ │ │ │ │ + │ │ │ │ │ + │ ▼ │ ▼ │ + │ providers 配置 │ 过滤后模型 │ + │ (10 个) │ (只保留配置的) │ + │ │ │ + │ ▼ │ + │ auth-profiles.json │ + │ │ │ + │ ▼ │ + │ auth.json │ + │ (pi-agent 格式) │ + │ │ + └────────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 三个脚本的作用 + +| 脚本 | 作用 | 输出 | +|------|------|------| +| `start-chrome-debug.sh` | 启动 Chrome 调试模式 | Chrome 进程监听 9222 端口 | +| `onboard.sh` | 连接 Chrome,提取各平台 cookies | `auth-profiles.json` | +| `server.sh` | 启动 Gateway 服务 | Gateway 进程监听 3001 端口 | + +--- + +## 关键源码文件 + +| 文件 | 作用 | +|------|------| +| `src/providers/{provider}-auth.ts` | 各平台的认证逻辑(连接 Chrome,提取 cookies) | +| `src/agents/models-config.ts` | 合并配置,生成 `models.json` | +| `src/agents/model-catalog.ts` | 加载模型目录,**过滤只保留配置的 providers** | +| `src/gateway/server-methods/models.ts` | RPC `models.list` 处理器 | +| `src/gateway/server-model-catalog.ts` | Gateway 模型目录加载入口 | + +--- + +## 过滤逻辑详解 + +位置:`src/agents/model-catalog.ts` + +```typescript +// 获取配置中定义的 providers +const configuredProviders = new Set( + Object.keys(cfg.models?.providers ?? {}).map((p) => p.toLowerCase()), +); + +// 遍历 ModelRegistry 返回的所有模型 +for (const entry of registry.getAll()) { + // 过滤:只保留配置中定义的 providers + if (!configuredProviders.has(entry.provider.toLowerCase())) { + continue; // 跳过未配置的 provider + } + models.push(entry); +} +``` + +**效果**:虽然 pi-coding-agent 的 `ModelRegistry` 会发现 ~800 个模型(来自 20+ 内置 providers),但最终只返回 `openclaw.json` 中配置的 10 个 providers 的 ~23 个模型。 diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 9727eb0946..0000000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,2388 +0,0 @@ -# Changelog - -Docs: https://docs.openclaw.ai - -## 2026.2.20 (Unreleased) - -### Changes - -- iOS/Gateway: stabilize background wake and reconnect behavior with background reconnect suppression/lease windows, BGAppRefresh wake fallback, location wake hook throttling, and APNs wake retry+nudge instrumentation. (#21226) thanks @mbelinky. - -### Fixes - -- Discord/Gateway: handle close code 4014 (missing privileged gateway intents) without crashing the gateway. Thanks @thewilloftheshadow. -- Security/Net: strip sensitive headers (`Authorization`, `Proxy-Authorization`, `Cookie`, `Cookie2`) on cross-origin redirects in `fetchWithSsrFGuard` to prevent credential forwarding across origin boundaries. (#20313) Thanks @afurm. -- Auto-reply/Runner: emit `onAgentRunStart` only after agent lifecycle or tool activity begins (and only once per run), so fallback preflight errors no longer mark runs as started. (#21165) Thanks @shakkernerd. -- Auto-reply/Prompt caching: restore prefix-cache stability by keeping inbound system metadata session-stable and moving per-message IDs (`message_id`, `message_id_full`, `reply_to_id`, `sender_id`) into untrusted conversation context. (#20597) Thanks @anisoptera. - -## 2026.2.19 - -### Changes - -- iOS/Watch: add an Apple Watch companion MVP with watch inbox UI, watch notification relay handling, and gateway command surfaces for watch status/send flows. (#20054) Thanks @mbelinky. -- iOS/Gateway: wake disconnected iOS nodes via APNs before `nodes.invoke` and auto-reconnect gateway sessions on silent push wake to reduce invoke failures while the app is backgrounded. (#20332) Thanks @mbelinky. -- Gateway/CLI: add paired-device hygiene flows with `device.pair.remove`, plus `openclaw devices remove` and guarded `openclaw devices clear --yes [--pending]` commands for removing paired entries and optionally rejecting pending requests. (#20057) Thanks @mbelinky. -- iOS/APNs: add push registration and notification-signing configuration for node delivery. (#20308) Thanks @mbelinky. -- Gateway/APNs: add a push-test pipeline for APNs delivery validation in gateway flows. (#20307) Thanks @mbelinky. -- Security/Audit: add `gateway.http.no_auth` findings when `gateway.auth.mode="none"` leaves Gateway HTTP APIs reachable, with loopback warning and remote-exposure critical severity, plus regression coverage and docs updates. -- Skills: harden coding-agent skill guidance by removing shell-command examples that interpolate untrusted issue text directly into command strings. -- Dev tooling: align `oxfmt` local/CI formatting behavior. (#12579) Thanks @vincentkoc. - -### Fixes - -- Agents/Streaming: keep assistant partial streaming active during reasoning streams, handle native `thinking_*` stream events consistently, dedupe mixed reasoning-end signals, and clear stale mutating tool errors after same-target retry success. (#20635) Thanks @obviyus. -- iOS/Chat: use a dedicated iOS chat session key for ChatSheet routing to avoid cross-client session collisions with main-session traffic. (#21139) thanks @mbelinky. -- iOS/Chat: auto-resync chat history after reconnect sequence gaps, clear stale pending runs, and avoid dead-end manual refresh errors after transient disconnects. (#21135) thanks @mbelinky. -- iOS/Screen: move `WKWebView` lifecycle ownership into `ScreenWebView` coordinator and explicit attach/detach flow to reduce gesture/lifecycle crash risk (`__NSArrayM insertObject:atIndex:` paths) during screen tab updates. (#20366) Thanks @ngutman. -- iOS/Onboarding: prevent pairing-status flicker during auto-resume by keeping resumed state transitions stable. (#20310) Thanks @mbelinky. -- iOS/Onboarding: stabilize pairing and reconnect behavior by resetting stale pairing request state on manual retry, disconnecting both operator and node gateways on operator failure, and avoiding duplicate pairing loops from operator transport identity attachment. (#20056) Thanks @mbelinky. -- iOS/Signing: restore local auto-selected signing-team overrides during iOS project generation by wiring `.local-signing.xcconfig` into the active signing config and emitting `OPENCLAW_DEVELOPMENT_TEAM` in local signing setup. (#19993) Thanks @ngutman. -- Telegram: unify message-like inbound handling so `message` and `channel_post` share the same dedupe/access/media pipeline and remain behaviorally consistent. (#20591) Thanks @obviyus. -- Telegram/Agents: gate exec/bash tool-failure warnings behind verbose mode so default Telegram replies stay clean while verbose sessions still surface diagnostics. (#20560) Thanks @obviyus. -- Telegram/Cron/Heartbeat: honor explicit Telegram topic targets in cron and heartbeat delivery (`:topic:`) so scheduled sends land in the configured topic instead of the last active thread. (#19367) Thanks @Lukavyi. -- Gateway/Daemon: forward `TMPDIR` into installed service environments so macOS LaunchAgent gateway runs can open SQLite temp/journal files reliably instead of failing with `SQLITE_CANTOPEN`. (#20512) Thanks @Clawborn. -- Agents/Billing: include the active model that produced a billing error in user-facing billing messages (for example, `OpenAI (gpt-5.3)`) across payload, failover, and lifecycle error paths, so users can identify exactly which key needs credits. (#20510) Thanks @echoVic. -- Gateway/TUI: honor `agents.defaults.blockStreamingDefault` for `chat.send` by removing the hardcoded block-streaming disable override, so replies can use configured block-mode delivery. (#19693) Thanks @neipor. -- UI/Sessions: accept the canonical main session-key alias in Chat UI flows so main-session routing stays consistent. (#20311) Thanks @mbelinky. -- OpenClawKit/Protocol: preserve JSON boolean literals (`true`/`false`) when bridging through `AnyCodable` so Apple client RPC params no longer re-encode booleans as `1`/`0`. Thanks @mbelinky. -- Commands/Doctor: skip embedding-provider warnings when `memory.backend` is `qmd`, because QMD manages embeddings internally and does not require `memorySearch` providers. (#17263) Thanks @miloudbelarebia. -- Canvas/A2UI: improve bundled-asset resolution and empty-state handling so UI fallbacks render reliably. (#20312) Thanks @mbelinky. -- Commands/Doctor: avoid rewriting invalid configs with new `gateway.auth.token` defaults during repair and only write when real config changes are detected, preventing accidental token duplication and backup churn. -- Gateway/Auth: default unresolved gateway auth to token mode with startup auto-generation/persistence of `gateway.auth.token`, while allowing explicit `gateway.auth.mode: "none"` for intentional open loopback setups. (#20686) thanks @gumadeiras. -- Channels/Matrix: fix mention detection for `formatted_body` Matrix-to links by handling matrix.to mention formats consistently. (#16941) Thanks @zerone0x. -- Heartbeat/Cron: skip interval heartbeats when `HEARTBEAT.md` is missing or empty and no tagged cron events are queued, while preserving cron-event fallback for queued tagged reminders. (#20461) thanks @vikpos. -- Browser/Relay: reuse an already-running extension relay when the relay port is occupied by another OpenClaw process, while still failing on non-relay port collisions to avoid masking unrelated listeners. (#20035) Thanks @mbelinky. -- Scripts: update clawdock helper command support to include `docker-compose.extra.yml` where available. (#17094) Thanks @zerone0x. -- Lobster/Config: remove Lobster executable-path overrides (`lobsterPath`), require PATH-based execution, and add focused Windows wrapper-resolution tests to keep shell-free behavior stable. -- Gateway/WebChat: block `sessions.patch` and `sessions.delete` for WebChat clients so session-store mutations stay restricted to non-WebChat operator flows. Thanks @allsmog for reporting. -- Gateway: clarify launchctl GUI domain bootstrap failure on macOS. (#13795) Thanks @vincentkoc. -- Lobster/CI: fix flaky test Windows cmd shim script resolution. (#20833) Thanks @vincentkoc. -- Browser/Relay: require gateway-token auth on both `/extension` and `/cdp`, and align Chrome extension setup to use a single `gateway.auth.token` input for relay authentication. Thanks @tdjackey for reporting. -- Gateway/Hooks: run BOOT.md startup checks per configured agent scope, including per-agent session-key resolution, startup-hook regression coverage, and non-success boot outcome logging for diagnosability. (#20569) thanks @mcaxtr. -- Protocol/Apple: regenerate Swift gateway models for `push.test` so `pnpm protocol:check` stays green on main. Thanks @mbelinky. -- Sandbox/Registry: serialize container and browser registry writes with shared file locks and atomic replacement to prevent lost updates and delete rollback races from desyncing `sandbox list`, `prune`, and `recreate --all`. Thanks @kexinoh. -- OTEL/diagnostics-otel: complete OpenTelemetry v2 API migration. (#12897) Thanks @vincentkoc. -- Cron/Webhooks: protect cron webhook POST delivery with SSRF-guarded outbound fetch (`fetchWithSsrFGuard`) to block private/metadata destinations before request dispatch. Thanks @Adam55A-code. -- Security/Voice Call: harden `voice-call` telephony TTS override merging by blocking unsafe deep-merge keys (`__proto__`, `prototype`, `constructor`) and add regression coverage for top-level and nested prototype-pollution payloads. -- Security/Windows Daemon: harden Scheduled Task `gateway.cmd` generation by quoting cmd metacharacter arguments, escaping `%`/`!` expansions, and rejecting CR/LF in arguments, descriptions, and environment assignments (`set "KEY=VALUE"`), preventing command injection in Windows daemon startup scripts. This ships in the next npm release. Thanks @tdjackey for reporting. -- Security/Gateway/Canvas: replace shared-IP fallback auth with node-scoped session capability URLs for `/__openclaw__/canvas/*` and `/__openclaw__/a2ui/*`, fail closed when trusted-proxy requests omit forwarded client headers, and add IPv6/proxy-header regression coverage. This ships in the next npm release. Thanks @aether-ai-agent for reporting. -- Security/Net: enforce strict dotted-decimal IPv4 literals in SSRF checks and fail closed on unsupported legacy forms (octal/hex/short/packed, for example `0177.0.0.1`, `127.1`, `2130706433`) before DNS lookup. -- Security/Discord: enforce trusted-sender guild permission checks for moderation actions (`timeout`, `kick`, `ban`) and ignore untrusted `senderUserId` params to prevent privilege escalation in tool-driven flows. Thanks @aether-ai-agent for reporting. -- Security/ACP+Exec: add `openclaw acp --token-file/--password-file` secret-file support (with inline secret flag warnings), redact ACP working-directory prefixes to `~` home-relative paths, constrain exec script preflight file inspection to the effective `workdir` boundary, and add security-audit warnings when `tools.exec.host="sandbox"` is configured while sandbox mode is off. -- Security/Plugins/Hooks: enforce runtime/package path containment with realpath checks so `openclaw.extensions`, `openclaw.hooks`, and hook handler modules cannot escape their trusted roots via traversal or symlinks. -- Security/Discord: centralize trusted sender checks for moderation actions in message-action dispatch, share moderation command parsing across handlers, and clarify permission helpers with explicit any/all semantics. -- Security/ACP: harden ACP bridge session management with duplicate-session refresh, idle-session reaping, oldest-idle soft-cap eviction, and burst rate limiting on session creation to reduce local DoS risk without disrupting normal IDE usage. -- Security/ACP: bound ACP prompt text payloads to 2 MiB before gateway forwarding, account for join separator bytes during pre-concatenation size checks, and avoid stale active-run session state when oversized prompts are rejected. Thanks @aether-ai-agent for reporting. -- Security/Plugins/Hooks: add optional `--pin` for npm plugin/hook installs, persist resolved npm metadata (`name`, `version`, `spec`, integrity, shasum, timestamp), warn/confirm on integrity drift during updates, and extend `openclaw security audit` to flag unpinned specs, missing integrity metadata, and install-record version drift. -- Security/Plugins: harden plugin discovery by blocking unsafe candidates (root escapes, world-writable paths, suspicious ownership), add startup warnings when `plugins.allow` is empty with discoverable non-bundled plugins, and warn on loaded plugins without install/load-path provenance. -- Security/Gateway: rate-limit control-plane write RPCs (`config.apply`, `config.patch`, `update.run`) to 3 requests per minute per `deviceId+clientIp`, add restart single-flight coalescing plus a 30-second restart cooldown, and log actor/device/ip with changed-path audit details for config/update-triggered restarts. -- Security/Webhooks: harden Feishu and Zalo webhook ingress with webhook-mode token preconditions, loopback-default Feishu bind host, JSON content-type enforcement, per-path rate limiting, replay dedupe for Zalo events, constant-time Zalo secret comparison, and anomaly status counters. -- Security/Plugins: for the next npm release, clarify plugin trust boundary and keep `runtime.system.runCommandWithTimeout` available by default for trusted in-process plugins. Thanks @markmusson for reporting. -- Security/Skills: for the next npm release, reject symlinks during skill packaging to prevent external file inclusion in distributed `.skill` archives. Thanks @aether-ai-agent for reporting. -- Security/Gateway: fail startup when `hooks.token` matches `gateway.auth.token` so hooks and gateway token reuse is rejected at boot. (#20813) Thanks @coygeek. -- Security/Network: block plaintext `ws://` connections to non-loopback hosts and require secure websocket transport elsewhere. (#20803) Thanks @jscaldwell55. -- Security/Config: parse frontmatter YAML using the YAML 1.2 core schema to avoid implicit coercion of `on`/`off`-style values. (#20857) Thanks @davidrudduck. -- Security/Discord: escape backticks in exec-approval embed content to prevent markdown formatting injection via command text. (#20854) Thanks @davidrudduck. -- Security/Agents: replace shell-based `execSync` usage with `execFileSync` in command lookup helpers to eliminate shell argument interpolation risk. (#20655) Thanks @mahanandhi. -- Security/Media: use `crypto.randomBytes()` for temp file names and set owner-only permissions for TTS temp files. (#20654) Thanks @mahanandhi. -- Security/Gateway: set baseline security headers (`X-Content-Type-Options: nosniff`, `Referrer-Policy: no-referrer`) on gateway HTTP responses. (#10526) Thanks @abdelsfane. -- Security/iMessage: harden remote attachment SSH/SCP handling by requiring strict host-key verification, validating `channels.imessage.remoteHost` as `host`/`user@host`, and rejecting unsafe host tokens from config or auto-detection. Thanks @allsmog for reporting. -- Security/Feishu: prevent path traversal in Feishu inbound media temp-file writes by replacing key-derived temp filenames with UUID-based names. Thanks @allsmog for reporting. -- Security/Feishu: escape mention regex metacharacters in `stripBotMention` so crafted mention metadata cannot trigger regex injection or ReDoS during inbound message parsing. (#20916) Thanks @orlyjamie for the fix and @allsmog for reporting. -- LINE/Security: harden inbound media temp-file naming by using UUID-based temp paths for downloaded media instead of external message IDs. (#20792) Thanks @mbelinky. -- Security/Media: harden local media ingestion against TOCTOU/symlink swap attacks by pinning reads to a single file descriptor with symlink rejection and inode/device verification in `saveMediaSource`. Thanks @dorjoos for reporting. -- Security/Lobster (Windows): for the next npm release, remove shell-based fallback when launching Lobster wrappers (`.cmd`/`.bat`) and switch to explicit argv execution with wrapper entrypoint resolution, preventing command injection while preserving Windows wrapper compatibility. Thanks @allsmog for reporting. -- Security/Exec: require `tools.exec.safeBins` binaries to resolve from trusted bin directories (system defaults plus gateway startup `PATH`) so PATH-hijacked trojan binaries cannot bypass allowlist checks. Thanks @jackhax for reporting. -- Security/Exec: remove file-existence oracle behavior from `tools.exec.safeBins` by using deterministic argv-only stdin-safe validation and blocking file-oriented flags (for example `sort -o`, `jq -f`, `grep -f`) so allow/deny results no longer disclose host file presence. This ships in the next npm release. Thanks @nedlir for reporting. -- Security/Browser: route browser URL navigation through one SSRF-guarded validation path for tab-open/CDP-target/Playwright navigation flows and block private/metadata destinations by default (configurable via `browser.ssrfPolicy`). This ships in the next npm release. Thanks @dorjoos for reporting. -- Security/Exec: for the next npm release, harden safe-bin stdin-only enforcement by blocking output/recursive flags (`sort -o/--output`, grep recursion) and tightening default safe bins to remove `sort`/`grep`, preventing safe-bin allowlist bypass for file writes/recursive reads. Thanks @nedlir for reporting. -- Security/Gateway/Agents: remove implicit admin scopes from agent tool gateway calls by classifying methods to least-privilege operator scopes, and enforce owner-only tooling (`cron`, `gateway`, `whatsapp_login`) through centralized tool-policy wrappers plus tool metadata to prevent non-owner DM privilege escalation. Ships in the next npm release. Thanks @Adam55A-code for reporting. -- Security/Gateway: centralize gateway method-scope authorization and default non-CLI gateway callers to least-privilege method scopes, with explicit CLI scope handling, full core-handler scope classification coverage, and regression guards to prevent scope drift. -- Security/Net: block SSRF bypass via NAT64 (`64:ff9b::/96`, `64:ff9b:1::/48`), 6to4 (`2002::/16`), and Teredo (`2001:0000::/32`) IPv6 transition addresses, and fail closed on IPv6 parse errors. Thanks @jackhax. -- Security/OTEL: sanitize OTLP endpoint URL resolution. (#13791) Thanks @vincentkoc. -- Security: patch Dependabot security issues in pnpm lock. (#20832) Thanks @vincentkoc. -- Security: migrate request dependencies to `@cypress/request`. (#20836) Thanks @vincentkoc. - -## 2026.2.17 - -### Changes - -- Agents/Anthropic: add opt-in 1M context beta header support for Opus/Sonnet via model `params.context1m: true` (maps to `anthropic-beta: context-1m-2025-08-07`). -- Agents/Models: support Anthropic Sonnet 4.6 (`anthropic/claude-sonnet-4-6`) across aliases/defaults with forward-compat fallback when upstream catalogs still only expose Sonnet 4.5. -- Commands/Subagents: add `/subagents spawn` for deterministic subagent activation from chat commands. (#18218) Thanks @JoshuaLelon. -- Agents/Subagents: add an accepted response note for `sessions_spawn` explaining polling subagents are disabled for one-off calls. Thanks @tyler6204. -- Agents/Subagents: prefix spawned subagent task messages with context to preserve source information in downstream handling. Thanks @tyler6204. -- iOS/Share: add an iOS share extension that forwards shared URL/text/image content directly to gateway `agent.request`, with delivery-route fallback and optional receipt acknowledgements. (#19424) Thanks @mbelinky. -- iOS/Talk: add a `Background Listening` toggle that keeps Talk Mode active while the app is backgrounded (off by default for battery safety). Thanks @zeulewan. -- iOS/Talk: add a `Voice Directive Hint` toggle for Talk Mode prompts so users can disable ElevenLabs voice-switching instructions to save tokens when not needed. (#18250) Thanks @zeulewan. -- iOS/Talk: harden barge-in behavior by disabling interrupt-on-speech when output route is built-in speaker/receiver, reducing false interruptions from local TTS bleed-through. Thanks @zeulewan. -- Slack: add native single-message text streaming with Slack `chat.startStream`/`appendStream`/`stopStream`; keep reply threading aligned with `replyToMode`, default streaming to enabled, and fall back to normal delivery when streaming fails. (#9972) Thanks @natedenh. -- Slack: add configurable streaming modes for draft previews. (#18555) Thanks @Solvely-Colin. -- Telegram/Agents: add inline button `style` support (`primary|success|danger`) across message tool schema, Telegram action parsing, send pipeline, and runtime prompt guidance. (#18241) Thanks @obviyus. -- Telegram: surface user message reactions as system events, with configurable `channels.telegram.reactionNotifications` scope. (#10075) Thanks @Glucksberg. -- iMessage: support `replyToId` on outbound text/media sends and normalize leading `[[reply_to:]]` tags so replies target the intended iMessage. Thanks @tyler6204. -- Tool Display/Web UI: add intent-first tool detail views and exec summaries. (#18592) Thanks @xdLawless2. -- Discord: expose native `/exec` command options (host/security/ask/node) so Discord slash commands get autocomplete and structured inputs. Thanks @thewilloftheshadow. -- Discord: allow reusable interactive components with `components.reusable=true` so buttons, selects, and forms can be used multiple times before expiring. Thanks @thewilloftheshadow. -- Discord: add per-button `allowedUsers` allowlist for interactive components to restrict who can click buttons. Thanks @thewilloftheshadow. -- Cron/Gateway: separate per-job webhook delivery (`delivery.mode = "webhook"`) from announce delivery, enforce valid HTTP(S) webhook URLs, and keep a temporary legacy `notify + cron.webhook` fallback for stored jobs. (#17901) Thanks @advaitpaliwal. -- Cron/CLI: add deterministic default stagger for recurring top-of-hour cron schedules (including 6-field seconds cron), auto-migrate existing jobs to persisted `schedule.staggerMs`, and add `openclaw cron add/edit --stagger ` plus `--exact` overrides for per-job timing control. -- Cron: log per-run model/provider usage telemetry in cron run logs/webhooks and add a local usage report script for aggregating token usage by job. (#18172) Thanks @HankAndTheCrew. -- Tools/Web: add URL allowlists for `web_search` and `web_fetch`. (#18584) Thanks @smartprogrammer93. -- Browser: add `extraArgs` config for custom Chrome launch arguments. (#18443) Thanks @JayMishra-source. -- Voice Call: pre-cache inbound greeting TTS for faster first playback. (#18447) Thanks @JayMishra-source. -- Skills: compact skill file `` paths in the system prompt by replacing home-directory prefixes with `~`, and add targeted compaction tests for prompt serialization behavior. (#14776) Thanks @bitfish3. -- Skills: refine skill-description routing boundaries with explicit "Use when"/"NOT for" guidance for coding-agent/github/weather, and clarify PTY/browser fallback wording. (#14577) Thanks @DylanWoodAkers. -- Auto-reply/Prompts: include trusted inbound `message_id` in conversation metadata payloads for downstream targeting workflows. Thanks @tyler6204. -- Auto-reply: include `sender_id` in trusted inbound metadata so moderation workflows can target the sender without relying on untrusted text. (#18303) Thanks @crimeacs. -- UI/Sessions: avoid duplicating typed session prefixes in display names (for example `Subagent Subagent ...`). Thanks @tyler6204. -- Agents/Z.AI: enable `tool_stream` by default for real-time tool call streaming, with opt-out via `params.tool_stream: false`. (#18173) Thanks @tianxiao1430-jpg. -- Plugins: add `before_agent_start` model/provider overrides before resolution. (#18568) Thanks @natefikru. -- Mattermost: add emoji reaction actions plus reaction event notifications, including an explicit boolean `remove` flag to avoid accidental removals. (#18608) Thanks @echo931. -- Memory/Search: add FTS fallback plus query expansion for memory search. (#18304) Thanks @irchelper. -- Agents/Models: support per-model `thinkingDefault` overrides in model config. (#18152) Thanks @wu-tian807. -- Agents: enable `llms.txt` discovery in default behavior. (#18158) Thanks @yolo-maxi. -- Extensions/Auth: add OpenAI Codex CLI auth provider integration. (#18009) Thanks @jiteshdhamaniya. -- Feishu: add Bitable create-app/create-field tools for automation workflows. (#17963) Thanks @gaowanqi08141999. -- Docker: add optional `OPENCLAW_INSTALL_BROWSER` build arg to preinstall Chromium + Xvfb in the Docker image, avoiding runtime Playwright installs. (#18449) - -### Fixes - -- Tests/Telegram: add regression coverage for command-menu sync that asserts all `setMyCommands` entries are Telegram-safe and hyphen-normalized across native/custom/plugin command sources. (#19703) Thanks @obviyus. -- Agents/Image: collapse resize diagnostics to one line per image and include visible pixel/byte size details in the log message for faster triage. -- Agents/Subagents: preemptively guard accumulated tool-result context before model calls by truncating oversized outputs and compacting oldest tool-result messages to avoid context-window overflow crashes. Thanks @tyler6204. -- Agents/Subagents/CLI: fail `sessions_spawn` when subagent model patching is rejected, allow subagent model patch defaults from `subagents.model`, and keep `sessions list`/`status` model reporting aligned to runtime model resolution. (#18660) Thanks @robbyczgw-cla. -- Agents/Subagents: add explicit subagent guidance to recover from `[compacted: tool output removed to free context]` / `[truncated: output exceeded context limit]` markers by re-reading with smaller chunks instead of full-file `cat`. Thanks @tyler6204. -- Agents/Tools: make `read` auto-page across chunks (when no explicit `limit` is provided) and scale its per-call output budget from model `contextWindow`, so larger contexts can read more before context guards kick in. Thanks @tyler6204. -- Agents/Tools: strip duplicated `read` truncation payloads from tool-result `details` and make pre-call context guarding account for heavy tool-result metadata, so repeated `read` calls no longer bypass compaction and overflow model context windows. Thanks @tyler6204. -- Reply threading: keep reply context sticky across streamed/split chunks and preserve `replyToId` on all chunk sends across shared and channel-specific delivery paths (including iMessage, BlueBubbles, Telegram, Discord, and Matrix), so follow-up bubbles stay attached to the same referenced message. Thanks @tyler6204. -- Gateway/Agent: defer transient lifecycle `error` snapshots with a short grace window so `agent.wait` does not resolve early during retry/failover. Thanks @tyler6204. -- Gateway/Presence: centralize presence snapshot broadcasts and unify runtime version precedence (`OPENCLAW_VERSION` > `OPENCLAW_SERVICE_VERSION` > `npm_package_version`) so self-presence and websocket `hello-ok` report consistent versions. -- Hooks/Automation: bridge outbound/inbound message lifecycle into internal hook events (`message:received`, `message:sent`) with session-key correlation guards, while keeping per-payload success/error reporting accurate for chunked and best-effort deliveries. (PR #9387) -- Media understanding: honor `agents.defaults.imageModel` during auto-discovery so implicit image analysis uses configured primary/fallback image models. (PR #7607) -- iOS/Onboarding: stop auth Step 3 retry-loop churn by pausing reconnect attempts on unauthorized/missing-token gateway errors and keeping auth/pairing issue state sticky during manual retry. (#19153) Thanks @mbelinky. -- Voice-call: auto-end calls when media streams disconnect to prevent stuck active calls. (#18435) Thanks @JayMishra-source. -- Voice call/Gateway: prevent overlapping closed-loop turn races with per-call turn locking, route transcript dedupe via source-aware fingerprints with strict cache eviction bounds, and harden `voicecall latency` stats for large logs without spread-operator stack overflow. (#19140) Thanks @mbelinky. -- iOS/Chat: route ChatSheet RPCs through the operator session instead of the node session to avoid node-role authorization failures for `chat.history`, `chat.send`, and `sessions.list`. (#19320) Thanks @mbelinky. -- macOS/Update: correct the Sparkle appcast version for 2026.2.15 so updates are offered again. (#18201) -- Gateway/Auth: clear stale device-auth tokens after device token mismatch errors so re-paired clients can re-auth. (#18201) -- Telegram: enable DM voice-note transcription with CLI fallback handling. (#18564) Thanks @thhuang. -- Telegram/Polls: restore Telegram poll action wiring in channel handlers. (#18122) Thanks @akyourowngames. -- WebChat: strip reply/audio directive tags from rendered chat output. (#18093) Thanks @aldoeliacim. -- Discord: honor configured HTTP proxy for app-id and allowlist REST resolution. (#17958) Thanks @k2009. -- BlueBubbles: add fallback path to recover outbound `message_id` from `fromMe` webhooks when platform message IDs are missing. Thanks @tyler6204. -- BlueBubbles: match outbound message-id fallback recovery by chat identifier as well as account context. Thanks @tyler6204. -- BlueBubbles: include sender identifier in untrusted conversation metadata for conversation info payloads. Thanks @tyler6204. -- Security/Exec: fix the OC-09 credential-theft path via environment-variable injection. (#18048) Thanks @aether-ai-agent. -- Security/Config: confine `$include` resolution to the top-level config directory, harden traversal/symlink checks with cross-platform-safe path containment, and add doctor hints for invalid escaped include paths. (#18652) Thanks @aether-ai-agent. -- Security/Net: block SSRF bypass via ISATAP embedded IPv4 transition addresses and centralize hostname/IP blocking checks across URL safety validators. Thanks @zpbrent for reporting. -- Providers: improve error messaging for unconfigured local `ollama`/`vllm` providers. (#18183) Thanks @arosstale. -- TTS: surface all provider errors instead of only the last error in aggregated failures. (#17964) Thanks @ikari-pl. -- CLI/Doctor/Configure: skip gateway auth checks for loopback-only setups. (#18407) Thanks @sggolakiya. -- CLI/Doctor: reconcile gateway service-token drift after re-pair flows. (#18525) Thanks @norunners. -- Process/Windows: disable detached spawn in exec runs to prevent empty command output. (#18067) Thanks @arosstale. -- Process: gracefully terminate process trees with SIGTERM before SIGKILL. (#18626) Thanks @sauerdaniel. -- Sessions/Windows: use atomic session-store writes to prevent context loss on Windows. (#18347) Thanks @twcwinston. -- Agents/Image: validate base64 image payloads before provider submission. (#18263) Thanks @sriram369. -- Models CLI: validate catalog entries in `openclaw models set`. (#18129) Thanks @carrotRakko. -- Usage: isolate last-turn totals in token usage reporting to avoid mixed-turn totals. (#18052) Thanks @arosstale. -- Cron: resolve `accountId` from agent bindings in isolated sessions. (#17996) Thanks @simonemacario. -- Gateway/HTTP: preserve unbracketed IPv6 `Host` headers when normalizing requests. (#18061) Thanks @Clawborn. -- Sandbox: fix workspace-directory orphaning during SHA-1 -> SHA-256 slug migration. (#18523) Thanks @yinghaosang. -- Ollama/Qwen: handle Qwen 3 reasoning field format in Ollama responses. (#18631) Thanks @mr-sk. -- OpenAI/Transcripts: always drop orphaned reasoning blocks from transcript repair. (#18632) Thanks @TySabs. -- Fix types in all tests. Typecheck the whole repository. -- Gateway/Channels: wire `gateway.channelHealthCheckMinutes` into strict config validation, treat implicit account status as managed for health checks, and harden channel auto-restart flow (preserve restart-attempt caps across crash loops, propagate enabled/configured runtime flags, and stop pending restart backoff after manual stop). Thanks @steipete. -- Gateway/WebChat: hard-cap `chat.history` oversized payloads by truncating high-cost fields and replacing over-budget entries with placeholders, so history fetches stay within configured byte limits and avoid chat UI freezes. (#18505) -- UI/Usage: replace lingering undefined `var(--text-muted)` usage with `var(--muted)` in usage date-range and chart styles to keep muted text visible across themes. (#17975) Thanks @jogelin. -- UI/Usage: preserve selected-range totals when timeline data is downsampled by bucket-aggregating timeseries points (instead of dropping intermediate points), so filtered tokens/cost stay accurate. (#17959) Thanks @jogelin. -- UI/Sessions: refresh the sessions table only after successful deletes and preserve delete errors on cancel/failure paths, so deleted sessions disappear automatically without masking delete failures. (#18507) -- Scripts/UI/Windows: fix `pnpm ui:*` spawn `EINVAL` failures by restoring shell-backed launch for `.cmd`/`.bat` runners, narrowing shell usage to launcher types that require it, and rejecting unsafe forwarded shell metacharacters in UI script args. (#18594) -- Hooks/Session-memory: recover `/new` conversation summaries when session pointers are reset-path or missing `sessionFile`, and consistently prefer the newest `.jsonl.reset.*` transcript candidate for fallback extraction. (#18088) -- Auto-reply/Sessions: prevent stale thread ID leakage into non-thread sessions so replies stay in the main DM after topic interactions. (#18528) Thanks @j2h4u. -- Slack: restrict forwarded-attachment ingestion to explicit shared-message attachments and skip non-Slack forwarded `image_url` fetches, preventing non-forward attachment unfurls from polluting inbound agent context while preserving forwarded message handling. -- Feishu: detect bot mentions in post messages with embedded docs when `message.mentions` is empty. (#18074) Thanks @popomore. -- Agents/Sessions: align session lock watchdog hold windows with run and compaction timeout budgets (plus grace), preventing valid long-running turns from being force-unlocked mid-run while still recovering hung lock owners. (#18060) -- Cron: preserve default model fallbacks for cron agent runs when only `model.primary` is overridden, so failover still follows configured fallbacks unless explicitly cleared with `fallbacks: []`. (#18210) Thanks @mahsumaktas. -- Cron: route text-only announce output through the main session announce flow via runSubagentAnnounceFlow so cron text-only output remains visible to the initiating session. Thanks @tyler6204. -- Cron: treat `timeoutSeconds: 0` as no-timeout (not clamped to 1), ensuring long-running cron runs are not prematurely terminated. Thanks @tyler6204. -- Cron announce injection now targets the session determined by delivery config (`to` + channel) instead of defaulting to the current session. Thanks @tyler6204. -- Cron/Heartbeat: canonicalize session-scoped reminder `sessionKey` routing and preserve explicit flat `sessionKey` cron tool inputs, preventing enqueue/wake namespace drift for session-targeted reminders. (#18637) Thanks @vignesh07. -- Cron/Webhooks: reuse existing session IDs for webhook/cron runs when the session key is stable and still fresh, preserving conversation history. (#18031) Thanks @Operative-001. -- Cron: prevent spin loops when cron jobs complete within the scheduled second by advancing the next run and enforcing a minimum refire gap. (#18073) Thanks @widingmarcus-cyber. -- OpenClawKit/iOS ChatUI: accept canonical session-key completion events for local pending runs and preserve message IDs across history refreshes, preventing stuck "thinking" state and message flicker after gateway replies. (#18165) Thanks @mbelinky. -- iOS/Onboarding: add QR-first onboarding wizard with setup-code deep link support, pairing/auth issue guidance, and device-pair QR generation improvements for Telegram/Web/TUI fallback flows. (#18162) Thanks @mbelinky and @Marvae. -- iOS/Gateway: stabilize connect/discovery state handling, add onboarding reset recovery in Settings, and fix iOS gateway-controller coverage for command-surface and last-connection persistence behavior. (#18164) Thanks @mbelinky. -- iOS/Talk: harden mobile talk config handling by ignoring redacted/env-placeholder API keys, support secure local keychain override, improve accessibility motion/contrast behavior in status UI, and tighten ATS to local-network allowance. (#18163) Thanks @mbelinky. -- iOS/Location: restore the significant location monitor implementation (service hooks + protocol surface + ATS key alignment) after merge drift so iOS builds compile again. (#18260) Thanks @ngutman. -- iOS/Signing: auto-select local Apple Development team during iOS project generation/build, prefer the canonical OpenClaw team when available, and support local per-machine signing overrides without committing team IDs. (#18421) Thanks @ngutman. -- Discord/Telegram: make per-account message action gates effective for both action listing and execution, and preserve top-level gate restrictions when account overrides only specify a subset of `actions` keys (account key -> base key -> default fallback). (#18494) -- Telegram: keep DM-topic replies and draft previews in the originating private-chat topic by preserving positive `message_thread_id` values for DM threads. (#18586) Thanks @sebslight. -- Telegram: preserve private-chat topic `message_thread_id` on outbound sends (message/sticker/poll), keep thread-not-found retry fallback, and avoid masking `chat not found` routing errors. (#18993) Thanks @obviyus. -- Discord: prevent duplicate media delivery when the model uses the `message send` tool with media, by skipping media extraction from messaging tool results since the tool already sent the message directly. (#18270) -- Discord: route `audioAsVoice` auto-replies through the voice message API so opt-in audio renders as voice messages. (#18041) Thanks @zerone0x. -- Discord: skip auto-thread creation in forum/media/voice/stage channels and keep group session last-route metadata fresh to avoid invalid thread API errors and lost follow-up sends. (#18098) Thanks @Clawborn. -- Discord/Commands: normalize `commands.allowFrom` entries with `user:`/`discord:`/`pk:` prefixes and `<@id>` mentions so command authorization matches Discord allowlist behavior. (#18042) -- Telegram: keep draft-stream preview replies attached to the user message for `replyToMode: "all"` in groups and DMs, preserving threaded reply context from preview through finalization. (#17880) Thanks @yinghaosang. -- Telegram: prevent streaming final replies from being overwritten by later final/error payloads, and suppress fallback tool-error warnings when a recovered assistant answer already exists after tool calls. (#17883) Thanks @Marvae and @obviyus. -- Telegram: debounce the first draft-stream preview update (30-char threshold) and finalize short responses by editing the stop-time preview message, improving first push notifications and avoiding duplicate final sends. (#18148) Thanks @Marvae. -- Telegram: disable block streaming when `channels.telegram.streamMode` is `off`, preventing newline/content-block replies from splitting into multiple messages. (#17679) Thanks @saivarunk. -- Telegram: keep `streamMode: "partial"` draft previews in a single message across assistant-message/reasoning boundaries, preventing duplicate preview bubbles during partial-mode tool-call turns. (#18956) Thanks @obviyus. -- Telegram: normalize native command names for Telegram menu registration (`-` -> `_`) to avoid `BOT_COMMAND_INVALID` command-menu wipeouts, and log failed command syncs instead of silently swallowing them. (#19257) Thanks @akramcodez. -- Telegram: route non-abort slash commands on the normal chat/topic sequential lane while keeping true abort requests (`/stop`, `stop`) on the control lane, preventing command/reply race conditions from control-lane bypass. (#17899) Thanks @obviyus. -- Telegram: ignore `` placeholder lines when extracting `MEDIA:` tool-result paths, preventing false local-file reads and dropped replies. (#18510) Thanks @yinghaosang. -- Telegram: skip retries when inbound media `getFile` fails with Telegram's 20MB limit and continue processing message text, avoiding dropped messages for oversized attachments. (#18531) Thanks @brandonwise. -- Telegram: clear stored polling offsets when bot tokens change or accounts are deleted, preventing stale offsets after token rotations. (#18233) -- Telegram: enable `autoSelectFamily` by default on Node.js 22+ so IPv4 fallback works on broken IPv6 networks. (#18272) Thanks @nacho9900. -- Auto-reply/TTS: keep tool-result media delivery enabled in group chats and native command sessions (while still suppressing tool summary text) so `NO_REPLY` follow-ups do not drop successful TTS audio. (#17991) Thanks @zerone0x. -- Agents/Tools: deliver tool-result media even when verbose tool output is off so media attachments are not dropped. (#16679) -- Discord: optimize reaction notification handling to skip unnecessary message fetches in `off`/`all`/`allowlist` modes, streamline reaction routing, and improve reaction emoji formatting. (#18248) Thanks @thewilloftheshadow and @victorGPT. -- CLI/Pairing: make `openclaw qr --remote` prefer `gateway.remote.url` over tailscale/public URL resolution and register the `openclaw clawbot qr` legacy alias path. (#18091) -- CLI/QR: restore fail-fast validation for `openclaw qr --remote` when neither `gateway.remote.url` nor tailscale `serve`/`funnel` is configured, preventing unusable remote pairing QR flows. (#18166) Thanks @mbelinky. -- CLI: fix parent/subcommand option collisions across gateway, daemon, update, ACP, and browser command flows, while preserving legacy `browser set headers --json ` compatibility. -- CLI/Doctor: ensure `openclaw doctor --fix --non-interactive --yes` exits promptly after completion so one-shot automation no longer hangs. (#18502) -- CLI/Doctor: auto-repair `dmPolicy="open"` configs missing wildcard allowlists and write channel-correct repair paths (including `channels.googlechat.dm.allowFrom`) so `openclaw doctor --fix` no longer leaves Google Chat configs invalid after attempted repair. (#18544) -- CLI/Doctor: detect gateway service token drift when the gateway token is only provided via environment variables, keeping service repairs aligned after token rotation. -- Gateway/Update: prevent restart crash loops after failed self-updates by restarting only on successful updates, stopping early on failed install/build steps, and running `openclaw doctor --fix` during updates to sanitize config. (#18131) Thanks @RamiNoodle733. -- Gateway/Update: preserve update.run restart delivery context so post-update status replies route back to the initiating channel/thread. (#18267) Thanks @yinghaosang. -- CLI/Update: run a standalone restart helper after updates, honoring service-name overrides and reporting restart initiation separately from confirmed restarts. (#18050) -- CLI/Daemon: warn when a gateway restart sees a stale service token so users can reinstall with `openclaw gateway install --force`, and skip drift warnings for non-gateway service restarts. (#18018) -- CLI/Daemon: prefer the active version-manager Node when installing daemons and include macOS version-manager bin directories in the service PATH so launchd services resolve user-managed runtimes. -- CLI/Status: fix `openclaw status --all` token summaries for bot-token-only channels so Mattermost/Zalo no longer show a bot+app warning. (#18527) Thanks @echo931. -- CLI/Configure: make the `/model picker` allowlist prompt searchable with tokenized matching in `openclaw configure` so users can filter huge model lists by typing terms like `gpt-5.2 openai/`. (#19010) Thanks @bjesuiter. -- CLI/Message: preserve `--components` JSON payloads in `openclaw message send` so Discord component payloads are no longer dropped. (#18222) Thanks @saurabhchopade. -- Voice Call: add an optional stale call reaper (`staleCallReaperSeconds`) to end stuck calls when enabled. (#18437) -- Auto-reply/Subagents: propagate group context (`groupId`, `groupChannel`, `space`) when spawning via `/subagents spawn`, matching tool-triggered subagent spawn behavior. -- Subagents: route nested announce results back to the parent session after the parent run ends, falling back only when the parent session is deleted. (#18043) Thanks @tyler6204. -- Subagents: cap announce retry loops with max attempts and expiry to prevent infinite retry spam after deferred announces. (#18444) -- Agents/Tools/exec: add a preflight guard that detects likely shell env var injection (e.g. `$DM_JSON`, `$TMPDIR`) in Python/Node scripts before execution, preventing recurring cron failures and wasted tokens when models emit mixed shell+language source. (#12836) -- Agents/Tools/exec: treat normal non-zero exit codes as completed and append the exit code to tool output to avoid false tool-failure warnings. (#18425) -- Agents/Tools: make loop detection progress-aware and phased by hard-blocking known `process(action=poll|log)` no-progress loops, warning on generic identical-call repeats, warning + no-progress-blocking ping-pong alternation loops (10/20), coalescing repeated warning spam into threshold buckets (including canonical ping-pong pairs), adding a global circuit breaker at 30 no-progress repeats, and emitting structured diagnostic `tool.loop` warning/error events for loop actions. (#16808) Thanks @akramcodez and @beca-oc. -- Agents/Hooks: preserve the `before_tool_call` wrapped-marker across abort-signal tool wrapping so the hook runs once per tool call in normal agent sessions. (#16852) Thanks @sreuter. -- Agents/Tests: add `before_message_write` persistence regression coverage for block/mutate behavior (including synthetic tool-result flushes) and thrown-hook fallback persistence. (#18197) Thanks @shakkernerd -- Agents/Tools: scope the `message` tool schema to the active channel so Telegram uses `buttons` and Discord uses `components`. (#18215) Thanks @obviyus. -- Agents/Image tool: replace Anthropic-incompatible union schema with explicit `image` (single) and `images` (multi) parameters, keeping tool schemas `anyOf`/`oneOf`/`allOf`-free while preserving multi-image analysis support. (#18551, #18566) Thanks @aldoeliacim. -- Agents/Models: probe the primary model when its auth-profile cooldown is near expiry (with per-provider throttling), so runs recover from temporary rate limits without staying on fallback models until restart. (#17478) Thanks @PlayerGhost. -- Agents/Failover: classify provider abort stop-reason errors (`Unhandled stop reason: abort`, `stop reason: abort`, `reason: abort`) as timeout-class failures so configured model fallback chains trigger instead of surfacing raw abort failures. (#18618) Thanks @sauerdaniel. -- Models/CLI: sync auth-profiles credentials into agent `auth.json` before registry availability checks so `openclaw models list --all` reports auth correctly for API-key/token providers, normalize provider-id aliases when bridging credentials, and skip expired token mirrors. (#18610, #18615) -- Agents/Context: raise default total bootstrap prompt cap from `24000` to `150000` chars (keeping `bootstrapMaxChars` at `20000`), include total-cap visibility in `/context`, and mark truncation from injected-vs-raw sizes so total-cap clipping is reflected accurately. -- Memory/QMD: scope managed collection names per agent and precreate glob-backed collection directories before registration, preventing cross-agent collection clobbering and startup ENOENT failures in fresh workspaces. (#17194) Thanks @jonathanadams96. -- Cron: preserve per-job schedule-error isolation in post-run maintenance recompute so malformed sibling jobs no longer abort persistence of successful runs. (#17852) Thanks @pierreeurope. -- Gateway/Config: prevent `config.patch` object-array merges from falling back to full-array replacement when some patch entries lack `id`, so partial `agents.list` updates no longer drop unrelated agents. (#17989) Thanks @stakeswky. -- Gateway/Auth: trim whitespace around trusted proxy entries before matching so configured proxies with stray spaces still authorize. (#18084) Thanks @Clawborn. -- Config/Discord: require string IDs in Discord allowlists, keep onboarding inputs string-only, and add doctor repair for numeric entries. (#18220) Thanks @thewilloftheshadow. -- Security/Sessions: create new session transcript JSONL files with user-only (`0o600`) permissions and extend `openclaw security audit --fix` to remediate existing transcript file permissions. -- Sessions/Maintenance: archive transcripts when pruning stale sessions, clean expired media in subdirectories, and purge `.deleted` transcript archives after the prune window to prevent disk leaks. (#18538) -- Infra/Fetch: ensure foreign abort-signal listener cleanup never masks original fetch successes/failures, while still preventing detached-finally unhandled rejection noise in `wrapFetchWithAbortSignal`. Thanks @Jackten. -- Heartbeat: allow suppressing tool error warning payloads during heartbeat runs via a new heartbeat config flag. (#18497) Thanks @thewilloftheshadow. -- Heartbeat: include sender metadata (From/To/Provider) in heartbeat prompts so model context matches the delivery target. (#18532) Thanks @dinakars777. -- Heartbeat/Telegram: strip configured `responsePrefix` before heartbeat ack detection (with boundary-safe matching) so prefixed `HEARTBEAT_OK` replies are correctly suppressed instead of leaking into DMs. (#18602) - -## 2026.2.15 - -### Changes - -- Discord: unlock rich interactive agent prompts with Components v2 (buttons, selects, modals, and attachment-backed file blocks) so for native interaction through Discord. Thanks @thewilloftheshadow. -- Discord: components v2 UI + embeds passthrough + exec approval UX refinements (CV2 containers, button layout, Discord-forwarding skip). Thanks @thewilloftheshadow. -- Plugins: expose `llm_input` and `llm_output` hook payloads so extensions can observe prompt/input context and model output usage details. (#16724) Thanks @SecondThread. -- Subagents: nested sub-agents (sub-sub-agents) with configurable depth. Set `agents.defaults.subagents.maxSpawnDepth: 2` to allow sub-agents to spawn their own children. Includes `maxChildrenPerAgent` limit (default 5), depth-aware tool policy, and proper announce chain routing. (#14447) Thanks @tyler6204. -- Slack/Discord/Telegram: add per-channel ack reaction overrides (account/channel-level) to support platform-specific emoji formats. (#17092) Thanks @zerone0x. -- Telegram: add `channel_post` inbound support for channel-based bot-to-bot wake/trigger flows, with channel allowlist gating and message/media batching parity. -- Cron/Gateway: add finished-run webhook delivery toggle (`notify`) and dedicated webhook auth token support (`cron.webhookToken`) for outbound cron webhook posts. (#14535) Thanks @advaitpaliwal. -- Channels: deduplicate probe/token resolution base types across core + extensions while preserving per-channel error typing. (#16986) Thanks @iyoda and @thewilloftheshadow. -- Memory: add MMR (Maximal Marginal Relevance) re-ranking for hybrid search diversity. Configurable via `memorySearch.query.hybrid.mmr`. Thanks @rodrigouroz. -- Memory: add opt-in temporal decay for hybrid search scoring, with configurable half-life via `memorySearch.query.hybrid.temporalDecay`. Thanks @rodrigouroz. - -### Fixes - -- Discord: send initial content when creating non-forum threads so `thread-create` content is delivered. (#18117) Thanks @zerone0x. -- Security: replace deprecated SHA-1 sandbox configuration hashing with SHA-256 for deterministic sandbox cache identity and recreation checks. Thanks @kexinoh. -- Security/Logging: redact Telegram bot tokens from error messages and uncaught stack traces to prevent accidental secret leakage into logs. Thanks @aether-ai-agent. -- Sandbox/Security: block dangerous sandbox Docker config (bind mounts, host networking, unconfined seccomp/apparmor) to prevent container escape via config injection. Thanks @aether-ai-agent. -- Sandbox: preserve array order in config hashing so order-sensitive Docker/browser settings trigger container recreation correctly. Thanks @kexinoh. -- Gateway/Security: redact sensitive session/path details from `status` responses for non-admin clients; full details remain available to `operator.admin`. (#8590) Thanks @fr33d3m0n. -- Gateway/Control UI: preserve requested operator scopes for Control UI bypass modes (`allowInsecureAuth` / `dangerouslyDisableDeviceAuth`) when device identity is unavailable, preventing false `missing scope` failures on authenticated LAN/HTTP operator sessions. (#17682) Thanks @leafbird. -- LINE/Security: fail closed on webhook startup when channel token or channel secret is missing, and treat LINE accounts as configured only when both are present. (#17587) Thanks @davidahmann. -- Skills/Security: restrict `download` installer `targetDir` to the per-skill tools directory to prevent arbitrary file writes. Thanks @Adam55A-code. -- Skills/Linux: harden go installer fallback on apt-based systems by handling root/no-sudo environments safely, doing best-effort apt index refresh, and returning actionable errors instead of failing with spawn errors. (#17687) Thanks @mcrolly. -- Web Fetch/Security: cap downloaded response body size before HTML parsing to prevent memory exhaustion from oversized or deeply nested pages. Thanks @xuemian168. -- Config/Gateway: make sensitive-key whitelist suffix matching case-insensitive while preserving `passwordFile` path exemptions, preventing accidental redaction of non-secret config values like `maxTokens` and IRC password-file paths. (#16042) Thanks @akramcodez. -- Dev tooling: harden git `pre-commit` hook against option injection from malicious filenames (for example `--force`), preventing accidental staging of ignored files. Thanks @mrthankyou. -- Gateway/Agent: reject malformed `agent:`-prefixed session keys (for example, `agent:main`) in `agent` and `agent.identity.get` instead of silently resolving them to the default agent, preventing accidental cross-session routing. (#15707) Thanks @rodrigouroz. -- Gateway/Chat: harden `chat.send` inbound message handling by rejecting null bytes, stripping unsafe control characters, and normalizing Unicode to NFC before dispatch. (#8593) Thanks @fr33d3m0n. -- Gateway/Send: return an actionable error when `send` targets internal-only `webchat`, guiding callers to use `chat.send` or a deliverable channel. (#15703) Thanks @rodrigouroz. -- Gateway/Commands: keep webchat command authorization on the internal `webchat` context instead of inferring another provider from channel allowlists, fixing dropped `/new`/`/status` commands in Control UI when channel allowlists are configured. (#7189) Thanks @karlisbergmanis-lv. -- Control UI: prevent stored XSS via assistant name/avatar by removing inline script injection, serving bootstrap config as JSON, and enforcing `script-src 'self'`. Thanks @Adam55A-code. -- Agents/Security: sanitize workspace paths before embedding into LLM prompts (strip Unicode control/format chars) to prevent instruction injection via malicious directory names. Thanks @aether-ai-agent. -- Agents/Sandbox: clarify system prompt path guidance so sandbox `bash/exec` uses container paths (for example `/workspace`) while file tools keep host-bridge mapping, avoiding first-attempt path misses from host-only absolute paths in sandbox command execution. (#17693) Thanks @app/juniordevbot. -- Agents/Context: apply configured model `contextWindow` overrides after provider discovery so `lookupContextTokens()` honors operator config values (including discovery-failure paths). (#17404) Thanks @michaelbship and @vignesh07. -- Agents/Context: derive `lookupContextTokens()` from auth-available model metadata and keep the smallest discovered context window for duplicate model ids, preventing cross-provider cache collisions from overestimating session context limits. (#17586) Thanks @githabideri and @vignesh07. -- Agents/OpenAI: force `store=true` for direct OpenAI Responses/Codex runs to preserve multi-turn server-side conversation state, while leaving proxy/non-OpenAI endpoints unchanged. (#16803) Thanks @mark9232 and @vignesh07. -- Memory/FTS: make `buildFtsQuery` Unicode-aware so non-ASCII queries (including CJK) produce keyword tokens instead of falling back to vector-only search. (#17672) Thanks @KinGP5471. -- Auto-reply/Compaction: resolve `memory/YYYY-MM-DD.md` placeholders with timezone-aware runtime dates and append a `Current time:` line to memory-flush turns, preventing wrong-year memory filenames without making the system prompt time-variant. (#17603, #17633) Thanks @nicholaspapadam-wq and @vignesh07. -- Auth/Cooldowns: auto-expire stale auth profile cooldowns when `cooldownUntil` or `disabledUntil` timestamps have passed, and reset `errorCount` so the next transient failure does not immediately escalate to a disproportionately long cooldown. Handles `cooldownUntil` and `disabledUntil` independently. (#3604) Thanks @nabbilkhan. -- Agents: return an explicit timeout error reply when an embedded run times out before producing any payloads, preventing silent dropped turns during slow cache-refresh transitions. (#16659) Thanks @liaosvcaf and @vignesh07. -- Group chats: always inject group chat context (name, participants, reply guidance) into the system prompt on every turn, not just the first. Prevents the model from losing awareness of which group it's in and incorrectly using the message tool to send to the same group. (#14447) Thanks @tyler6204. -- Browser/Agents: when browser control service is unavailable, return explicit non-retry guidance (instead of "try again") so models do not loop on repeated browser tool calls until timeout. (#17673) Thanks @austenstone. -- Subagents: use child-run-based deterministic announce idempotency keys across direct and queued delivery paths (with legacy queued-item fallback) to prevent duplicate announce retries without collapsing distinct same-millisecond announces. (#17150) Thanks @widingmarcus-cyber. -- Subagents/Models: preserve `agents.defaults.model.fallbacks` when subagent sessions carry a model override, so subagent runs fail over to configured fallback models instead of retrying only the overridden primary model. -- Agents/Tools: scope the `message` tool schema to the active channel so Telegram uses `buttons` and Discord uses `components`. (#18215) Thanks @obviyus. -- Telegram: omit `message_thread_id` for DM sends/draft previews and keep forum-topic handling (`id=1` general omitted, non-general kept), preventing DM failures with `400 Bad Request: message thread not found`. (#10942) Thanks @garnetlyx. -- Telegram: replace inbound `` placeholder with successful preflight voice transcript in message body context, preventing placeholder-only prompt bodies for mention-gated voice messages. (#16789) Thanks @Limitless2023. -- Telegram: retry inbound media `getFile` calls (3 attempts with backoff) and gracefully fall back to placeholder-only processing when retries fail, preventing dropped voice/media messages on transient Telegram network errors. (#16154) Thanks @yinghaosang. -- Telegram: finalize streaming preview replies in place instead of sending a second final message, preventing duplicate Telegram assistant outputs at stream completion. (#17218) Thanks @obviyus. -- Discord: preserve channel session continuity when runtime payloads omit `message.channelId` by falling back to event/raw `channel_id` values for routing/session keys, so same-channel messages keep history across turns/restarts. Also align diagnostics so active Discord runs no longer appear as `sessionKey=unknown`. (#17622) Thanks @shakkernerd. -- Discord: dedupe native skill commands by skill name in multi-agent setups to prevent duplicated slash commands with `_2` suffixes. (#17365) Thanks @seewhyme. -- Discord: ensure role allowlist matching uses raw role IDs for message routing authorization. Thanks @xinhuagu. -- Discord: skip text-based exec approval forwarding in favor of Discord's component-based approval UI. Thanks @thewilloftheshadow. -- Web UI/Agents: hide `BOOTSTRAP.md` in the Agents Files list after onboarding is completed, avoiding confusing missing-file warnings for completed workspaces. (#17491) Thanks @gumadeiras. -- Memory/QMD: scope managed collection names per agent and precreate glob-backed collection directories before registration, preventing cross-agent collection clobbering and startup ENOENT failures in fresh workspaces. (#17194) Thanks @jonathanadams96. -- Gateway/Memory: initialize QMD startup sync for every configured agent (not just the default agent), so `memory.qmd.update.onBoot` is effective across multi-agent setups. (#17663) Thanks @HenryLoenwind. -- Auto-reply/WhatsApp/TUI/Web: when a final assistant message is `NO_REPLY` and a messaging tool send succeeded, mirror the delivered messaging-tool text into session-visible assistant output so TUI/Web no longer show `NO_REPLY` placeholders. (#7010) Thanks @Morrowind-Xie. -- Cron: infer `payload.kind="agentTurn"` for model-only `cron.update` payload patches, so partial agent-turn updates do not fail validation when `kind` is omitted. (#15664) Thanks @rodrigouroz. -- TUI: make searchable-select filtering and highlight rendering ANSI-aware so queries ignore hidden escape codes and no longer corrupt ANSI styling sequences during match highlighting. (#4519) Thanks @bee4come. -- TUI/Windows: coalesce rapid single-line submit bursts in Git Bash into one multiline message as a fallback when bracketed paste is unavailable, preventing pasted multiline text from being split into multiple sends. (#4986) Thanks @adamkane. -- TUI: suppress false `(no output)` placeholders for non-local empty final events during concurrent runs, preventing external-channel replies from showing empty assistant bubbles while a local run is still streaming. (#5782) Thanks @LagWizard and @vignesh07. -- TUI: preserve copy-sensitive long tokens (URLs/paths/file-like identifiers) during wrapping and overflow sanitization so wrapped output no longer inserts spaces that corrupt copy/paste values. (#17515, #17466, #17505) Thanks @abe238, @trevorpan, and @JasonCry. -- CLI/Build: make legacy daemon CLI compatibility shim generation tolerant of minimal tsdown daemon export sets, while preserving restart/register compatibility aliases and surfacing explicit errors for unavailable legacy daemon commands. Thanks @vignesh07. - -## 2026.2.14 - -### Changes - -- Telegram: add poll sending via `openclaw message poll` (duration seconds, silent delivery, anonymity controls). (#16209) Thanks @robbyczgw-cla. -- Slack/Discord: add `dmPolicy` + `allowFrom` config aliases for DM access control; legacy `dm.policy` + `dm.allowFrom` keys remain supported and `openclaw doctor --fix` can migrate them. -- Discord: allow exec approval prompts to target channels or both DM+channel via `channels.discord.execApprovals.target`. (#16051) Thanks @leonnardo. -- Sandbox: add `sandbox.browser.binds` to configure browser-container bind mounts separately from exec containers. (#16230) Thanks @seheepeak. -- Discord: add debug logging for message routing decisions to improve `--debug` tracing. (#16202) Thanks @jayleekr. -- Agents: add optional `messages.suppressToolErrors` config to hide non-mutating tool-failure warnings from user-facing chat while still surfacing mutating failures. (#16620) Thanks @vai-oro. - -### Fixes - -- CLI/Installation: fix Docker installation hangs on macOS. (#12972) Thanks @vincentkoc. -- Models: fix antigravity opus 4.6 availability follow-up. (#12845) Thanks @vincentkoc. -- Security/Sessions/Telegram: restrict session tool targeting by default to the current session tree (`tools.sessions.visibility`, default `tree`) with sandbox clamping, and pass configured per-account Telegram webhook secrets in webhook mode when no explicit override is provided. Thanks @aether-ai-agent. -- CLI/Plugins: ensure `openclaw message send` exits after successful delivery across plugin-backed channels so one-shot sends do not hang. (#16491) Thanks @yinghaosang. -- CLI/Plugins: run registered plugin `gateway_stop` hooks before `openclaw message` exits (success and failure paths), so plugin-backed channels can clean up one-shot CLI resources. (#16580) Thanks @gumadeiras. -- WhatsApp: honor per-account `dmPolicy` overrides (account-level settings now take precedence over channel defaults for inbound DMs). (#10082) Thanks @mcaxtr. -- Telegram: when `channels.telegram.commands.native` is `false`, exclude plugin commands from `setMyCommands` menu registration while keeping plugin slash handlers callable. (#15132) Thanks @Glucksberg. -- LINE: return 200 OK for Developers Console "Verify" requests (`{"events":[]}`) without `X-Line-Signature`, while still requiring signatures for real deliveries. (#16582) Thanks @arosstale. -- Cron: deliver text-only output directly when `delivery.to` is set so cron recipients get full output instead of summaries. (#16360) Thanks @thewilloftheshadow. -- Cron/Slack: preserve agent identity (name and icon) when cron jobs deliver outbound messages. (#16242) Thanks @robbyczgw-cla. -- Media: accept `MEDIA:`-prefixed paths (lenient whitespace) when loading outbound media to prevent `ENOENT` for tool-returned local media paths. (#13107) Thanks @mcaxtr. -- Media understanding: treat binary `application/vnd.*`/zip/octet-stream attachments as non-text (while keeping vendor `+json`/`+xml` text-eligible) so Office/ZIP files are not inlined into prompt body text. (#16513) Thanks @rmramsey32. -- Agents: deliver tool result media (screenshots, images, audio) to channels regardless of verbose level. (#11735) Thanks @strelov1. -- Auto-reply/Block streaming: strip leading whitespace from streamed block replies so messages starting with blank lines no longer deliver visible leading empty lines. (#16422) Thanks @mcinteerj. -- Auto-reply/Queue: keep queued followups and overflow summaries when drain attempts fail, then retry delivery instead of dropping messages on transient errors. (#16771) Thanks @mmhzlrj. -- Agents/Image tool: allow workspace-local image paths by including the active workspace directory in local media allowlists, and trust sandbox-validated paths in image loaders to prevent false "not under an allowed directory" rejections. (#15541) -- Agents/Image tool: propagate the effective workspace root into tool wiring so workspace-local image paths are accepted by default when running without an explicit `workspaceDir`. (#16722) -- BlueBubbles: include sender identity in group chat envelopes and pass clean message text to the agent prompt, aligning with iMessage/Signal formatting. (#16210) Thanks @zerone0x. -- CLI: fix lazy core command registration so top-level maintenance commands (`doctor`, `dashboard`, `reset`, `uninstall`) resolve correctly instead of exposing a non-functional `maintenance` placeholder command. -- CLI/Dashboard: when `gateway.bind=lan`, generate localhost dashboard URLs to satisfy browser secure-context requirements while preserving non-LAN bind behavior. (#16434) Thanks @BinHPdev. -- TUI/Gateway: resolve local gateway target URL from `gateway.bind` mode (tailnet/lan) instead of hardcoded localhost so `openclaw tui` connects when gateway is non-loopback. (#16299) Thanks @cortexuvula. -- TUI: honor explicit `--session ` in `openclaw tui` even when `session.scope` is `global`, so named sessions no longer collapse into shared global history. (#16575) Thanks @cinqu. -- TUI: use available terminal width for session name display in searchable select lists. (#16238) Thanks @robbyczgw-cla. -- TUI: preserve in-flight streaming replies when a different run finalizes concurrently (avoid clearing active run or reloading history mid-stream). (#10704) Thanks @axschr73. -- TUI: keep pre-tool streamed text visible when later tool-boundary deltas temporarily omit earlier text blocks. (#6958) Thanks @KrisKind75. -- TUI: sanitize ANSI/control-heavy history text, redact binary-like lines, and split pathological long unbroken tokens before rendering to prevent startup crashes on binary attachment history. (#13007) Thanks @wilkinspoe. -- TUI: harden render-time sanitizer for narrow terminals by chunking moderately long unbroken tokens and adding fast-path sanitization guards to reduce overhead on normal text. (#5355) Thanks @tingxueren. -- TUI: render assistant body text in terminal default foreground (instead of fixed light ANSI color) so contrast remains readable on light themes such as Solarized Light. (#16750) Thanks @paymog. -- TUI/Hooks: pass explicit reset reason (`new` vs `reset`) through `sessions.reset` and emit internal command hooks for gateway-triggered resets so `/new` hook workflows fire in TUI/webchat. -- Gateway/Agent: route bare `/new` and `/reset` through `sessions.reset` before running the fresh-session greeting prompt, so reset commands clear the current session in-place instead of falling through to normal agent runs. (#16732) Thanks @kdotndot and @vignesh07. -- Cron: prevent `cron list`/`cron status` from silently skipping past-due recurring jobs by using maintenance recompute semantics. (#16156) Thanks @zerone0x. -- Cron: repair missing/corrupt `nextRunAtMs` for the updated job without globally recomputing unrelated due jobs during `cron update`. (#15750) -- Cron: treat persisted jobs with missing `enabled` as enabled by default across update/list/timer due-path checks, and add regression coverage for missing-`enabled` store records. (#15433) Thanks @eternauta1337. -- Cron: skip missed-job replay on startup for jobs interrupted mid-run (stale `runningAtMs` markers), preventing restart loops for self-restarting jobs such as update tasks. (#16694) Thanks @sbmilburn. -- Heartbeat/Cron: treat cron-tagged queued system events as cron reminders even on interval wakes, so isolated cron announce summaries no longer run under the default heartbeat prompt. (#14947) Thanks @archedark-ada and @vignesh07. -- Discord: prefer gateway guild id when logging inbound messages so cached-miss guilds do not appear as `guild=dm`. Thanks @thewilloftheshadow. -- Discord: treat empty per-guild `channels: {}` config maps as no channel allowlist (not deny-all), so `groupPolicy: "open"` guilds without explicit channel entries continue to receive messages. (#16714) Thanks @xqliu. -- Models/CLI: guard `models status` string trimming paths to prevent crashes from malformed non-string config values. (#16395) Thanks @BinHPdev. -- Gateway/Subagents: preserve queued announce items and summary state on delivery errors, retry failed announce drains, and avoid dropping unsent announcements on timeout/failure. (#16729) Thanks @Clawdette-Workspace. -- Gateway/Config: make `config.patch` merge object arrays by `id` (for example `agents.list`) instead of replacing the whole array, so partial agent updates do not silently delete unrelated agents. (#6766) Thanks @lightclient. -- Webchat/Prompts: stop injecting direct-chat `conversation_label` into inbound untrusted metadata context blocks, preventing internal label noise from leaking into visible chat replies. (#16556) Thanks @nberardi. -- Auto-reply/Prompts: include trusted inbound `message_id`, `chat_id`, `reply_to_id`, and optional `message_id_full` metadata fields so action tools (for example reactions) can target the triggering message without relying on user text. (#17662) Thanks @MaikiMolto. -- Gateway/Sessions: abort active embedded runs and clear queued session work before `sessions.reset`, returning unavailable if the run does not stop in time. (#16576) Thanks @Grynn. -- Sessions/Agents: harden transcript path resolution for mismatched agent context by preserving explicit store roots and adding safe absolute-path fallback to the correct agent sessions directory. (#16288) Thanks @robbyczgw-cla. -- Agents: add a safety timeout around embedded `session.compact()` to ensure stalled compaction runs settle and release blocked session lanes. (#16331) Thanks @BinHPdev. -- Agents/Tools: make required-parameter validation errors list missing fields and instruct: "Supply correct parameters before retrying," reducing repeated invalid tool-call loops (for example `read({})`). (#14729) -- Agents: keep unresolved mutating tool failures visible until the same action retry succeeds, scope mutation-error surfacing to mutating calls (including `session_status` model changes), and dedupe duplicate failure warnings in outbound replies. (#16131) Thanks @Swader. -- Agents/Process/Bootstrap: preserve unbounded `process log` offset-only pagination (default tail applies only when both `offset` and `limit` are omitted) and enforce strict `bootstrapTotalMaxChars` budgeting across injected bootstrap content (including markers), skipping additional injection when remaining budget is too small. (#16539) Thanks @CharlieGreenman. -- Agents/Workspace: persist bootstrap onboarding state so partially initialized workspaces recover missing `BOOTSTRAP.md` once, while completed onboarding keeps BOOTSTRAP deleted even if runtime files are later recreated. Thanks @gumadeiras. -- Agents/Workspace: create `BOOTSTRAP.md` when core workspace files are seeded in partially initialized workspaces, while keeping BOOTSTRAP one-shot after onboarding deletion. (#16457) Thanks @robbyczgw-cla. -- Agents: classify external timeout aborts during compaction the same as internal timeouts, preventing unnecessary auth-profile rotation and preserving compaction-timeout snapshot fallback behavior. (#9855) Thanks @mverrilli. -- Agents: treat empty-stream provider failures (`request ended without sending any chunks`) as timeout-class failover signals, enabling auth-profile rotation/fallback and showing a friendly timeout message instead of raw provider errors. (#10210) Thanks @zenchantlive. -- Agents: treat `read` tool `file_path` arguments as valid in tool-start diagnostics to avoid false “read tool called without path” warnings when alias parameters are used. (#16717) Thanks @Stache73. -- Agents/Transcript: drop malformed tool-call blocks with blank required fields (`id`/`name` or missing `input`/`arguments`) during session transcript repair to prevent persistent tool-call corruption on future turns. (#15485) Thanks @mike-zachariades. -- Tools/Write/Edit: normalize structured text-block arguments for `content`/`oldText`/`newText` before filesystem edits, preventing JSON-like file corruption and false “exact text not found” misses from block-form params. (#16778) Thanks @danielpipernz. -- Ollama/Agents: avoid forcing `` tag enforcement for Ollama models, which could suppress all output as `(no output)`. (#16191) Thanks @Glucksberg. -- Plugins: suppress false duplicate plugin id warnings when the same extension is discovered via multiple paths (config/workspace/global vs bundled), while still warning on genuine duplicates. (#16222) Thanks @shadril238. -- Agents/Process: supervise PTY/child process lifecycles with explicit ownership, cancellation, timeouts, and deterministic cleanup, preventing Codex/Pi PTY sessions from dying or stalling on resume. (#14257) Thanks @onutc. -- Skills: watch `SKILL.md` only when refreshing skills snapshot to avoid file-descriptor exhaustion in large data trees. (#11325) Thanks @household-bard. -- Memory/QMD: make `memory status` read-only by skipping QMD boot update/embed side effects for status-only manager checks. -- Memory/QMD: keep original QMD failures when builtin fallback initialization fails (for example missing embedding API keys), instead of replacing them with fallback init errors. -- Memory/Builtin: keep `memory status` dirty reporting stable across invocations by deriving status-only manager dirty state from persisted index metadata instead of process-start defaults. (#10863) Thanks @BarryYangi. -- Memory/QMD: cap QMD command output buffering to prevent memory exhaustion from pathological `qmd` command output. -- Memory/QMD: parse qmd scope keys once per request to avoid repeated parsing in scope checks. -- Memory/QMD: query QMD index using exact docid matches before falling back to prefix lookup for better recall correctness and index efficiency. -- Memory/QMD: pass result limits to `search`/`vsearch` commands so QMD can cap results earlier. -- Memory/QMD: avoid reading full markdown files when a `from/lines` window is requested in QMD reads. -- Memory/QMD: skip rewriting unchanged session export markdown files during sync to reduce disk churn. -- Memory/QMD: make QMD result JSON parsing resilient to noisy command output by extracting the first JSON array from noisy `stdout`. -- Memory/QMD: treat prefixed `no results found` marker output as an empty result set in qmd JSON parsing. (#11302) Thanks @blazerui. -- Memory/QMD: avoid multi-collection `query` ranking corruption by running one `qmd query -c ` per managed collection and merging by best score (also used for `search`/`vsearch` fallback-to-query). (#16740) Thanks @volarian-vai. -- Memory/QMD: rebind managed collections when existing collection metadata drifts (including sessions name-only listings), preventing non-default agents from reusing another agent's `sessions` collection path. (#17194) Thanks @jonathanadams96. -- Memory/QMD: make `openclaw memory index` verify and print the active QMD index file path/size, and fail when QMD leaves a missing or zero-byte index artifact after an update. (#16775) Thanks @Shunamxiao. -- Memory/QMD: detect null-byte `ENOTDIR` update failures, rebuild managed collections once, and retry update to self-heal corrupted collection metadata. (#12919) Thanks @jorgejhms. -- Memory/QMD/Security: add `rawKeyPrefix` support for QMD scope rules and preserve legacy `keyPrefix: "agent:..."` matching, preventing scoped deny bypass when operators match agent-prefixed session keys. -- Memory/Builtin: narrow memory watcher targets to markdown globs and ignore dependency/venv directories to reduce file-descriptor pressure during memory sync startup. (#11721) Thanks @rex05ai. -- Security/Memory-LanceDB: treat recalled memories as untrusted context (escape injected memory text + explicit non-instruction framing), skip likely prompt-injection payloads during auto-capture, and restrict auto-capture to user messages to reduce memory-poisoning risk. (#12524) Thanks @davidschmid24. -- Security/Memory-LanceDB: require explicit `autoCapture: true` opt-in (default is now disabled) to prevent automatic PII capture unless operators intentionally enable it. (#12552) Thanks @fr33d3m0n. -- Diagnostics/Memory: prune stale diagnostic session state entries and cap tracked session states to prevent unbounded in-memory growth on long-running gateways. (#5136) Thanks @coygeek and @vignesh07. -- Gateway/Memory: clean up `agentRunSeq` tracking on run completion/abort and enforce maintenance-time cap pruning to prevent unbounded sequence-map growth over long uptimes. (#6036) Thanks @coygeek and @vignesh07. -- Auto-reply/Memory: bound `ABORT_MEMORY` growth by evicting oldest entries and deleting reset (`false`) flags so abort state tracking cannot grow unbounded over long uptimes. (#6629) Thanks @coygeek and @vignesh07. -- Slack/Memory: bound thread-starter cache growth with TTL + max-size pruning to prevent long-running Slack gateways from accumulating unbounded thread cache state. (#5258) Thanks @coygeek and @vignesh07. -- Outbound/Memory: bound directory cache growth with max-size eviction and proactive TTL pruning to prevent long-running gateways from accumulating unbounded directory entries. (#5140) Thanks @coygeek and @vignesh07. -- Skills/Memory: remove disconnected nodes from remote-skills cache to prevent stale node metadata from accumulating over long uptimes. (#6760) Thanks @coygeek. -- Sandbox/Tools: make sandbox file tools bind-mount aware (including absolute container paths) and enforce read-only bind semantics for writes. (#16379) Thanks @tasaankaeris. -- Sandbox/Prompts: show the sandbox container workdir as the prompt working directory and clarify host-path usage for file tools, preventing host-path `exec` failures in sandbox sessions. (#16790) Thanks @carrotRakko. -- Media/Security: allow local media reads from OpenClaw state `workspace/` and `sandboxes/` roots by default so generated workspace media can be delivered without unsafe global path bypasses. (#15541) Thanks @lanceji. -- Media/Security: harden local media allowlist bypasses by requiring an explicit `readFile` override when callers mark paths as validated, and reject filesystem-root `localRoots` entries. (#16739) -- Media/Security: allow outbound local media reads from the active agent workspace (including `workspace-`) via agent-scoped local roots, avoiding broad global allowlisting of all per-agent workspaces. (#17136) Thanks @MisterGuy420. -- Outbound/Media: thread explicit `agentId` through core `sendMessage` direct-delivery path so agent-scoped local media roots apply even when mirror metadata is absent. (#17268) Thanks @gumadeiras. -- Discord/Security: harden voice message media loading (SSRF + allowed-local-root checks) so tool-supplied paths/URLs cannot be used to probe internal URLs or read arbitrary local files. -- Security/BlueBubbles: require explicit `mediaLocalRoots` allowlists for local outbound media path reads to prevent local file disclosure. (#16322) Thanks @mbelinky. -- Security/BlueBubbles: reject ambiguous shared-path webhook routing when multiple webhook targets match the same guid/password. -- Security/BlueBubbles: harden BlueBubbles webhook auth behind reverse proxies by only accepting passwordless webhooks for direct localhost loopback requests (forwarded/proxied requests now require a password). Thanks @simecek. -- Feishu/Security: harden media URL fetching against SSRF and local file disclosure. (#16285) Thanks @mbelinky. -- Security/Zalo: reject ambiguous shared-path webhook routing when multiple webhook targets match the same secret. -- Security/Nostr: require loopback source and block cross-origin profile mutation/import attempts. Thanks @vincentkoc. -- Security/Signal: harden signal-cli archive extraction during install to prevent path traversal outside the install root. -- Security/Hooks: restrict hook transform modules to `~/.openclaw/hooks/transforms` (prevents path traversal/escape module loads via config). Config note: `hooks.transformsDir` must now be within that directory. Thanks @akhmittra. -- Security/Hooks: ignore hook package manifest entries that point outside the package directory (prevents out-of-tree handler loads during hook discovery). -- Security/Archive: enforce archive extraction entry/size limits to prevent resource exhaustion from high-expansion ZIP/TAR archives. Thanks @vincentkoc. -- Security/Media: reject oversized base64-backed input media before decoding to avoid large allocations. Thanks @vincentkoc. -- Security/Media: stream and bound URL-backed input media fetches to prevent memory exhaustion from oversized responses. Thanks @vincentkoc. -- Security/Skills: harden archive extraction for download-installed skills to prevent path traversal outside the target directory. Thanks @markmusson. -- Security/Slack: compute command authorization for DM slash commands even when `dmPolicy=open`, preventing unauthorized users from running privileged commands via DM. Thanks @christos-eth. -- Security/Pairing: scope pairing allowlist writes/reads to channel accounts (for example `telegram:yy`), and propagate account-aware pairing approvals so multi-account channels do not share a single per-channel pairing allowFrom store. (#17631) Thanks @crazytan. -- Security/iMessage: keep DM pairing-store identities out of group allowlist authorization (prevents cross-context command authorization). Thanks @vincentkoc. -- Security/Google Chat: deprecate `users/` allowlists (treat `users/...` as immutable user id only); keep raw email allowlists for usability. Thanks @vincentkoc. -- Security/Google Chat: reject ambiguous shared-path webhook routing when multiple webhook targets verify successfully (prevents cross-account policy-context misrouting). Thanks @vincentkoc. -- Telegram/Security: require numeric Telegram sender IDs for allowlist authorization (reject `@username` principals), auto-resolve `@username` to IDs in `openclaw doctor --fix` (when possible), and warn in `openclaw security audit` when legacy configs contain usernames. Thanks @vincentkoc. -- Telegram/Security: reject Telegram webhook startup when `webhookSecret` is missing or empty (prevents unauthenticated webhook request forgery). Thanks @yueyueL. -- Security/Windows: avoid shell invocation when spawning child processes to prevent cmd.exe metacharacter injection via untrusted CLI arguments (e.g. agent prompt text). -- Telegram: set webhook callback timeout handling to `onTimeout: "return"` (10s) so long-running update processing no longer emits webhook 500s and retry storms. (#16763) Thanks @chansearrington. -- Signal: preserve case-sensitive `group:` target IDs during normalization so mixed-case group IDs no longer fail with `Group not found`. (#16748) Thanks @repfigit. -- Security/Agents: scope CLI process cleanup to owned child PIDs to avoid killing unrelated processes on shared hosts. Thanks @aether-ai-agent. -- Security/Agents: enforce workspace-root path bounds for `apply_patch` in non-sandbox mode to block traversal and symlink escape writes. Thanks @p80n-sec. -- Security/Agents: enforce symlink-escape checks for `apply_patch` delete hunks under `workspaceOnly`, while still allowing deleting the symlink itself. Thanks @p80n-sec. -- Security/Agents (macOS): prevent shell injection when writing Claude CLI keychain credentials. (#15924) Thanks @aether-ai-agent. -- macOS: hard-limit unkeyed `openclaw://agent` deep links and ignore `deliver` / `to` / `channel` unless a valid unattended key is provided. Thanks @Cillian-Collins. -- Scripts/Security: validate GitHub logins and avoid shell invocation in `scripts/update-clawtributors.ts` to prevent command injection via malicious commit records. Thanks @scanleale. -- Security: fix Chutes manual OAuth login state validation by requiring the full redirect URL (reject code-only pastes) (thanks @aether-ai-agent). -- Security/Gateway: harden tool-supplied `gatewayUrl` overrides by restricting them to loopback or the configured `gateway.remote.url`. Thanks @p80n-sec. -- Security/Gateway: block `system.execApprovals.*` via `node.invoke` (use `exec.approvals.node.*` instead). Thanks @christos-eth. -- Security/Gateway: reject oversized base64 chat attachments before decoding to avoid large allocations. Thanks @vincentkoc. -- Security/Gateway: stop returning raw resolved config values in `skills.status` requirement checks (prevents operator.read clients from reading secrets). Thanks @simecek. -- Security/Net: fix SSRF guard bypass via full-form IPv4-mapped IPv6 literals (blocks loopback/private/metadata access). Thanks @yueyueL. -- Security/Browser: harden browser control file upload + download helpers to prevent path traversal / local file disclosure. Thanks @1seal. -- Security/Browser: block cross-origin mutating requests to loopback browser control routes (CSRF hardening). Thanks @vincentkoc. -- Security/Node Host: enforce `system.run` rawCommand/argv consistency to prevent allowlist/approval bypass. Thanks @christos-eth. -- Security/Exec approvals: prevent safeBins allowlist bypass via shell expansion (host exec allowlist mode only; not enabled by default). Thanks @christos-eth. -- Security/Exec: harden PATH handling by disabling project-local `node_modules/.bin` bootstrapping by default, disallowing node-host `PATH` overrides, and spawning ACP servers via the current executable by default. Thanks @akhmittra. -- Security/Tlon: harden Urbit URL fetching against SSRF by blocking private/internal hosts by default (opt-in: `channels.tlon.allowPrivateNetwork`). Thanks @p80n-sec. -- Security/Voice Call (Telnyx): require webhook signature verification when receiving inbound events; configs without `telnyx.publicKey` are now rejected unless `skipSignatureVerification` is enabled. Thanks @p80n-sec. -- Security/Voice Call: require valid Twilio webhook signatures even when ngrok free tier loopback compatibility mode is enabled. Thanks @p80n-sec. -- Security/Discovery: stop treating Bonjour TXT records as authoritative routing (prefer resolved service endpoints) and prevent discovery from overriding stored TLS pins; autoconnect now requires a previously trusted gateway. Thanks @simecek. - -## 2026.2.13 - -### Changes - -- Install: add optional Podman-based setup: `setup-podman.sh` for one-time host setup (openclaw user, image, launch script, systemd quadlet), `run-openclaw-podman.sh launch` / `launch setup`; systemd Quadlet unit for openclaw user service; docs for rootless container, openclaw user (subuid/subgid), and quadlet (troubleshooting). (#16273) Thanks @DarwinsBuddy. -- Discord: send voice messages with waveform previews from local audio files (including silent delivery). (#7253) Thanks @nyanjou. -- Discord: add configurable presence status/activity/type/url (custom status defaults to activity text). (#10855) Thanks @h0tp-ftw. -- Slack/Plugins: add thread-ownership outbound gating via `message_sending` hooks, including @-mention bypass tracking and Slack outbound hook wiring for cancel/modify behavior. (#15775) Thanks @DarlingtonDeveloper. -- Agents: add synthetic catalog support for `hf:zai-org/GLM-5`. (#15867) Thanks @battman21. -- Skills: remove duplicate `local-places` Google Places skill/proxy and keep `goplaces` as the single supported Google Places path. -- Agents: add pre-prompt context diagnostics (`messages`, `systemPromptChars`, `promptChars`, provider/model, session file) before embedded runner prompt calls to improve overflow debugging. (#8930) Thanks @Glucksberg. -- Onboarding/Providers: add first-class Hugging Face Inference provider support (provider wiring, onboarding auth choice/API key flow, and default-model selection), and preserve Hugging Face auth intent in auth-choice remapping (`tokenProvider=huggingface` with `authChoice=apiKey`) while skipping env-override prompts when an explicit token is provided. (#13472) Thanks @Josephrp. -- Onboarding/Providers: add `minimax-api-key-cn` auth choice for the MiniMax China API endpoint. (#15191) Thanks @liuy. - -### Breaking - -- Config/State: removed legacy `.moltbot` auto-detection/migration and `moltbot.json` config candidates. If you still have state/config under `~/.moltbot`, move it to `~/.openclaw` (recommended) or set `OPENCLAW_STATE_DIR` / `OPENCLAW_CONFIG_PATH` explicitly. - -### Fixes - -- Gateway/Auth: add trusted-proxy mode hardening follow-ups by keeping `OPENCLAW_GATEWAY_*` env compatibility, auto-normalizing invalid setup combinations in interactive `gateway configure` (trusted-proxy forces `bind=lan` and disables Tailscale serve/funnel), and suppressing shared-secret/rate-limit audit findings that do not apply to trusted-proxy deployments. (#15940) Thanks @nickytonline. -- Docs/Hooks: update hooks documentation URLs to the new `/automation/hooks` location. (#16165) Thanks @nicholascyh. -- Security/Audit: warn when `gateway.tools.allow` re-enables default-denied tools over HTTP `POST /tools/invoke`, since this can increase RCE blast radius if the gateway is reachable. -- Security/Plugins/Hooks: harden npm-based installs by restricting specs to registry packages only, passing `--ignore-scripts` to `npm pack`, and cleaning up temp install directories. -- Security/Sessions: preserve inter-session input provenance for routed prompts so delegated/internal sessions are not treated as direct external user instructions. Thanks @anbecker. -- Feishu: stop persistent Typing reaction on NO_REPLY/suppressed runs by wiring reply-dispatcher cleanup to remove typing indicators. (#15464) Thanks @arosstale. -- Agents: strip leading empty lines from `sanitizeUserFacingText` output and normalize whitespace-only outputs to empty text. (#16158) Thanks @mcinteerj. -- BlueBubbles: gracefully degrade when Private API is disabled by filtering private-only actions, skipping private-only reactions/reply effects, and avoiding private reply markers so non-private flows remain usable. (#16002) Thanks @L-U-C-K-Y. -- Outbound: add a write-ahead delivery queue with crash-recovery retries to prevent lost outbound messages after gateway restarts. (#15636) Thanks @nabbilkhan, @thewilloftheshadow. -- Auto-reply/Threading: auto-inject implicit reply threading so `replyToMode` works without requiring model-emitted `[[reply_to_current]]`, while preserving `replyToMode: "off"` behavior for implicit Slack replies and keeping block-streaming chunk coalescing stable under `replyToMode: "first"`. (#14976) Thanks @Diaspar4u. -- Auto-reply/Threading: honor explicit `[[reply_to_*]]` tags even when `replyToMode` is `off`. (#16174) Thanks @aldoeliacim. -- Plugins/Threading: rename `allowTagsWhenOff` to `allowExplicitReplyTagsWhenOff` and keep the old key as a deprecated alias for compatibility. (#16189) -- Outbound/Threading: pass `replyTo` and `threadId` from `message send` tool actions through the core outbound send path to channel adapters, preserving thread/reply routing. (#14948) Thanks @mcaxtr. -- Auto-reply/Media: allow image-only inbound messages (no caption) to reach the agent instead of short-circuiting as empty text, and preserve thread context in queued/followup prompt bodies for media-only runs. (#11916) Thanks @arosstale. -- Discord: route autoThread replies to existing threads instead of the root channel. (#8302) Thanks @gavinbmoore, @thewilloftheshadow. -- Web UI: add `img` to DOMPurify allowed tags and `src`/`alt` to allowed attributes so markdown images render in webchat instead of being stripped. (#15437) Thanks @lailoo. -- Telegram/Matrix: treat MP3 and M4A (including `audio/mp4`) as voice-compatible for `asVoice` routing, and keep WAV/AAC falling back to regular audio sends. (#15438) Thanks @azade-c. -- WhatsApp: preserve outbound document filenames for web-session document sends instead of always sending `"file"`. (#15594) Thanks @TsekaLuk. -- Telegram: cap bot menu registration to Telegram's 100-command limit with an overflow warning while keeping typed hidden commands available. (#15844) Thanks @battman21. -- Telegram: scope skill commands to the resolved agent for default accounts so `setMyCommands` no longer triggers `BOT_COMMANDS_TOO_MUCH` when multiple agents are configured. (#15599) -- Discord: avoid misrouting numeric guild allowlist entries to `/channels/` by prefixing guild-only inputs with `guild:` during resolution. (#12326) Thanks @headswim. -- Memory/QMD: default `memory.qmd.searchMode` to `search` for faster CPU-only recall and always scope `search`/`vsearch` requests to managed collections (auto-falling back to `query` when required). (#16047) Thanks @togotago. -- Memory/LanceDB: add configurable `captureMaxChars` for auto-capture while keeping the legacy 500-char default. (#16641) Thanks @ciberponk. -- MS Teams: preserve parsed mention entities/text when appending OneDrive fallback file links, and accept broader real-world Teams mention ID formats (`29:...`, `8:orgid:...`) while still rejecting placeholder patterns. (#15436) Thanks @hyojin. -- Media: classify `text/*` MIME types as documents in media-kind routing so text attachments are no longer treated as unknown. (#12237) Thanks @arosstale. -- Inbound/Web UI: preserve literal `\n` sequences when normalizing inbound text so Windows paths like `C:\\Work\\nxxx\\README.md` are not corrupted. (#11547) Thanks @mcaxtr. -- TUI/Streaming: preserve richer streamed assistant text when final payload drops pre-tool-call text blocks, while keeping non-empty final payload authoritative for plain-text updates. (#15452) Thanks @TsekaLuk. -- Providers/MiniMax: switch implicit MiniMax API-key provider from `openai-completions` to `anthropic-messages` with the correct Anthropic-compatible base URL, fixing `invalid role: developer (2013)` errors on MiniMax M2.5. (#15275) Thanks @lailoo. -- Ollama/Agents: use resolved model/provider base URLs for native `/api/chat` streaming (including aliased providers), normalize `/v1` endpoints, and forward abort + `maxTokens` stream options for reliable cancellation and token caps. (#11853) Thanks @BrokenFinger98. -- OpenAI Codex/Spark: implement end-to-end `gpt-5.3-codex-spark` support across fallback/thinking/model resolution and `models list` forward-compat visibility. (#14990, #15174) Thanks @L-U-C-K-Y, @loiie45e. -- Agents/Codex: allow `gpt-5.3-codex-spark` in forward-compat fallback, live model filtering, and thinking presets, and fix model-picker recognition for spark. (#14990) Thanks @L-U-C-K-Y. -- Models/Codex: resolve configured `openai-codex/gpt-5.3-codex-spark` through forward-compat fallback during `models list`, so it is not incorrectly tagged as missing when runtime resolution succeeds. (#15174) Thanks @loiie45e. -- OpenAI Codex/Auth: bridge OpenClaw OAuth profiles into `pi` `auth.json` so model discovery and models-list registry resolution can use Codex OAuth credentials. (#15184) Thanks @loiie45e. -- Auth/OpenAI Codex: share OAuth login handling across onboarding and `models auth login --provider openai-codex`, keep onboarding alive when OAuth fails, and surface a direct OAuth help note instead of terminating the wizard. (#15406, follow-up to #14552) Thanks @zhiluo20. -- Onboarding/Providers: add vLLM as an onboarding provider with model discovery, auth profile wiring, and non-interactive auth-choice validation. (#12577) Thanks @gejifeng. -- Onboarding/CLI: restore terminal state without resuming paused `stdin`, so onboarding exits cleanly (including Docker TTY installs that would otherwise hang). (#12972) Thanks @vincentkoc. -- Signal/Install: auto-install `signal-cli` via Homebrew on non-x64 Linux architectures, avoiding x86_64 native binary `Exec format error` failures on arm64/arm hosts. (#15443) Thanks @jogvan-k. -- macOS Voice Wake: fix a crash in trigger trimming for CJK/Unicode transcripts by matching and slicing on original-string ranges instead of transformed-string indices. (#11052) Thanks @Flash-LHR. -- Mattermost (plugin): retry websocket monitor connections with exponential backoff and abort-aware teardown so transient connect failures no longer permanently stop monitoring. (#14962) Thanks @mcaxtr. -- Discord/Agents: apply channel/group `historyLimit` during embedded-runner history compaction to prevent long-running channel sessions from bypassing truncation and overflowing context windows. (#11224) Thanks @shadril238. -- Outbound targets: fail closed for WhatsApp/Twitch/Google Chat fallback paths so invalid or missing targets are dropped instead of rerouted, and align resolver hints with strict target requirements. (#13578) Thanks @mcaxtr. -- Gateway/Restart: clear stale command-queue and heartbeat wake runtime state after SIGUSR1 in-process restarts to prevent zombie gateway behavior where queued work stops draining. (#15195) Thanks @joeykrug. -- Heartbeat: prevent scheduler silent-death races during runner reloads, preserve retry cooldown backoff under wake bursts, and prioritize user/action wake causes over interval/retry reasons when coalescing. (#15108) Thanks @joeykrug. -- Heartbeat: allow explicit wake (`wake`) and hook wake (`hook:*`) reasons to run even when `HEARTBEAT.md` is effectively empty so queued system events are processed. (#14527) Thanks @arosstale. -- Auto-reply/Heartbeat: strip sentence-ending `HEARTBEAT_OK` tokens even when followed by up to 4 punctuation characters, while preserving surrounding sentence punctuation. (#15847) Thanks @Spacefish. -- Sessions/Agents: pass `agentId` when resolving existing transcript paths in reply runs so non-default agents and heartbeat/chat handlers no longer fail with `Session file path must be within sessions directory`. (#15141) Thanks @Goldenmonstew. -- Sessions/Agents: pass `agentId` through status and usage transcript-resolution paths (auto-reply, gateway usage APIs, and session cost/log loaders) so non-default agents can resolve absolute session files without path-validation failures. (#15103) Thanks @jalehman. -- Sessions: archive previous transcript files on `/new` and `/reset` session resets (including gateway `sessions.reset`) so stale transcripts do not accumulate on disk. (#14869) Thanks @mcaxtr. -- Status/Sessions: stop clamping derived `totalTokens` to context-window size, keep prompt-token snapshots wired through session accounting, and surface context usage as unknown when fresh snapshot data is missing to avoid false 100% reports. (#15114) Thanks @echoVic. -- Gateway/Routing: speed up hot paths for session listing (derived titles + previews), WS broadcast, and binding resolution. -- Gateway/Sessions: cache derived title + last-message transcript reads to speed up repeated sessions list refreshes. -- CLI/Completion: route plugin-load logs to stderr and write generated completion scripts directly to stdout to avoid `source <(openclaw completion ...)` corruption. (#15481) Thanks @arosstale. -- CLI: lazily load outbound provider dependencies and remove forced success-path exits so commands terminate naturally without killing intentional long-running foreground actions. (#12906) Thanks @DrCrinkle. -- CLI: speed up startup by lazily registering core commands (keeps rich `--help` while reducing cold-start overhead). -- Security/Gateway + ACP: block high-risk tools (`sessions_spawn`, `sessions_send`, `gateway`, `whatsapp_login`) from HTTP `/tools/invoke` by default with `gateway.tools.{allow,deny}` overrides, and harden ACP permission selection to fail closed when tool identity/options are ambiguous while supporting `allow_always`/`reject_always`. (#15390) Thanks @aether-ai-agent. -- Security/ACP: prompt for non-read/search permission requests in ACP clients (reduces silent tool approval risk). Thanks @aether-ai-agent. -- Security/Gateway: breaking default-behavior change - canvas IP-based auth fallback now only accepts machine-scoped addresses (RFC1918, link-local, ULA IPv6, CGNAT); public-source IP matches now require bearer token auth. (#14661) Thanks @sumleo. -- Security/Link understanding: block loopback/internal host patterns and private/mapped IPv6 addresses in extracted URL handling to close SSRF bypasses in link CLI flows. (#15604) Thanks @AI-Reviewer-QS. -- Security/Browser: constrain `POST /trace/stop`, `POST /wait/download`, and `POST /download` output paths to OpenClaw temp roots and reject traversal/escape paths. -- Security/Browser: sanitize download `suggestedFilename` to keep implicit `wait/download` paths within the downloads root. Thanks @1seal. -- Security/Browser: confine `POST /hooks/file-chooser` upload paths to an OpenClaw temp uploads root and reject traversal/escape paths. Thanks @1seal. -- Security/Browser: require auth for the sandbox browser bridge server (protects `/profiles`, `/tabs`, CDP URLs, and other control endpoints). Thanks @jackhax. -- Security: bind local helper servers to loopback and fail closed on non-loopback OAuth callback hosts (reduces localhost/LAN attack surface). -- Security/Canvas: serve A2UI assets via the shared safe-open path (`openFileWithinRoot`) to close traversal/TOCTOU gaps, with traversal and symlink regression coverage. (#10525) Thanks @abdelsfane. -- Security/WhatsApp: enforce `0o600` on `creds.json` and `creds.json.bak` on save/backup/restore paths to reduce credential file exposure. (#10529) Thanks @abdelsfane. -- Security/Gateway: sanitize and truncate untrusted WebSocket header values in pre-handshake close logs to reduce log-poisoning risk. Thanks @thewilloftheshadow. -- Security/Audit: add misconfiguration checks for sandbox Docker config with sandbox mode off, ineffective `gateway.nodes.denyCommands` entries, global minimal tool-profile overrides by agent profiles, and permissive extension-plugin tool reachability. -- Security/Audit: distinguish external webhooks (`hooks.enabled`) from internal hooks (`hooks.internal.enabled`) in attack-surface summaries to avoid false exposure signals when only internal hooks are enabled. (#13474) Thanks @mcaxtr. -- Security/Onboarding: clarify multi-user DM isolation remediation with explicit `openclaw config set session.dmScope ...` commands in security audit, doctor security, and channel onboarding guidance. (#13129) Thanks @VintLin. -- Security/Gateway: bind node `system.run` approval overrides to gateway exec-approval records (runId-bound), preventing approval-bypass via `node.invoke` param injection. Thanks @222n5. -- Agents/Nodes: harden node exec approval decision handling in the `nodes` tool run path by failing closed on unexpected approval decisions, and add regression coverage for approval-required retry/deny/timeout flows. (#4726) Thanks @rmorse. -- Android/Nodes: harden `app.update` by requiring HTTPS and gateway-host URL matching plus SHA-256 verification, stream URL camera downloads to disk with size guards to avoid memory spikes, and stop signing release builds with debug keys. (#13541) Thanks @smartprogrammer93. -- Routing: enforce strict binding-scope matching across peer/guild/team/roles so peer-scoped Discord/Slack bindings no longer match unrelated guild/team contexts or fallback tiers. (#15274) Thanks @lailoo. -- Exec/Allowlist: allow multiline heredoc bodies (`<<`, `<<-`) while keeping multiline non-heredoc shell commands blocked, so exec approval parsing permits heredoc input safely without allowing general newline command chaining. (#13811) Thanks @mcaxtr. -- Config: preserve `${VAR}` env references when writing config files so `openclaw config set/apply/patch` does not persist secrets to disk. Thanks @thewilloftheshadow. -- Config: remove a cross-request env-snapshot race in config writes by carrying read-time env context into write calls per request, preserving `${VAR}` refs safely under concurrent gateway config mutations. (#11560) Thanks @akoscz. -- Config: log overwrite audit entries (path, backup target, and hash transition) whenever an existing config file is replaced, improving traceability for unexpected config clobbers. -- Config: keep legacy audio transcription migration strict by rejecting non-string/unsafe command tokens while still migrating valid custom script executables. (#5042) Thanks @shayan919293. -- Config: accept `$schema` key in config file so JSON Schema editor tooling works without validation errors. (#14998) -- Gateway/Tools Invoke: sanitize `/tools/invoke` execution failures while preserving `400` for tool input errors and returning `500` for unexpected runtime failures, with regression coverage and docs updates. (#13185) Thanks @davidrudduck. -- Gateway/Hooks: preserve `408` for hook request-body timeout responses while keeping bounded auth-failure cache eviction behavior, with timeout-status regression coverage. (#15848) Thanks @AI-Reviewer-QS. -- Plugins/Hooks: fire `before_tool_call` hook exactly once per tool invocation in embedded runs by removing duplicate dispatch paths while preserving parameter mutation semantics. (#15635) Thanks @lailoo. -- Agents/Transcript policy: sanitize OpenAI/Codex tool-call ids during transcript policy normalization to prevent invalid tool-call identifiers from propagating into session history. (#15279) Thanks @divisonofficer. -- Agents/Image tool: cap image-analysis completion `maxTokens` by model capability (`min(4096, model.maxTokens)`) to avoid over-limit provider failures while still preventing truncation. (#11770) Thanks @detecti1. -- Agents/Compaction: centralize exec default resolution in the shared tool factory so per-agent `tools.exec` overrides (host/security/ask/node and related defaults) persist across compaction retries. (#15833) Thanks @napetrov. -- Gateway/Agents: stop injecting a phantom `main` agent into gateway agent listings when `agents.list` explicitly excludes it. (#11450) Thanks @arosstale. -- Process/Exec: avoid shell execution for `.exe` commands on Windows so env overrides work reliably in `runCommandWithTimeout`. Thanks @thewilloftheshadow. -- Daemon/Windows: preserve literal backslashes in `gateway.cmd` command parsing so drive and UNC paths are not corrupted in runtime checks and doctor entrypoint comparisons. (#15642) Thanks @arosstale. -- Sandbox: pass configured `sandbox.docker.env` variables to sandbox containers at `docker create` time. (#15138) Thanks @stevebot-alive. -- Voice Call: route webhook runtime event handling through shared manager event logic so rejected inbound hangups are idempotent in production, with regression tests for duplicate reject events and provider-call-ID remapping parity. (#15892) Thanks @dcantu96. -- Cron: add regression coverage for announce-mode isolated jobs so runs that already report `delivered: true` do not enqueue duplicate main-session relays, including delivery configs where `mode` is omitted and defaults to announce. (#15737) Thanks @brandonwise. -- Cron: honor `deleteAfterRun` in isolated announce delivery by mapping it to subagent announce cleanup mode, so cron run sessions configured for deletion are removed after completion. (#15368) Thanks @arosstale. -- Web tools/web_fetch: prefer `text/markdown` responses for Cloudflare Markdown for Agents, add `cf-markdown` extraction for markdown bodies, and redact fetched URLs in `x-markdown-tokens` debug logs to avoid leaking raw paths/query params. (#15376) Thanks @Yaxuan42. -- Tools/web_search: support `freshness` for the Perplexity provider by mapping `pd`/`pw`/`pm`/`py` to Perplexity `search_recency_filter` values and including freshness in the Perplexity cache key. (#15343) Thanks @echoVic. -- Clawdock: avoid Zsh readonly variable collisions in helper scripts. (#15501) Thanks @nkelner. -- Memory: switch default local embedding model to the QAT `embeddinggemma-300m-qat-Q8_0` variant for better quality at the same footprint. (#15429) Thanks @azade-c. -- Docs/Discord: expand quick setup and clarify guild workspace guidance. (#20088) Thanks @pejmanjohn, @thewilloftheshadow. -- Docs/Mermaid: remove hardcoded Mermaid init theme blocks from four docs diagrams so dark mode inherits readable theme defaults. (#15157) Thanks @heytulsiprasad. -- Security/Pairing: generate 256-bit base64url device and node pairing tokens and use byte-safe constant-time verification to avoid token-compare edge-case failures. (#16535) Thanks @FaizanKolega, @gumadeiras. - -## 2026.2.12 - -### Changes - -- CLI/Plugins: add `openclaw plugins uninstall ` with `--dry-run`, `--force`, and `--keep-files` options, including safe uninstall path handling and plugin uninstall docs. (#5985) Thanks @JustasMonkev. -- CLI: add `openclaw logs --local-time` to display log timestamps in local timezone. (#13818) Thanks @xialonglee. -- Telegram: render blockquotes as native `
` tags instead of stripping them. (#14608) -- Telegram: expose `/compact` in the native command menu. (#10352) Thanks @akramcodez. -- Discord: add role-based allowlists and role-based agent routing. (#10650) Thanks @Minidoracat. -- Config: avoid redacting `maxTokens`-like fields during config snapshot redaction, preventing round-trip validation failures in `/config`. (#14006) Thanks @constansino. - -### Breaking - -- Hooks: `POST /hooks/agent` now rejects payload `sessionKey` overrides by default. To keep fixed hook context, set `hooks.defaultSessionKey` (recommended with `hooks.allowedSessionKeyPrefixes: ["hook:"]`). If you need legacy behavior, explicitly set `hooks.allowRequestSessionKey: true`. Thanks @alpernae for reporting. - -### Fixes - -- Gateway/OpenResponses: harden URL-based `input_file`/`input_image` handling with explicit SSRF deny policy, hostname allowlists (`files.urlAllowlist` / `images.urlAllowlist`), per-request URL input caps (`maxUrlParts`), blocked-fetch audit logging, and regression coverage/docs updates. -- Sessions: guard `withSessionStoreLock` against undefined `storePath` to prevent `path.dirname` crash. (#14717) -- Security: fix unauthenticated Nostr profile API remote config tampering. (#13719) Thanks @coygeek. -- Security: remove bundled soul-evil hook. (#14757) Thanks @Imccccc. -- Security/Audit: add hook session-routing hardening checks (`hooks.defaultSessionKey`, `hooks.allowRequestSessionKey`, and prefix allowlists), and warn when HTTP API endpoints allow explicit session-key routing. -- Security/Sandbox: confine mirrored skill sync destinations to the sandbox `skills/` root and stop using frontmatter-controlled skill names as filesystem destination paths. Thanks @1seal. -- Security/Web tools: treat browser/web content as untrusted by default (wrapped outputs for browser snapshot/tabs/console and structured external-content metadata for web tools), and strip `toolResult.details` from model-facing transcript/compaction inputs to reduce prompt-injection replay risk. -- Security/Hooks: harden webhook and device token verification with shared constant-time secret comparison, and add per-client auth-failure throttling for hook endpoints (`429` + `Retry-After`). Thanks @akhmittra. -- Security/Browser: require auth for loopback browser control HTTP routes, auto-generate `gateway.auth.token` when browser control starts without auth, and add a security-audit check for unauthenticated browser control. Thanks @tcusolle. -- Sessions/Gateway: harden transcript path resolution and reject unsafe session IDs/file paths so session operations stay within agent sessions directories. Thanks @akhmittra. -- Sessions: preserve `verboseLevel`, `thinkingLevel`/`reasoningLevel`, and `ttsAuto` overrides across `/new` and `/reset` session resets. (#10787) Thanks @mcaxtr. -- Gateway: raise WS payload/buffer limits so 5,000,000-byte image attachments work reliably. (#14486) Thanks @0xRaini. -- Logging/CLI: use local timezone timestamps for console prefixing, and include `±HH:MM` offsets when using `openclaw logs --local-time` to avoid ambiguity. (#14771) Thanks @0xRaini. -- Gateway: drain active turns before restart to prevent message loss. (#13931) Thanks @0xRaini. -- Gateway: auto-generate auth token during install to prevent launchd restart loops. (#13813) Thanks @cathrynlavery. -- Gateway: prevent `undefined`/missing token in auth config. (#13809) Thanks @asklee-klawd. -- Configure/Gateway: reject literal `"undefined"`/`"null"` token input and validate gateway password prompt values to avoid invalid password-mode configs. (#13767) Thanks @omair445. -- Gateway: handle async `EPIPE` on stdout/stderr during shutdown. (#13414) Thanks @keshav55. -- Gateway/Control UI: resolve missing dashboard assets when `openclaw` is installed globally via symlink-based Node managers (nvm/fnm/n/Homebrew). (#14919) Thanks @aynorica. -- Gateway/Control UI: keep partial assistant output visible when runs are aborted, and persist aborted partials to session transcripts for follow-up context. -- Cron: use requested `agentId` for isolated job auth resolution. (#13983) Thanks @0xRaini. -- Cron: prevent cron jobs from skipping execution when `nextRunAtMs` advances. (#14068) Thanks @WalterSumbon. -- Cron: pass `agentId` to `runHeartbeatOnce` for main-session jobs. (#14140) Thanks @ishikawa-pro. -- Cron: re-arm timers when `onTimer` fires while a job is still executing. (#14233) Thanks @tomron87. -- Cron: prevent duplicate fires when multiple jobs trigger simultaneously. (#14256) Thanks @xinhuagu. -- Cron: prevent duplicate announce-mode isolated cron deliveries, and keep main-session fallback active when best-effort structured delivery attempts fail to send any message. (#15739) Thanks @widingmarcus-cyber. -- Cron: isolate scheduler errors so one bad job does not break all jobs. (#14385) Thanks @MarvinDontPanic. -- Cron: prevent one-shot `at` jobs from re-firing on restart after skipped/errored runs. (#13878) Thanks @lailoo. -- Heartbeat: prevent scheduler stalls on unexpected run errors and avoid immediate rerun loops after `requests-in-flight` skips. (#14901) Thanks @joeykrug. -- Cron: honor stored session model overrides for isolated-agent runs while preserving `hooks.gmail.model` precedence for Gmail hook sessions. (#14983) Thanks @shtse8. -- Logging/Browser: fall back to `os.tmpdir()/openclaw` for default log, browser trace, and browser download temp paths when `/tmp/openclaw` is unavailable. -- WhatsApp: convert Markdown bold/strikethrough to WhatsApp formatting. (#14285) Thanks @Raikan10. -- WhatsApp: allow media-only sends and normalize leading blank payloads. (#14408) Thanks @karimnaguib. -- WhatsApp: default MIME type for voice messages when Baileys omits it. (#14444) Thanks @mcaxtr. -- Telegram: handle no-text message in model picker editMessageText. (#14397) Thanks @0xRaini. -- Telegram: surface REACTION_INVALID as non-fatal warning. (#14340) Thanks @0xRaini. -- BlueBubbles: fix webhook auth bypass via loopback proxy trust. (#13787) Thanks @coygeek. -- Slack: change default replyToMode from "off" to "all". (#14364) Thanks @nm-de. -- Slack: honor `limit` for `emoji-list` actions across core and extension adapters, with capped emoji-list responses in the Slack action handler. (#4293) Thanks @mcaxtr. -- Slack: detect control commands when channel messages start with bot mention prefixes (for example, `@Bot /new`). (#14142) Thanks @beefiker. -- Slack: include thread reply metadata in inbound message footer context (`thread_ts`, `parent_user_id`) while keeping top-level `thread_ts == ts` events unthreaded. (#14625) Thanks @bennewton999. -- Signal: enforce E.164 validation for the Signal bot account prompt so mistyped numbers are caught early. (#15063) Thanks @Duartemartins. -- Discord: process DM reactions instead of silently dropping them. (#10418) Thanks @mcaxtr. -- Discord: treat Administrator as full permissions in channel permission checks. Thanks @thewilloftheshadow. -- Discord: respect replyToMode in threads. (#11062) Thanks @cordx56. -- Discord: add optional gateway proxy support for WebSocket connections via `channels.discord.proxy`. (#10400) Thanks @winter-loo, @thewilloftheshadow. -- Browser: add Chrome launch flag `--disable-blink-features=AutomationControlled` to reduce `navigator.webdriver` automation detection issues on reCAPTCHA-protected sites. (#10735) Thanks @Milofax. -- Heartbeat: filter noise-only system events so scheduled reminder notifications do not fire when cron runs carry only heartbeat markers. (#13317) Thanks @pvtclawn. -- Signal: render mention placeholders as `@uuid`/`@phone` so mention gating and Clawdbot targeting work. (#2013) Thanks @alexgleason. -- Agents/Reminders: guard reminder promises by appending a note when no `cron.add` succeeded in the turn, so users know nothing was scheduled. (#18588) Thanks @vignesh07. -- Discord: omit empty content fields for media-only messages while preserving caption whitespace. (#9507) Thanks @leszekszpunar. -- Onboarding/Providers: add Z.AI endpoint-specific auth choices (`zai-coding-global`, `zai-coding-cn`, `zai-global`, `zai-cn`) and expand default Z.AI model wiring. (#13456) Thanks @tomsun28. -- Onboarding/Providers: update MiniMax API default/recommended models from M2.1 to M2.5, add M2.5/M2.5-Lightning model entries, and include `minimax-m2.5` in modern model filtering. (#14865) Thanks @adao-max. -- Ollama: use configured `models.providers.ollama.baseUrl` for model discovery and normalize `/v1` endpoints to the native Ollama API root. (#14131) Thanks @shtse8. -- Voice Call: pass Twilio stream auth token via `` instead of query string. (#14029) Thanks @mcwigglesmcgee. -- Config/Models: allow full `models.providers.*.models[*].compat` keys used by `openai-completions` (`thinkingFormat`, `supportsStrictMode`, and streaming/tool-result compatibility flags) so valid provider overrides no longer fail strict config validation. (#11063) Thanks @ikari-pl. -- Feishu: pass `Buffer` directly to the Feishu SDK upload APIs instead of `Readable.from(...)` to avoid form-data upload failures. (#10345) Thanks @youngerstyle. -- Feishu: trigger mention-gated group handling only when the bot itself is mentioned (not just any mention). (#11088) Thanks @openperf. -- Feishu: probe status uses the resolved account context for multi-account credential checks. (#11233) Thanks @onevcat. -- Feishu: add streaming card replies via Card Kit API and preserve `renderMode=auto` fallback behavior for plain-text responses. (#10379) Thanks @xzq-xu. -- Feishu DocX: preserve top-level converted block order using `firstLevelBlockIds` when writing/appending documents. (#13994) Thanks @Cynosure159. -- Feishu plugin packaging: remove `workspace:*` `openclaw` dependency from `extensions/feishu` and sync lockfile for install compatibility. (#14423) Thanks @jackcooper2015. -- CLI/Wizard: exit with code 1 when `configure`, `agents add`, or interactive `onboard` wizards are canceled, so `set -e` automation stops correctly. (#14156) Thanks @0xRaini. -- Media: strip `MEDIA:` lines with local paths instead of leaking as visible text. (#14399) Thanks @0xRaini. -- Config/Cron: exclude `maxTokens` from config redaction and honor `deleteAfterRun` on skipped cron jobs. (#13342) Thanks @niceysam. -- Config: ignore `meta` field changes in config file watcher. (#13460) Thanks @brandonwise. -- Daemon: suppress `EPIPE` error when restarting LaunchAgent. (#14343) Thanks @0xRaini. -- Antigravity: add opus 4.6 forward-compat model and bypass thinking signature sanitization. (#14218) Thanks @jg-noncelogic. -- Agents: prevent file descriptor leaks in child process cleanup. (#13565) Thanks @KyleChen26. -- Agents: prevent double compaction caused by cache TTL bypassing guard. (#13514) Thanks @taw0002. -- Agents: use last API call's cache tokens for context display instead of accumulated sum. (#13805) Thanks @akari-musubi. -- Agents: keep followup-runner session `totalTokens` aligned with post-compaction context by using last-call usage and shared token-accounting logic. (#14979) Thanks @shtse8. -- Hooks/Plugins: wire 9 previously unwired plugin lifecycle hooks into core runtime paths (session, compaction, gateway, and outbound message hooks). (#14882) Thanks @shtse8. -- Hooks/Tools: dispatch `before_tool_call` and `after_tool_call` hooks from both tool execution paths with rebased conflict fixes. (#15012) Thanks @Patrick-Barletta, @Takhoffman. -- Hooks: replace loader `console.*` output with subsystem logger messages so hook loading errors/warnings route through standard logging. (#11029) Thanks @shadril238. -- Discord: allow channel-edit to archive/lock threads and set auto-archive duration. (#5542) Thanks @stumct. -- Discord tests: use a partial @buape/carbon mock in slash command coverage. (#13262) Thanks @arosstale. -- Tests: update thread ID handling in Slack message collection tests. (#14108) Thanks @swizzmagik. -- Update/Daemon: fix post-update restart compatibility by generating `dist/cli/daemon-cli.js` with alias-aware exports from hashed daemon bundles, preventing `registerDaemonCli` import failures during `openclaw update`. - -## 2026.2.9 - -### Added - -- Commands: add `commands.allowFrom` config for separate command authorization, allowing operators to restrict slash commands to specific users while keeping chat open to others. (#12430) Thanks @thewilloftheshadow. -- Docker: add ClawDock shell helpers for Docker workflows. (#12817) Thanks @Olshansk. -- Gateway: periodic channel health monitor auto-restarts stuck, crashed, or silently-stopped channels. Configurable via `gateway.channelHealthCheckMinutes` (default: 5, set to 0 to disable). (#7053, #4302) -- iOS: alpha node app + setup-code onboarding. (#11756) Thanks @mbelinky. -- Channels: comprehensive BlueBubbles and channel cleanup. (#11093) Thanks @tyler6204. -- Channels: IRC first-class channel support. (#11482) Thanks @vignesh07. -- Plugins: device pairing + phone control plugins (Telegram `/pair`, iOS/Android node controls). (#11755) Thanks @mbelinky. -- Tools: add Grok (xAI) as a `web_search` provider. (#12419) Thanks @tmchow. -- Gateway: add agent management RPC methods for the web UI (`agents.create`, `agents.update`, `agents.delete`). (#11045) Thanks @advaitpaliwal. -- Gateway: stream thinking events to WS clients and broadcast tool events independent of verbose level. (#10568) Thanks @nk1tz. -- Web UI: show a Compaction divider in chat history. (#11341) Thanks @Takhoffman. -- Agents: include runtime shell in agent envelopes. (#1835) Thanks @Takhoffman. -- Agents: auto-select `zai/glm-4.6v` for image understanding when ZAI is primary provider. (#10267) Thanks @liuy. -- Paths: add `OPENCLAW_HOME` for overriding the home directory used by internal path resolution. (#12091) Thanks @sebslight. -- Onboarding: add Custom Provider flow for OpenAI and Anthropic-compatible endpoints. (#11106) Thanks @MackDing. -- Hooks: route webhook agent runs to specific `agentId`s, add `hooks.allowedAgentIds` controls, and fall back to default agent when unknown IDs are provided. (#13672) Thanks @BillChirico. - -### Fixes - -- Cron: prevent one-shot `at` jobs from re-firing on gateway restart when previously skipped or errored. (#13845) -- Discord: add exec approval cleanup option to delete DMs after approval/denial/timeout. (#13205) Thanks @thewilloftheshadow. -- Sessions: prune stale entries, cap session store size, rotate large stores, accept duration/size thresholds, default to warn-only maintenance, and prune cron run sessions after retention windows. (#13083) Thanks @skyfallsin, @Glucksberg, @gumadeiras. -- CI: Implement pipeline and workflow order. Thanks @quotentiroler. -- WhatsApp: preserve original filenames for inbound documents. (#12691) Thanks @akramcodez. -- Telegram: harden quote parsing; preserve quote context; avoid QUOTE_TEXT_INVALID; avoid nested reply quote misclassification. (#12156) Thanks @rybnikov. -- Security/Telegram: breaking default-behavior change — standalone canvas host + Telegram webhook listeners now bind loopback (`127.0.0.1`) instead of `0.0.0.0`; set `channels.telegram.webhookHost` when external ingress is required. (#13184) Thanks @davidrudduck. -- Telegram: recover proactive sends when stale topic thread IDs are used by retrying without `message_thread_id`. (#11620) -- Discord: auto-create forum/media thread posts on send, with chunked follow-up replies and media handling for forum sends. (#12380) Thanks @magendary, @thewilloftheshadow. -- Discord: cap gateway reconnect attempts to avoid infinite retry loops. (#12230) Thanks @Yida-Dev. -- Telegram: render markdown spoilers with `` HTML tags. (#11543) Thanks @ezhikkk. -- Telegram: truncate command registration to 100 entries to avoid `BOT_COMMANDS_TOO_MUCH` failures on startup. (#12356) Thanks @arosstale. -- Telegram: match DM `allowFrom` against sender user id (fallback to chat id) and clarify pairing logs. (#12779) Thanks @liuxiaopai-ai. -- Pairing/Telegram: include the actual pairing code in approve commands, route Telegram pairing replies through the shared pairing message builder, and add regression checks to prevent `` placeholder drift. -- Onboarding: QuickStart now auto-installs shell completion (prompt only in Manual). -- Onboarding/Providers: add LiteLLM provider onboarding and preserve custom LiteLLM proxy base URLs while enforcing API-key auth mode. (#12823) Thanks @ryan-crabbe. -- Docker: make `docker-setup.sh` compatible with macOS Bash 3.2 and empty extra mounts. (#9441) Thanks @mateusz-michalik. -- Auth: strip embedded line breaks from pasted API keys and tokens before storing/resolving credentials. -- Agents: strip reasoning tags and downgraded tool markers from messaging tool and streaming output to prevent leakage. (#11053, #13453) Thanks @liebertar, @meaadore1221-afk, @gumadeiras. -- Browser: prevent stuck `act:evaluate` from wedging the browser tool, and make cancellation stop waiting promptly. (#13498) Thanks @onutc. -- Security/Gateway: default-deny missing connect `scopes` (no implicit `operator.admin`). -- Web UI: make chat refresh smoothly scroll to the latest messages and suppress new-messages badge flash during manual refresh. -- Web UI: coerce Form Editor values to schema types before `config.set` and `config.apply`, preventing numeric and boolean fields from being serialized as strings. (#13468) Thanks @mcaxtr. -- Tools/web_search: include provider-specific settings in the web search cache key, and pass `inlineCitations` for Grok. (#12419) Thanks @tmchow. -- Tools/web_search: fix Grok response parsing for xAI Responses API output blocks. (#13049) Thanks @ereid7. -- Tools/web_search: normalize direct Perplexity model IDs while keeping OpenRouter model IDs unchanged. (#12795) Thanks @cdorsey. -- Model failover: treat HTTP 400 errors as failover-eligible, enabling automatic model fallback. (#1879) Thanks @orenyomtov. -- Errors: prevent false positive context overflow detection when conversation mentions "context overflow" topic. (#2078) Thanks @sbking. -- Errors: avoid rewriting/swallowing normal assistant replies that mention error keywords by scoping `sanitizeUserFacingText` rewrites to error-context. (#12988) Thanks @Takhoffman. -- Config: re-hydrate state-dir `.env` during runtime config loads so `${VAR}` substitutions remain resolvable. (#12748) Thanks @rodrigouroz. -- Gateway: no more post-compaction amnesia; injected transcript writes now preserve Pi session `parentId` chain so agents can remember again. (#12283) Thanks @Takhoffman. -- Gateway: fix multi-agent sessions.usage discovery. (#11523) Thanks @Takhoffman. -- Agents: recover from context overflow caused by oversized tool results (pre-emptive capping + fallback truncation). (#11579) Thanks @tyler6204. -- Subagents/compaction: stabilize announce timing and preserve compaction metrics across retries. (#11664) Thanks @tyler6204. -- Subagents: report timeout-aborted runs as timed out instead of completed successfully in parent-session announcements. (#13996) Thanks @dario-github. -- Cron: share isolated announce flow and harden scheduling/delivery reliability. (#11641) Thanks @tyler6204. -- Cron tool: recover flat params when LLM omits the `job` wrapper for add requests. (#12124) Thanks @tyler6204. -- Gateway/CLI: when `gateway.bind=lan`, use a LAN IP for probe URLs and Control UI links. (#11448) Thanks @AnonO6. -- CLI: make `openclaw plugins list` output scannable by hoisting source roots and shortening bundled/global/workspace plugin paths. -- Hooks: fix bundled hooks broken since 2026.2.2 (tsdown migration). (#9295) Thanks @patrickshao. -- Security/Plugins: install plugin and hook dependencies with `--ignore-scripts` to prevent lifecycle script execution. -- Routing: refresh bindings per message by loading config at route resolution so binding changes apply without restart. (#11372) Thanks @juanpablodlc. -- Exec approvals: render forwarded commands in monospace for safer approval scanning. (#11937) Thanks @sebslight. -- Config: clamp `maxTokens` to `contextWindow` to prevent invalid model configs. (#5516) Thanks @lailoo. -- Thinking: allow xhigh for `github-copilot/gpt-5.2-codex` and `github-copilot/gpt-5.2`. (#11646) Thanks @LatencyTDH. -- Thinking: honor `/think off` for reasoning-capable models. (#9564) Thanks @liuy. -- Discord: support forum/media thread-create starter messages, wire `message thread create --message`, and harden routing. (#10062) Thanks @jarvis89757. -- Discord: download attachments from forwarded messages. (#17049) Thanks @pip-nomel, @thewilloftheshadow. -- Paths: structurally resolve `OPENCLAW_HOME`-derived home paths and fix Windows drive-letter handling in tool meta shortening. (#12125) Thanks @mcaxtr. -- Memory: set Voyage embeddings `input_type` for improved retrieval. (#10818) Thanks @mcinteerj. -- Memory: disable async batch embeddings by default for memory indexing (opt-in via `agents.defaults.memorySearch.remote.batch.enabled`). (#13069) Thanks @mcinteerj. -- Memory/QMD: reuse default model cache across agents instead of re-downloading per agent. (#12114) Thanks @tyler6204. -- Memory/QMD: run boot refresh in background by default, add configurable QMD maintenance timeouts, retry QMD after fallback failures, and scope QMD queries to OpenClaw-managed collections. (#9690, #9705, #10042) Thanks @vignesh07. -- Memory/QMD: initialize QMD backend on gateway startup so background update timers restart after process reloads. (#10797) Thanks @vignesh07. -- Config/Memory: auto-migrate legacy top-level `memorySearch` settings into `agents.defaults.memorySearch`. (#11278, #9143) Thanks @vignesh07. -- Memory/QMD: treat plain-text `No results found` output from QMD as an empty result instead of throwing invalid JSON errors. (#9824) -- Memory/QMD: add `memory.qmd.searchMode` to choose `query`, `search`, or `vsearch` recall mode. (#9967, #10084) -- Media understanding: recognize `.caf` audio attachments for transcription. (#10982) Thanks @succ985. -- State dir: honor `OPENCLAW_STATE_DIR` for default device identity and canvas storage paths. (#4824) Thanks @kossoy. -- Doctor/State dir: suppress repeated legacy migration warnings only for valid symlink mirrors, while keeping warnings for empty or invalid legacy trees. (#11709) Thanks @gumadeiras. -- Tests: harden flaky hotspots by removing timer sleeps, consolidating onboarding provider-auth coverage, and improving memory test realism. (#11598) Thanks @gumadeiras. -- macOS: honor Nix-managed defaults suite (`ai.openclaw.mac`) for nixMode to prevent onboarding from reappearing after bundle-id churn. (#12205) Thanks @joshp123. -- Matrix: add multi-account support via `channels.matrix.accounts`; use per-account config for dm policy, allowFrom, groups, and other settings; serialize account startup to avoid race condition. (#7286, #3165, #3085) Thanks @emonty. - -## 2026.2.6 - -### Changes - -- Cron: default `wakeMode` is now `"now"` for new jobs (was `"next-heartbeat"`). (#10776) Thanks @tyler6204. -- Cron: `cron run` defaults to force execution; use `--due` to restrict to due-only. (#10776) Thanks @tyler6204. -- Models: support Anthropic Opus 4.6 and OpenAI Codex gpt-5.3-codex (forward-compat fallbacks). (#9853, #10720, #9995) Thanks @TinyTb, @calvin-hpnet, @tyler6204. -- Providers: add xAI (Grok) support. (#9885) Thanks @grp06. -- Providers: add Baidu Qianfan support. (#8868) Thanks @ide-rea. -- Web UI: add token usage dashboard. (#10072) Thanks @Takhoffman. -- Web UI: add RTL auto-direction support for Hebrew/Arabic text in chat composer and rendered messages. (#11498) Thanks @dirbalak. -- Memory: native Voyage AI support. (#7078) Thanks @mcinteerj. -- Sessions: cap sessions_history payloads to reduce context overflow. (#10000) Thanks @gut-puncture. -- CLI: sort commands alphabetically in help output. (#8068) Thanks @deepsoumya617. -- CI: optimize pipeline throughput (macOS consolidation, Windows perf, workflow concurrency). (#10784) Thanks @mcaxtr. -- Agents: bump pi-mono to 0.52.7; add embedded forward-compat fallback for Opus 4.6 model ids. - -### Added - -- Cron: run history deep-links to session chat from the dashboard. (#10776) Thanks @tyler6204. -- Cron: per-run session keys in run log entries and default labels for cron sessions. (#10776) Thanks @tyler6204. -- Cron: legacy payload field compatibility (`deliver`, `channel`, `to`, `bestEffortDeliver`) in schema. (#10776) Thanks @tyler6204. - -### Fixes - -- TTS: add missing OpenAI voices (ballad, cedar, juniper, marin, verse) to the allowlist so they are recognized instead of silently falling back to Edge TTS. (#2393) -- Cron: scheduler reliability (timer drift, restart catch-up, lock contention, stale running markers). (#10776) Thanks @tyler6204. -- Cron: store migration hardening (legacy field migration, parse error handling, explicit delivery mode persistence). (#10776) Thanks @tyler6204. -- Memory: set Voyage embeddings `input_type` for improved retrieval. (#10818) Thanks @mcinteerj. -- Memory/QMD: run boot refresh in background by default, add configurable QMD maintenance timeouts, retry QMD after fallback failures, and scope QMD queries to OpenClaw-managed collections. (#9690, #9705, #10042) Thanks @vignesh07. -- Media understanding: recognize `.caf` audio attachments for transcription. (#10982) Thanks @succ985. -- Telegram: auto-inject DM topic threadId in message tool + subagent announce. (#7235) Thanks @Lukavyi. -- Security: require auth for Gateway canvas host and A2UI assets. (#9518) Thanks @coygeek. -- Cron: fix scheduling and reminder delivery regressions; harden next-run recompute + timer re-arming + legacy schedule fields. (#9733, #9823, #9948, #9932) Thanks @tyler6204, @pycckuu, @j2h4u, @fujiwara-tofu-shop. -- Update: harden Control UI asset handling in update flow. (#10146) Thanks @gumadeiras. -- Security: add skill/plugin code safety scanner; redact credentials from config.get gateway responses. (#9806, #9858) Thanks @abdelsfane. -- Exec approvals: coerce bare string allowlist entries to objects. (#9903) Thanks @mcaxtr. -- Slack: add mention stripPatterns for /new and /reset. (#9971) Thanks @ironbyte-rgb. -- Chrome extension: fix bundled path resolution. (#8914) Thanks @kelvinCB. -- Compaction/errors: allow multiple compaction retries on context overflow; show clear billing errors. (#8928, #8391) Thanks @Glucksberg. - -## 2026.2.3 - -### Changes - -- Telegram: remove last `@ts-nocheck` from `bot-handlers.ts`, use Grammy types directly, deduplicate `StickerMetadata`. Zero `@ts-nocheck` remaining in `src/telegram/`. (#9206) -- Telegram: remove `@ts-nocheck` from `bot-message.ts`, type deps via `Omit`, widen `allMedia` to `TelegramMediaRef[]`. (#9180) -- Telegram: remove `@ts-nocheck` from `bot.ts`, fix duplicate `bot.catch` error handler (Grammy overrides), remove dead reaction `message_thread_id` routing, harden sticker cache guard. (#9077) -- Onboarding: add Cloudflare AI Gateway provider setup and docs. (#7914) Thanks @roerohan. -- Onboarding: add Moonshot (.cn) auth choice and keep the China base URL when preserving defaults. (#7180) Thanks @waynelwz. -- Docs: clarify tmux send-keys for TUI by splitting text and Enter. (#7737) Thanks @Wangnov. -- Docs: mirror the landing page revamp for zh-CN (features, quickstart, docs directory, network model, credits). (#8994) Thanks @joshp123. -- Messages: add per-channel and per-account responsePrefix overrides across channels. (#9001) Thanks @mudrii. -- Cron: add announce delivery mode for isolated jobs (CLI + Control UI) and delivery mode config. -- Cron: default isolated jobs to announce delivery; accept ISO 8601 `schedule.at` in tool inputs. -- Cron: hard-migrate isolated jobs to announce/none delivery; drop legacy post-to-main/payload delivery fields and `atMs` inputs. -- Cron: delete one-shot jobs after success by default; add `--keep-after-run` for CLI. -- Cron: suppress messaging tools during announce delivery so summaries post consistently. -- Cron: avoid duplicate deliveries when isolated runs send messages directly. - -### Fixes - -- Control UI: add hardened fallback for asset resolution in global npm installs. (#4855) Thanks @anapivirtua. -- Update: remove dead restore control-ui step that failed on gitignored dist/ output. -- Update: avoid wiping prebuilt Control UI assets during dev auto-builds (`tsdown --no-clean`), run update doctor via `openclaw.mjs`, and auto-restore missing UI assets after doctor. (#10146) Thanks @gumadeiras. -- Models: add forward-compat fallback for `openai-codex/gpt-5.3-codex` when model registry hasn't discovered it yet. (#9989) Thanks @w1kke. -- Auto-reply/Docs: normalize `extra-high` (and spaced variants) to `xhigh` for Codex thinking levels, and align Codex 5.3 FAQ examples. (#9976) Thanks @slonce70. -- Compaction: remove orphaned `tool_result` messages during history pruning to prevent session corruption from aborted tool calls. (#9868, fixes #9769, #9724, #9672) -- Telegram: pass `parentPeer` for forum topic binding inheritance so group-level bindings apply to all topics within the group. (#9789, fixes #9545, #9351) -- CLI: pass `--disable-warning=ExperimentalWarning` as a Node CLI option when respawning (avoid disallowed `NODE_OPTIONS` usage; fixes npm pack). (#9691) Thanks @18-RAJAT. -- CLI: resolve bundled Chrome extension assets by walking up to the nearest assets directory; add resolver and clipboard tests. (#8914) Thanks @kelvinCB. -- Tests: stabilize Windows ACL coverage with deterministic os.userInfo mocking. (#9335) Thanks @M00N7682. -- Exec approvals: coerce bare string allowlist entries to objects to prevent allowlist corruption. (#9903, fixes #9790) Thanks @mcaxtr. -- Exec approvals: ensure two-phase approval registration/decision flow works reliably by validating `twoPhase` requests and exposing `waitDecision` as an approvals-scoped gateway method. (#3357, fixes #2402) Thanks @ramin-shirali. -- Heartbeat: allow explicit accountId routing for multi-account channels. (#8702) Thanks @lsh411. -- TUI/Gateway: handle non-streaming finals, refresh history for non-local chat runs, and avoid event gap warnings for targeted tool streams. (#8432) Thanks @gumadeiras. -- Shell completion: auto-detect and migrate slow dynamic patterns to cached files for faster terminal startup; add completion health checks to doctor/update/onboard. -- Telegram: honor session model overrides in inline model selection. (#8193) Thanks @gildo. -- Web UI: fix agent model selection saves for default/non-default agents and wrap long workspace paths. Thanks @Takhoffman. -- Web UI: resolve header logo path when `gateway.controlUi.basePath` is set. (#7178) Thanks @Yeom-JinHo. -- Web UI: apply button styling to the new-messages indicator. -- Onboarding: infer auth choice from non-interactive API key flags. (#8484) Thanks @f-trycua. -- Security: keep untrusted channel metadata out of system prompts (Slack/Discord). Thanks @KonstantinMirin. -- Security: enforce sandboxed media paths for message tool attachments. (#9182) Thanks @victormier. -- Security: require explicit credentials for gateway URL overrides to prevent credential leakage. (#8113) Thanks @victormier. -- Security: gate `whatsapp_login` tool to owner senders and default-deny non-owner contexts. (#8768) Thanks @victormier. -- Voice call: harden webhook verification with host allowlists/proxy trust and keep ngrok loopback bypass. -- Voice call: add regression coverage for anonymous inbound caller IDs with allowlist policy. (#8104) Thanks @victormier. -- Cron: accept epoch timestamps and 0ms durations in CLI `--at` parsing. -- Cron: reload store data when the store file is recreated or mtime changes. -- Cron: deliver announce runs directly, honor delivery mode, and respect wakeMode for summaries. (#8540) Thanks @tyler6204. -- Telegram: include forward_from_chat metadata in forwarded messages and harden cron delivery target checks. (#8392) Thanks @Glucksberg. -- macOS: fix cron payload summary rendering and ISO 8601 formatter concurrency safety. -- Discord: enforce DM allowlists for agent components (buttons/select menus), honoring pairing store approvals and tag matches. (#11254) Thanks @thedudeabidesai. - -## 2026.2.2-3 - -### Fixes - -- Update: ship legacy daemon-cli shim for pre-tsdown update imports (fixes daemon restart after npm update). - -## 2026.2.2-2 - -### Changes - -- Docs: promote BlueBubbles as the recommended iMessage integration; mark imsg channel as legacy. (#8415) Thanks @tyler6204. - -### Fixes - -- CLI status: resolve build-info from bundled dist output (fixes "unknown" commit in npm builds). - -## 2026.2.2-1 - -### Fixes - -- CLI status: fall back to build-info for version detection (fixes "unknown" in beta builds). Thanks @gumadeira. - -## 2026.2.2 - -### Changes - -- Feishu: add Feishu/Lark plugin support + docs. (#7313) Thanks @jiulingyun (openclaw-cn). -- Web UI: add Agents dashboard for managing agent files, tools, skills, models, channels, and cron jobs. -- Subagents: discourage direct messaging tool use unless a specific external recipient is requested. -- Memory: implement the opt-in QMD backend for workspace memory. (#3160) Thanks @vignesh07. -- Security: add healthcheck skill and bootstrap audit guidance. (#7641) Thanks @Takhoffman. -- Config: allow setting a default subagent thinking level via `agents.defaults.subagents.thinking` (and per-agent `agents.list[].subagents.thinking`). (#7372) Thanks @tyler6204. -- Docs: zh-CN translations seed + polish, pipeline guidance, nav/landing updates, and typo fixes. (#8202, #6995, #6619, #7242, #7303, #7415) Thanks @AaronWander, @taiyi747, @Explorer1092, @rendaoyuan, @joshp123, @lailoo. -- Docs: add zh-CN i18n guardrails to avoid editing generated translations. (#8416) Thanks @joshp123. - -### Fixes - -- Docs: finish renaming the QMD memory docs to reference the OpenClaw state dir. -- Onboarding: keep TUI flow exclusive (skip completion prompt + background Web UI seed). -- Onboarding: drop completion prompt now handled by install/update. -- TUI: block onboarding output while TUI is active and restore terminal state on exit. -- CLI: cache shell completion scripts in state dir and source cached files in profiles. -- Zsh completion: escape option descriptions to avoid invalid option errors. -- Agents: repair malformed tool calls and session transcripts. (#7473) Thanks @justinhuangcode. -- fix(agents): validate AbortSignal instances before calling AbortSignal.any() (#7277) (thanks @Elarwei001) -- fix(webchat): respect user scroll position during streaming and refresh (#7226) (thanks @marcomarandiz) -- Telegram: recover from grammY long-poll timed out errors. (#7466) Thanks @macmimi23. -- Media understanding: skip binary media from file text extraction. (#7475) Thanks @AlexZhangji. -- Security: enforce access-group gating for Slack slash commands when channel type lookup fails. -- Security: require validated shared-secret auth before skipping device identity on gateway connect. Thanks @simecek. -- Security: guard skill installer downloads with SSRF checks (block private/localhost URLs). -- Security/Gateway: require `operator.approvals` for in-chat `/approve` when invoked from gateway clients. Thanks @yueyueL. -- Security: harden Windows exec allowlist; block cmd.exe bypass via single &. Thanks @simecek. -- Discord: route autoThread replies to existing threads instead of the root channel. (#8302) Thanks @gavinbmoore, @thewilloftheshadow. -- Media understanding: apply SSRF guardrails to provider fetches; allow private baseUrl overrides explicitly. -- fix(voice-call): harden inbound allowlist; reject anonymous callers; require Telnyx publicKey for allowlist; token-gate Twilio media streams; cap webhook body size (thanks @simecek) -- Onboarding: keep TUI flow exclusive (skip completion prompt + background Web UI seed); completion prompt now handled by install/update. -- CLI/Zsh completion: cache scripts in state dir and escape option descriptions to avoid invalid option errors. -- fix(ui): resolve Control UI asset path correctly. -- fix(ui): refresh agent files after external edits. -- Tests: stub SSRF DNS pinning in web auto-reply + Gemini video coverage. (#6619) Thanks @joshp123. - -## 2026.2.1 - -### Changes - -- Docs: onboarding/install/i18n/exec-approvals/Control UI/exe.dev/cacheRetention updates + misc nav/typos. (#3050, #3461, #4064, #4675, #4729, #4763, #5003, #5402, #5446, #5474, #5663, #5689, #5694, #5967, #6270, #6300, #6311, #6416, #6487, #6550, #6789) -- Telegram: use shared pairing store. (#6127) Thanks @obviyus. -- Agents: add OpenRouter app attribution headers. Thanks @alexanderatallah. -- Agents: add system prompt safety guardrails. (#5445) Thanks @joshp123. -- Agents: update pi-ai to 0.50.9 and rename cacheControlTtl -> cacheRetention (with back-compat mapping). -- Agents: extend CreateAgentSessionOptions with systemPrompt/skills/contextFiles. -- Agents: add tool policy conformance snapshot (no runtime behavior change). (#6011) -- Auth: update MiniMax OAuth hint + portal auth note copy. -- Discord: inherit thread parent bindings for routing. (#3892) Thanks @aerolalit. -- Gateway: inject timestamps into agent and chat.send messages. (#3705) Thanks @conroywhitney, @CashWilliams. -- Gateway: require TLS 1.3 minimum for TLS listeners. (#5970) Thanks @loganaden. -- Web UI: refine chat layout + extend session active duration. -- CI: add formal conformance + alias consistency checks. (#5723, #5807) - -### Fixes - -- Security: guard remote media fetches with SSRF protections (block private/localhost, DNS pinning). -- Updates: clean stale global install rename dirs and extend gateway update timeouts to avoid npm ENOTEMPTY failures. -- Security/Plugins/Hooks: validate install paths and reject traversal-like names (prevents path traversal outside the state dir). Thanks @logicx24. -- Telegram: add download timeouts for file fetches. (#6914) Thanks @hclsys. -- Telegram: enforce thread specs for DM vs forum sends. (#6833) Thanks @obviyus. -- Streaming: flush block streaming on paragraph boundaries for newline chunking. (#7014) -- Streaming: stabilize partial streaming filters. -- Auto-reply: avoid referencing workspace files in /new greeting prompt. (#5706) Thanks @bravostation. -- Tools: align tool execute adapters/signatures (legacy + parameter order + arg normalization). -- Tools: treat "\*" tool allowlist entries as valid to avoid spurious unknown-entry warnings. -- Skills: update session-logs paths from .clawdbot to .openclaw. (#4502) -- Slack: harden media fetch limits and Slack file URL validation. (#6639) Thanks @davidiach. -- Lint: satisfy curly rule after import sorting. (#6310) -- Process: resolve Windows `spawn()` failures for npm-family CLIs by appending `.cmd` when needed. (#5815) Thanks @thejhinvirtuoso. -- Discord: resolve PluralKit proxied senders for allowlists and labels. (#5838) Thanks @thewilloftheshadow. -- Tlon: add timeout to SSE client fetch calls (CWE-400). (#5926) -- Memory search: L2-normalize local embedding vectors to fix semantic search. (#5332) -- Agents: align embedded runner + typings with pi-coding-agent API updates (pi 0.51.0). -- Agents: ensure OpenRouter attribution headers apply in the embedded runner. -- Agents: cap context window resolution for compaction safeguard. (#6187) Thanks @iamEvanYT. -- System prompt: resolve overrides and hint using session_status for current date/time. (#1897, #1928, #2108, #3677) -- Agents: fix Pi prompt template argument syntax. (#6543) -- Subagents: fix announce failover race (always emit lifecycle end; timeout=0 means no-timeout). (#6621) -- Teams: gate media auth retries. -- Telegram: restore draft streaming partials. (#5543) Thanks @obviyus. -- Onboarding: friendlier Windows onboarding message. (#6242) Thanks @shanselman. -- TUI: prevent crash when searching with digits in the model selector. -- Agents: wire before_tool_call plugin hook into tool execution. (#6570, #6660) Thanks @ryancnelson. -- Browser: secure Chrome extension relay CDP sessions. -- Docker: use container port for gateway command instead of host port. (#5110) Thanks @mise42. -- Docker: start gateway CMD by default for container deployments. (#6635) Thanks @kaizen403. -- fix(lobster): block arbitrary exec via lobsterPath/cwd injection (GHSA-4mhr-g7xj-cg8j). (#5335) Thanks @vignesh07. -- Security: sanitize WhatsApp accountId to prevent path traversal. (#4610) -- Security: restrict MEDIA path extraction to prevent LFI. (#4930) -- Security: validate message-tool filePath/path against sandbox root. (#6398) -- Security: block LD*/DYLD* env overrides for host exec. (#4896) Thanks @HassanFleyah. -- Security: harden web tool content wrapping + file parsing safeguards. (#4058) Thanks @VACInc. -- Security: enforce Twitch `allowFrom` allowlist gating (deny non-allowlisted senders). Thanks @MegaManSec. - -## 2026.1.31 - -### Changes - -- Docs: onboarding/install/i18n/exec-approvals/Control UI/exe.dev/cacheRetention updates + misc nav/typos. (#3050, #3461, #4064, #4675, #4729, #4763, #5003, #5402, #5446, #5474, #5663, #5689, #5694, #5967, #6270, #6300, #6311, #6416, #6487, #6550, #6789) -- Telegram: use shared pairing store. (#6127) Thanks @obviyus. -- Agents: add OpenRouter app attribution headers. Thanks @alexanderatallah. -- Agents: add system prompt safety guardrails. (#5445) Thanks @joshp123. -- Agents: update pi-ai to 0.50.9 and rename cacheControlTtl -> cacheRetention (with back-compat mapping). -- Agents: extend CreateAgentSessionOptions with systemPrompt/skills/contextFiles. -- Agents: add tool policy conformance snapshot (no runtime behavior change). (#6011) -- Auth: update MiniMax OAuth hint + portal auth note copy. -- Discord: inherit thread parent bindings for routing. (#3892) Thanks @aerolalit. -- Gateway: inject timestamps into agent and chat.send messages. (#3705) Thanks @conroywhitney, @CashWilliams. -- Gateway: require TLS 1.3 minimum for TLS listeners. (#5970) Thanks @loganaden. -- Web UI: refine chat layout + extend session active duration. -- CI: add formal conformance + alias consistency checks. (#5723, #5807) - -### Fixes - -- Security: guard remote media fetches with SSRF protections (block private/localhost, DNS pinning). -- Updates: clean stale global install rename dirs and extend gateway update timeouts to avoid npm ENOTEMPTY failures. -- Plugins: validate plugin/hook install paths and reject traversal-like names. -- Telegram: add download timeouts for file fetches. (#6914) Thanks @hclsys. -- Telegram: enforce thread specs for DM vs forum sends. (#6833) Thanks @obviyus. -- Streaming: flush block streaming on paragraph boundaries for newline chunking. (#7014) -- Streaming: stabilize partial streaming filters. -- Auto-reply: avoid referencing workspace files in /new greeting prompt. (#5706) Thanks @bravostation. -- Tools: align tool execute adapters/signatures (legacy + parameter order + arg normalization). -- Tools: treat `"*"` tool allowlist entries as valid to avoid spurious unknown-entry warnings. -- Skills: update session-logs paths from .clawdbot to .openclaw. (#4502) -- Slack: harden media fetch limits and Slack file URL validation. (#6639) Thanks @davidiach. -- Lint: satisfy curly rule after import sorting. (#6310) -- Process: resolve Windows `spawn()` failures for npm-family CLIs by appending `.cmd` when needed. (#5815) Thanks @thejhinvirtuoso. -- Discord: resolve PluralKit proxied senders for allowlists and labels. (#5838) Thanks @thewilloftheshadow. -- Tlon: add timeout to SSE client fetch calls (CWE-400). (#5926) -- Memory search: L2-normalize local embedding vectors to fix semantic search. (#5332) -- Agents: align embedded runner + typings with pi-coding-agent API updates (pi 0.51.0). -- Agents: ensure OpenRouter attribution headers apply in the embedded runner. -- Agents: cap context window resolution for compaction safeguard. (#6187) Thanks @iamEvanYT. -- System prompt: resolve overrides and hint using session_status for current date/time. (#1897, #1928, #2108, #3677) -- Agents: fix Pi prompt template argument syntax. (#6543) -- Subagents: fix announce failover race (always emit lifecycle end; timeout=0 means no-timeout). (#6621) -- Teams: gate media auth retries. -- Telegram: restore draft streaming partials. (#5543) Thanks @obviyus. -- Onboarding: friendlier Windows onboarding message. (#6242) Thanks @shanselman. -- TUI: prevent crash when searching with digits in the model selector. -- Agents: wire before_tool_call plugin hook into tool execution. (#6570, #6660) Thanks @ryancnelson. -- Browser: secure Chrome extension relay CDP sessions. -- Docker: use container port for gateway command instead of host port. (#5110) Thanks @mise42. -- Docker: start gateway CMD by default for container deployments. (#6635) Thanks @kaizen403. -- fix(lobster): block arbitrary exec via lobsterPath/cwd injection (GHSA-4mhr-g7xj-cg8j). (#5335) Thanks @vignesh07. -- Security: sanitize WhatsApp accountId to prevent path traversal. (#4610) -- Security: restrict MEDIA path extraction to prevent LFI. (#4930) -- Security: validate message-tool filePath/path against sandbox root. (#6398) -- Security: block LD*/DYLD* env overrides for host exec. (#4896) Thanks @HassanFleyah. -- Security: harden web tool content wrapping + file parsing safeguards. (#4058) Thanks @VACInc. -- Security: enforce Twitch `allowFrom` allowlist gating (deny non-allowlisted senders). Thanks @MegaManSec. - -## 2026.1.30 - -### Changes - -- CLI: add `completion` command (Zsh/Bash/PowerShell/Fish) and auto-setup during postinstall/onboarding. -- CLI: add per-agent `models status` (`--agent` filter). (#4780) Thanks @jlowin. -- Agents: add Kimi K2.5 to the synthetic model catalog. (#4407) Thanks @manikv12. -- Auth: switch Kimi Coding to built-in provider; normalize OAuth profile email. -- Auth: add MiniMax OAuth plugin + onboarding option. (#4521) Thanks @Maosghoul. -- Agents: update pi SDK/API usage and dependencies. -- Web UI: refresh sessions after chat commands and improve session display names. -- Build: move TypeScript builds to `tsdown` + `tsgo` (faster builds, CI typechecks), update tsconfig target, and clean up lint rules. -- Build: align npm tar override and bin metadata so the `openclaw` CLI entrypoint is preserved in npm publishes. -- Docs: add pi/pi-dev docs and update OpenClaw branding + install links. -- Docker E2E: stabilize gateway readiness, plugin installs/manifests, and cleanup/doctor switch entrypoint checks. - -### Fixes - -- Security: restrict local path extraction in media parser to prevent LFI. (#4880) -- Gateway: prevent token defaults from becoming the literal "undefined". (#4873) Thanks @Hisleren. -- Control UI: fix assets resolution for npm global installs. (#4909) Thanks @YuriNachos. -- macOS: avoid stderr pipe backpressure in gateway discovery. (#3304) Thanks @abhijeet117. -- Telegram: normalize account token lookup for non-normalized IDs. (#5055) Thanks @jasonsschin. -- Telegram: preserve delivery thread fallback and fix threadId handling in delivery context. -- Telegram: fix HTML nesting for overlapping styles/links. (#4578) Thanks @ThanhNguyxn. -- Telegram: accept numeric messageId/chatId in react actions. (#4533) Thanks @Ayush10. -- Telegram: honor per-account proxy dispatcher via undici fetch. (#4456) Thanks @spiceoogway. -- Telegram: scope skill commands to bound agent per bot. (#4360) Thanks @robhparker. -- BlueBubbles: debounce by messageId to preserve attachments in text+image messages. (#4984) -- Routing: prefer requesterOrigin over stale session entries for sub-agent announce delivery. (#4957) -- Extensions: restore embedded extension discovery typings. -- CLI: fix `tui:dev` port resolution. -- LINE: fix status command TypeError. (#4651) -- OAuth: skip expired-token warnings when refresh tokens are still valid. (#4593) -- Build: skip redundant UI install step in Dockerfile. (#4584) Thanks @obviyus. - -## 2026.1.29 - -### Changes - -- Rebrand: rename the npm package/CLI to `openclaw`, add a `openclaw` compatibility shim, and move extensions to the `@openclaw/*` scope. -- Onboarding: strengthen security warning copy for beta + access control expectations. -- Onboarding: add Venice API key to non-interactive flow. (#1893) Thanks @jonisjongithub. -- Config: auto-migrate legacy state/config paths and keep config resolution consistent across legacy filenames. -- Gateway: warn on hook tokens via query params; document header auth preference. (#2200) Thanks @YuriNachos. -- Gateway: add dangerous Control UI device auth bypass flag + audit warnings. (#2248) -- Doctor: warn on gateway exposure without auth. (#2016) Thanks @Alex-Alaniz. -- Web UI: keep sub-agent announce replies visible in WebChat. (#1977) Thanks @andrescardonas7. -- Browser: route browser control via gateway/node; remove standalone browser control command and control URL config. -- Browser: route `browser.request` via node proxies when available; honor proxy timeouts; derive browser ports from `gateway.port`. -- Browser: fall back to URL matching for extension relay target resolution. (#1999) Thanks @jonit-dev. -- Telegram: allow caption param for media sends. (#1888) Thanks @mguellsegarra. -- Telegram: support plugin sendPayload channelData (media/buttons) and validate plugin commands. (#1917) Thanks @JoshuaLelon. -- Telegram: avoid block replies when streaming is disabled. (#1885) Thanks @ivancasco. -- Telegram: add optional silent send flag (disable notifications). (#2382) Thanks @Suksham-sharma. -- Telegram: support editing sent messages via message(action="edit"). (#2394) Thanks @marcelomar21. -- Telegram: support quote replies for message tool and inbound context. (#2900) Thanks @aduk059. -- Telegram: add sticker receive/send with vision caching. (#2629) Thanks @longjos. -- Telegram: send sticker pixels to vision models. (#2650) -- Telegram: keep topic IDs in restart sentinel notifications. (#1807) Thanks @hsrvc. -- Discord: add configurable privileged gateway intents for presences/members. (#2266) Thanks @kentaro. -- Slack: clear ack reaction after streamed replies. (#2044) Thanks @fancyboi999. -- Matrix: switch plugin SDK to @vector-im/matrix-bot-sdk. -- Tlon: format thread reply IDs as @ud. (#1837) Thanks @wca4a. -- Tools: add per-sender group tool policies and fix precedence. (#1757) Thanks @adam91holt. -- Agents: summarize dropped messages during compaction safeguard pruning. (#2509) Thanks @jogi47. -- Agents: expand cron tool description with full schema docs. (#1988) Thanks @tomascupr. -- Agents: honor tools.exec.safeBins in exec allowlist checks. (#2281) -- Memory Search: allow extra paths for memory indexing (ignores symlinks). (#3600) Thanks @kira-ariaki. -- Skills: add multi-image input support to Nano Banana Pro skill. (#1958) Thanks @tyler6204. -- Skills: add missing dependency metadata for GitHub, Notion, Slack, Discord. (#1995) Thanks @jackheuberger. -- Commands: group /help and /commands output with Telegram paging. (#2504) Thanks @hougangdev. -- Routing: add per-account DM session scope and document multi-account isolation. (#3095) Thanks @jarvis-sam. -- Routing: precompile session key regexes. (#1697) Thanks @Ray0907. -- CLI: use Node's module compile cache for faster startup. (#2808) Thanks @pi0. -- Auth: show copyable Google auth URL after ASCII prompt. (#1787) Thanks @robbyczgw-cla. -- TUI: avoid width overflow when rendering selection lists. (#1686) Thanks @mossein. -- macOS: finish OpenClaw app rename for macOS sources, bundle identifiers, and shared kit paths. (#2844) Thanks @fal3. -- Branding: update launchd labels, mobile bundle IDs, and logging subsystems to bot.molt (legacy bundle ID migrations). Thanks @thewilloftheshadow. -- macOS: limit project-local `node_modules/.bin` PATH preference to debug builds (reduce PATH hijacking risk). -- macOS: keep custom SSH usernames in remote target. (#2046) Thanks @algal. -- macOS: avoid crash when rendering code blocks by bumping Textual to 0.3.1. (#2033) Thanks @garricn. -- Update: ignore dist/control-ui for dirty checks and restore after ui builds. (#1976) Thanks @Glucksberg. -- Build: bundle A2UI assets during build and stop tracking generated bundles. (#2455) Thanks @0oAstro. -- CI: increase Node heap size for macOS checks. (#1890) Thanks @realZachi. -- Config: apply config.env before ${VAR} substitution. (#1813) Thanks @spanishflu-est1918. -- Gateway: prefer newest session metadata when combining stores. (#1823) Thanks @emanuelst. -- Docs: tighten Fly private deployment steps. (#2289) Thanks @dguido. -- Docs: add migration guide for moving to a new machine. (#2381) -- Docs: add Northflank one-click deployment guide. (#2167) Thanks @AdeboyeDN. -- Docs: add Vercel AI Gateway to providers sidebar. (#1901) Thanks @jerilynzheng. -- Docs: add Render deployment guide. (#1975) Thanks @anurag. -- Docs: add Claude Max API Proxy guide. (#1875) Thanks @atalovesyou. -- Docs: add DigitalOcean deployment guide. (#1870) Thanks @0xJonHoldsCrypto. -- Docs: add Oracle Cloud (OCI) platform guide + cross-links. (#2333) Thanks @hirefrank. -- Docs: add Raspberry Pi install guide. (#1871) Thanks @0xJonHoldsCrypto. -- Docs: add GCP Compute Engine deployment guide. (#1848) Thanks @hougangdev. -- Docs: add LINE channel guide. Thanks @thewilloftheshadow. -- Docs: credit both contributors for Control UI refresh. (#1852) Thanks @EnzeD. -- Docs: keep docs header sticky so navbar stays visible while scrolling. (#2445) Thanks @chenyuan99. -- Docs: update exe.dev install instructions. (#https://github.com/openclaw/openclaw/pull/3047) Thanks @zackerthescar. - -### Breaking - -- **BREAKING:** Gateway auth mode "none" is removed; gateway now requires token/password (Tailscale Serve identity still allowed). - -### Fixes - -- Skills: update session-logs paths to use ~/.openclaw. (#4502) Thanks @bonald. -- Telegram: avoid silent empty replies by tracking normalization skips before fallback. (#3796) -- Mentions: honor mentionPatterns even when explicit mentions are present. (#3303) Thanks @HirokiKobayashi-R. -- Discord: restore username directory lookup in target resolution. (#3131) Thanks @bonald. -- Agents: align MiniMax base URL test expectation with default provider config. (#3131) Thanks @bonald. -- Agents: prevent retries on oversized image errors and surface size limits. (#2871) Thanks @Suksham-sharma. -- Agents: inherit provider baseUrl/api for inline models. (#2740) Thanks @lploc94. -- Memory Search: keep auto provider model defaults and only include remote when configured. (#2576) Thanks @papago2355. -- Telegram: include AccountId in native command context for multi-agent routing. (#2942) Thanks @Chloe-VP. -- Telegram: handle video note attachments in media extraction. (#2905) Thanks @mylukin. -- TTS: read OPENAI_TTS_BASE_URL at runtime instead of module load to honor config.env. (#3341) Thanks @hclsys. -- macOS: auto-scroll to bottom when sending a new message while scrolled up. (#2471) Thanks @kennyklee. -- Web UI: auto-expand the chat compose textarea while typing (with sensible max height). (#2950) Thanks @shivamraut101. -- Gateway: prevent crashes on transient network errors (fetch failures, timeouts, DNS). Added fatal error detection to only exit on truly critical errors. Fixes #2895, #2879, #2873. (#2980) Thanks @elliotsecops. -- Agents: guard channel tool listActions to avoid plugin crashes. (#2859) Thanks @mbelinky. -- Discord: stop resolveDiscordTarget from passing directory params into messaging target parsers. Fixes #3167. Thanks @thewilloftheshadow. -- Discord: avoid resolving bare channel names to user DMs when a username matches. Thanks @thewilloftheshadow. -- Discord: fix directory config type import for target resolution. Thanks @thewilloftheshadow. -- Providers: update MiniMax API endpoint and compatibility mode. (#3064) Thanks @hlbbbbbbb. -- Telegram: treat more network errors as recoverable in polling. (#3013) Thanks @ryancontent. -- Discord: resolve usernames to user IDs for outbound messages. (#2649) Thanks @nonggialiang. -- Providers: update Moonshot Kimi model references to kimi-k2.5. (#2762) Thanks @MarvinCui. -- Gateway: suppress AbortError and transient network errors in unhandled rejections. (#2451) Thanks @Glucksberg. -- TTS: keep /tts status replies on text-only commands and avoid duplicate block-stream audio. (#2451) Thanks @Glucksberg. -- Security: pin npm overrides to keep tar@7.5.4 for install toolchains. -- Security: properly test Windows ACL audit for config includes. (#2403) Thanks @dominicnunez. -- CLI: recognize versioned Node executables when parsing argv. (#2490) Thanks @David-Marsh-Photo. -- CLI: avoid prompting for gateway runtime under the spinner. (#2874) -- BlueBubbles: coalesce inbound URL link preview messages. (#1981) Thanks @tyler6204. -- Cron: allow payloads containing "heartbeat" in event filter. (#2219) Thanks @dwfinkelstein. -- CLI: avoid loading config for global help/version while registering plugin commands. (#2212) Thanks @dial481. -- Agents: include memory.md when bootstrapping memory context. (#2318) Thanks @czekaj. -- Agents: release session locks on process termination and cover more signals. (#2483) Thanks @janeexai. -- Agents: skip cooldowned providers during model failover. (#2143) Thanks @YiWang24. -- Telegram: harden polling + retry behavior for transient network errors and Node 22 transport issues. (#2420) Thanks @techboss. -- Telegram: ignore non-forum group message_thread_id while preserving DM thread sessions. (#2731) Thanks @dylanneve1. -- Telegram: wrap reasoning italics per line to avoid raw underscores. (#2181) Thanks @YuriNachos. -- Telegram: centralize API error logging for delivery and bot calls. (#2492) Thanks @altryne. -- Voice Call: enforce Twilio webhook signature verification for ngrok URLs; disable ngrok free tier bypass by default. -- Security: harden Tailscale Serve auth by validating identity via local tailscaled before trusting headers. -- Media: fix text attachment MIME misclassification with CSV/TSV inference and UTF-16 detection; add XML attribute escaping for file output. (#3628) Thanks @frankekn. -- Build: align memory-core peer dependency with lockfile. -- Security: add mDNS discovery mode with minimal default to reduce information disclosure. (#1882) Thanks @orlyjamie. -- Security: harden URL fetches with DNS pinning to reduce rebinding risk. Thanks Chris Zheng. -- Web UI: improve WebChat image paste previews and allow image-only sends. (#1925) Thanks @smartprogrammer93. -- Security: wrap external hook content by default with a per-hook opt-out. (#1827) Thanks @mertcicekci0. -- Gateway: default auth now fail-closed (token/password required; Tailscale Serve identity remains allowed). -- Gateway: treat loopback + non-local Host connections as remote unless trusted proxy headers are present. -- Onboarding: remove unsupported gateway auth "off" choice from onboarding/configure flows and CLI flags. - -## 2026.1.24-3 - -### Fixes - -- Slack: fix image downloads failing due to missing Authorization header on cross-origin redirects. (#1936) Thanks @sanderhelgesen. -- Gateway: harden reverse proxy handling for local-client detection and unauthenticated proxied connects. (#1795) Thanks @orlyjamie. -- Security audit: flag loopback Control UI with auth disabled as critical. (#1795) Thanks @orlyjamie. -- CLI: resume claude-cli sessions and stream CLI replies to TUI clients. (#1921) Thanks @rmorse. - -## 2026.1.24-2 - -### Fixes - -- Packaging: include dist/link-understanding output in npm tarball (fixes missing apply.js import on install). - -## 2026.1.24-1 - -### Fixes - -- Packaging: include dist/shared output in npm tarball (fixes missing reasoning-tags import on install). - -## 2026.1.24 - -### Highlights - -- Providers: Ollama discovery + docs; Venice guide upgrades + cross-links. (#1606) Thanks @abhaymundhara. https://docs.openclaw.ai/providers/ollama https://docs.openclaw.ai/providers/venice -- Channels: LINE plugin (Messaging API) with rich replies + quick replies. (#1630) Thanks @plum-dawg. -- TTS: Edge fallback (keyless) + `/tts` auto modes. (#1668, #1667) Thanks @steipete, @sebslight. https://docs.openclaw.ai/tts -- Exec approvals: approve in-chat via `/approve` across all channels (including plugins). (#1621) Thanks @czekaj. https://docs.openclaw.ai/tools/exec-approvals https://docs.openclaw.ai/tools/slash-commands -- Telegram: DM topics as separate sessions + outbound link preview toggle. (#1597, #1700) Thanks @rohannagpal, @zerone0x. https://docs.openclaw.ai/channels/telegram - -### Changes - -- Channels: add LINE plugin (Messaging API) with rich replies, quick replies, and plugin HTTP registry. (#1630) Thanks @plum-dawg. -- TTS: add Edge TTS provider fallback, defaulting to keyless Edge with MP3 retry on format failures. (#1668) Thanks @steipete. https://docs.openclaw.ai/tts -- TTS: add auto mode enum (off/always/inbound/tagged) with per-session `/tts` override. (#1667) Thanks @sebslight. https://docs.openclaw.ai/tts -- Telegram: treat DM topics as separate sessions and keep DM history limits stable with thread suffixes. (#1597) Thanks @rohannagpal. -- Telegram: add `channels.telegram.linkPreview` to toggle outbound link previews. (#1700) Thanks @zerone0x. https://docs.openclaw.ai/channels/telegram -- Web search: add Brave freshness filter parameter for time-scoped results. (#1688) Thanks @JonUleis. https://docs.openclaw.ai/tools/web -- UI: refresh Control UI dashboard design system (colors, icons, typography). (#1745, #1786) Thanks @EnzeD, @mousberg. -- Exec approvals: forward approval prompts to chat with `/approve` for all channels (including plugins). (#1621) Thanks @czekaj. https://docs.openclaw.ai/tools/exec-approvals https://docs.openclaw.ai/tools/slash-commands -- Gateway: expose config.patch in the gateway tool with safe partial updates + restart sentinel. (#1653) Thanks @Glucksberg. -- Diagnostics: add diagnostic flags for targeted debug logs (config + env override). https://docs.openclaw.ai/diagnostics/flags -- Docs: expand FAQ (migration, scheduling, concurrency, model recommendations, OpenAI subscription auth, Pi sizing, hackable install, docs SSL workaround). -- Docs: add verbose installer troubleshooting guidance. -- Docs: add macOS VM guide with local/hosted options + VPS/nodes guidance. (#1693) Thanks @f-trycua. -- Docs: add Bedrock EC2 instance role setup + IAM steps. (#1625) Thanks @sergical. https://docs.openclaw.ai/bedrock -- Docs: update Fly.io guide notes. -- Dev: add prek pre-commit hooks + dependabot config for weekly updates. (#1720) Thanks @dguido. - -### Fixes - -- Web UI: fix config/debug layout overflow, scrolling, and code block sizing. (#1715) Thanks @saipreetham589. -- Web UI: show Stop button during active runs, swap back to New session when idle. (#1664) Thanks @ndbroadbent. -- Web UI: clear stale disconnect banners on reconnect; allow form saves with unsupported schema paths but block missing schema. (#1707) Thanks @Glucksberg. -- Web UI: hide internal `message_id` hints in chat bubbles. -- Gateway: allow Control UI token-only auth to skip device pairing even when device identity is present (`gateway.controlUi.allowInsecureAuth`). (#1679) Thanks @steipete. -- Matrix: decrypt E2EE media attachments with preflight size guard. (#1744) Thanks @araa47. -- BlueBubbles: route phone-number targets to DMs, avoid leaking routing IDs, and auto-create missing DMs (Private API required). (#1751) Thanks @tyler6204. https://docs.openclaw.ai/channels/bluebubbles -- BlueBubbles: keep part-index GUIDs in reply tags when short IDs are missing. -- iMessage: normalize chat_id/chat_guid/chat_identifier prefixes case-insensitively and keep service-prefixed handles stable. (#1708) Thanks @aaronn. -- Signal: repair reaction sends (group/UUID targets + CLI author flags). (#1651) Thanks @vilkasdev. -- Signal: add configurable signal-cli startup timeout + external daemon mode docs. (#1677) https://docs.openclaw.ai/channels/signal -- Telegram: set fetch duplex="half" for uploads on Node 22 to avoid sendPhoto failures. (#1684) Thanks @commdata2338. -- Telegram: use wrapped fetch for long-polling on Node to normalize AbortSignal handling. (#1639) -- Telegram: honor per-account proxy for outbound API calls. (#1774) Thanks @radek-paclt. -- Telegram: fall back to text when voice notes are blocked by privacy settings. (#1725) Thanks @foeken. -- Voice Call: return stream TwiML for outbound conversation calls on initial Twilio webhook. (#1634) -- Voice Call: serialize Twilio TTS playback and cancel on barge-in to prevent overlap. (#1713) Thanks @dguido. -- Google Chat: tighten email allowlist matching, typing cleanup, media caps, and onboarding/docs/tests. (#1635) Thanks @iHildy. -- Google Chat: normalize space targets without double `spaces/` prefix. -- Agents: auto-compact on context overflow prompt errors before failing. (#1627) Thanks @rodrigouroz. -- Agents: use the active auth profile for auto-compaction recovery. -- Media understanding: skip image understanding when the primary model already supports vision. (#1747) Thanks @tyler6204. -- Models: default missing custom provider fields so minimal configs are accepted. -- Messaging: keep newline chunking safe for fenced markdown blocks across channels. -- Messaging: treat newline chunking as paragraph-aware (blank-line splits) to keep lists and headings together. (#1726) Thanks @tyler6204. -- TUI: reload history after gateway reconnect to restore session state. (#1663) -- Heartbeat: normalize target identifiers for consistent routing. -- Exec: keep approvals for elevated ask unless full mode. (#1616) Thanks @ivancasco. -- Exec: treat Windows platform labels as Windows for node shell selection. (#1760) Thanks @ymat19. -- Gateway: include inline config env vars in service install environments. (#1735) Thanks @Seredeep. -- Gateway: skip Tailscale DNS probing when tailscale.mode is off. (#1671) -- Gateway: reduce log noise for late invokes + remote node probes; debounce skills refresh. (#1607) Thanks @petter-b. -- Gateway: clarify Control UI/WebChat auth error hints for missing tokens. (#1690) -- Gateway: listen on IPv6 loopback when bound to 127.0.0.1 so localhost webhooks work. -- Gateway: store lock files in the temp directory to avoid stale locks on persistent volumes. (#1676) -- macOS: default direct-transport `ws://` URLs to port 18789; document `gateway.remote.transport`. (#1603) Thanks @ngutman. -- Tests: cap Vitest workers on CI macOS to reduce timeouts. (#1597) Thanks @rohannagpal. -- Tests: avoid fake-timer dependency in embedded runner stream mock to reduce CI flakes. (#1597) Thanks @rohannagpal. -- Tests: increase embedded runner ordering test timeout to reduce CI flakes. (#1597) Thanks @rohannagpal. - -## 2026.1.23-1 - -### Fixes - -- Packaging: include dist/tts output in npm tarball (fixes missing dist/tts/tts.js). - -## 2026.1.23 - -### Highlights - -- TTS: move Telegram TTS into core + enable model-driven TTS tags by default for expressive audio replies. (#1559) Thanks @Glucksberg. https://docs.openclaw.ai/tts -- Gateway: add `/tools/invoke` HTTP endpoint for direct tool calls (auth + tool policy enforced). (#1575) Thanks @vignesh07. https://docs.openclaw.ai/gateway/tools-invoke-http-api -- Heartbeat: per-channel visibility controls (OK/alerts/indicator). (#1452) Thanks @dlauer. https://docs.openclaw.ai/gateway/heartbeat -- Deploy: add Fly.io deployment support + guide. (#1570) https://docs.openclaw.ai/platforms/fly -- Channels: add Tlon/Urbit channel plugin (DMs, group mentions, thread replies). (#1544) Thanks @wca4a. https://docs.openclaw.ai/channels/tlon - -### Changes - -- Channels: allow per-group tool allow/deny policies across built-in + plugin channels. (#1546) Thanks @adam91holt. https://docs.openclaw.ai/multi-agent-sandbox-tools -- Agents: add Bedrock auto-discovery defaults + config overrides. (#1553) Thanks @fal3. https://docs.openclaw.ai/bedrock -- CLI: add `openclaw system` for system events + heartbeat controls; remove standalone `wake`. (commit 71203829d) https://docs.openclaw.ai/cli/system -- CLI: add live auth probes to `openclaw models status` for per-profile verification. (commit 40181afde) https://docs.openclaw.ai/cli/models -- CLI: restart the gateway by default after `openclaw update`; add `--no-restart` to skip it. (commit 2c85b1b40) -- Browser: add node-host proxy auto-routing for remote gateways (configurable per gateway/node). (commit c3cb26f7c) -- Plugins: add optional `llm-task` JSON-only tool for workflows. (#1498) Thanks @vignesh07. https://docs.openclaw.ai/tools/llm-task -- Markdown: add per-channel table conversion (bullets for Signal/WhatsApp, code blocks elsewhere). (#1495) Thanks @odysseus0. -- Agents: keep system prompt time zone-only and move current time to `session_status` for better cache hits. (commit 66eec295b) -- Agents: remove redundant bash tool alias from tool registration/display. (#1571) Thanks @Takhoffman. -- Docs: add cron vs heartbeat decision guide (with Lobster workflow notes). (#1533) Thanks @JustYannicc. https://docs.openclaw.ai/automation/cron-vs-heartbeat -- Docs: clarify HEARTBEAT.md empty file skips heartbeats, missing file still runs. (#1535) Thanks @JustYannicc. https://docs.openclaw.ai/gateway/heartbeat - -### Fixes - -- Sessions: accept non-UUID sessionIds for history/send/status while preserving agent scoping. (#1518) -- Heartbeat: accept plugin channel ids for heartbeat target validation + UI hints. -- Messaging/Sessions: mirror outbound sends into target session keys (threads + dmScope), create session entries on send, and normalize session key casing. (#1520, commit 4b6cdd1d3) -- Sessions: reject array-backed session stores to prevent silent wipes. (#1469) -- Gateway: compare Linux process start time to avoid PID recycling lock loops; keep locks unless stale. (#1572) Thanks @steipete. -- Gateway: accept null optional fields in exec approval requests. (#1511) Thanks @pvoo. -- Exec approvals: persist allowlist entry ids to keep macOS allowlist rows stable. (#1521) Thanks @ngutman. -- Exec: honor tools.exec ask/security defaults for elevated approvals (avoid unwanted prompts). (commit 5662a9cdf) -- Daemon: use platform PATH delimiters when building minimal service paths. (commit a4e57d3ac) -- Linux: include env-configured user bin roots in systemd PATH and align PATH audits. (#1512) Thanks @robbyczgw-cla. -- Tailscale: retry serve/funnel with sudo only for permission errors and keep original failure details. (#1551) Thanks @sweepies. -- Docker: update gateway command in docker-compose and Hetzner guide. (#1514) -- Agents: show tool error fallback when the last assistant turn only invoked tools (prevents silent stops). (commit 8ea8801d0) -- Agents: ignore IDENTITY.md template placeholders when parsing identity. (#1556) -- Agents: drop orphaned OpenAI Responses reasoning blocks on model switches. (#1562) Thanks @roshanasingh4. -- Agents: add CLI log hint to "agent failed before reply" messages. (#1550) Thanks @sweepies. -- Agents: warn and ignore tool allowlists that only reference unknown or unloaded plugin tools. (#1566) -- Agents: treat plugin-only tool allowlists as opt-ins; keep core tools enabled. (#1467) -- Agents: honor enqueue overrides for embedded runs to avoid queue deadlocks in tests. (commit 084002998) -- Slack: honor open groupPolicy for unlisted channels in message + slash gating. (#1563) Thanks @itsjaydesu. -- Discord: limit autoThread mention bypass to bot-owned threads; keep ack reactions mention-gated. (#1511) Thanks @pvoo. -- Discord: retry rate-limited allowlist resolution + command deploy to avoid gateway crashes. (commit f70ac0c7c) -- Mentions: ignore mentionPattern matches when another explicit mention is present in group chats (Slack/Discord/Telegram/WhatsApp). (commit d905ca0e0) -- Telegram: render markdown in media captions. (#1478) -- MS Teams: remove `.default` suffix from Graph scopes and Bot Framework probe scopes. (#1507, #1574) Thanks @Evizero. -- Browser: keep extension relay tabs controllable when the extension reuses a session id after switching tabs. (#1160) -- Voice wake: auto-save wake words on blur/submit across iOS/Android and align limits with macOS. (commit 69f645c66) -- UI: keep the Control UI sidebar visible while scrolling long pages. (#1515) Thanks @pookNast. -- UI: cache Control UI markdown rendering + memoize chat text extraction to reduce Safari typing jank. (commit d57cb2e1a) -- TUI: forward unknown slash commands, include Gateway commands in autocomplete, and render slash replies as system output. (commit 1af227b61, commit 8195497ce, commit 6fba598ea) -- CLI: auth probe output polish (table output, inline errors, reduced noise, and wrap fixes in `openclaw models status`). (commit da3f2b489, commit 00ae21bed, commit 31e59cd58, commit f7dc27f2d, commit 438e782f8, commit 886752217, commit aabe0bed3, commit 81535d512, commit c63144ab1) -- Media: only parse `MEDIA:` tags when they start the line to avoid stripping prose mentions. (#1206) -- Media: preserve PNG alpha when possible; fall back to JPEG when still over size cap. (#1491) Thanks @robbyczgw-cla. -- Skills: gate bird Homebrew install to macOS. (#1569) Thanks @bradleypriest. - -## 2026.1.22 - -### Changes - -- Highlight: Compaction safeguard now uses adaptive chunking, progressive fallback, and UI status + retries. (#1466) Thanks @dlauer. -- Providers: add Antigravity usage tracking to status output. (#1490) Thanks @patelhiren. -- Slack: add chat-type reply threading overrides via `replyToModeByChatType`. (#1442) Thanks @stefangalescu. -- BlueBubbles: add `asVoice` support for MP3/CAF voice memos in sendAttachment. (#1477, #1482) Thanks @Nicell. -- Onboarding: add hatch choice (TUI/Web/Later), token explainer, background dashboard seed on macOS, and showcase link. - -### Fixes - -- BlueBubbles: stop typing indicator on idle/no-reply. (#1439) Thanks @Nicell. -- Message tool: keep path/filePath as-is for send; hydrate buffers only for sendAttachment. (#1444) Thanks @hopyky. -- Auto-reply: only report a model switch when session state is available. (#1465) Thanks @robbyczgw-cla. -- Control UI: resolve local avatar URLs with basePath across injection + identity RPC. (#1457) Thanks @dlauer. -- Agents: sanitize assistant history text to strip tool-call markers. (#1456) Thanks @zerone0x. -- Discord: clarify Message Content Intent onboarding hint. (#1487) Thanks @kyleok. -- Gateway: stop the service before uninstalling and fail if it remains loaded. -- Agents: surface concrete API error details instead of generic AI service errors. -- Exec: fall back to non-PTY when PTY spawn fails (EBADF). (#1484) -- Exec approvals: allow per-segment allowlists for chained shell commands on gateway + node hosts. (#1458) Thanks @czekaj. -- Agents: make OpenAI sessions image-sanitize-only; gate tool-id/repair sanitization by provider. -- Doctor: honor CLAWDBOT_GATEWAY_TOKEN for auth checks and security audit token reuse. (#1448) Thanks @azade-c. -- Agents: make tool summaries more readable and only show optional params when set. -- Agents: honor SOUL.md guidance even when the file is nested or path-qualified. (#1434) Thanks @neooriginal. -- Matrix (plugin): persist m.direct for resolved DMs and harden room fallback. (#1436, #1486) Thanks @sibbl. -- CLI: prefer `~` for home paths in output. -- Mattermost (plugin): enforce pairing/allowlist gating, keep @username targets, and clarify plugin-only docs. (#1428) Thanks @damoahdominic. -- Agents: centralize transcript sanitization in the runner; keep tags and error turns intact. -- Auth: skip auth profiles in cooldown during initial selection and rotation. (#1316) Thanks @odrobnik. -- Agents/TUI: honor user-pinned auth profiles during cooldown and preserve search picker ranking. (#1432) Thanks @tobiasbischoff. -- Docs: fix gog auth services example to include docs scope. (#1454) Thanks @zerone0x. -- Slack: reduce WebClient retries to avoid duplicate sends. (#1481) -- Slack: read thread replies for message reads when threadId is provided (replies-only). (#1450) Thanks @rodrigouroz. -- Discord: honor accountId across message actions and cron deliveries. (#1492) Thanks @svkozak. -- macOS: prefer linked channels in gateway summary to avoid false “not linked” status. -- macOS/tests: fix gateway summary lookup after guard unwrap; prevent browser opens during tests. (ECID-1483) - -## 2026.1.21-2 - -### Fixes - -- Control UI: ignore bootstrap identity placeholder text for avatar values and fall back to the default avatar. https://docs.openclaw.ai/cli/agents https://docs.openclaw.ai/web/control-ui -- Slack: remove deprecated `filetype` field from `files.uploadV2` to eliminate API warnings. (#1447) - -## 2026.1.21 - -### Changes - -- Highlight: Lobster optional plugin tool for typed workflows + approval gates. https://docs.openclaw.ai/tools/lobster -- Lobster: allow workflow file args via `argsJson` in the plugin tool. https://docs.openclaw.ai/tools/lobster -- Heartbeat: allow running heartbeats in an explicit session key. (#1256) Thanks @zknicker. -- CLI: default exec approvals to the local host, add gateway/node targeting flags, and show target details in allowlist output. -- CLI: exec approvals mutations render tables instead of raw JSON. -- Exec approvals: support wildcard agent allowlists (`*`) across all agents. -- Exec approvals: allowlist matches resolved binary paths only, add safe stdin-only bins, and tighten allowlist shell parsing. -- Nodes: expose node PATH in status/describe and bootstrap PATH for node-host execution. -- CLI: flatten node service commands under `openclaw node` and remove `service node` docs. -- CLI: move gateway service commands under `openclaw gateway` and add `gateway probe` for reachability. -- Sessions: add per-channel reset overrides via `session.resetByChannel`. (#1353) Thanks @cash-echo-bot. -- Agents: add identity avatar config support and Control UI avatar rendering. (#1329, #1424) Thanks @dlauer. -- UI: show per-session assistant identity in the Control UI. (#1420) Thanks @robbyczgw-cla. -- CLI: add `openclaw update wizard` for interactive channel selection and restart prompts. https://docs.openclaw.ai/cli/update -- Signal: add typing indicators and DM read receipts via signal-cli. -- MSTeams: add file uploads, adaptive cards, and attachment handling improvements. (#1410) Thanks @Evizero. -- Onboarding: remove the run setup-token auth option (paste setup-token or reuse CLI creds instead). -- Docs: add troubleshooting entry for gateway.mode blocking gateway start. https://docs.openclaw.ai/gateway/troubleshooting -- Docs: add /model allowlist troubleshooting note. (#1405) -- Docs: add per-message Gmail search example for gog. (#1220) Thanks @mbelinky. - -### Breaking - -- **BREAKING:** Control UI now rejects insecure HTTP without device identity by default. Use HTTPS (Tailscale Serve) or set `gateway.controlUi.allowInsecureAuth: true` to allow token-only auth. https://docs.openclaw.ai/web/control-ui#insecure-http -- **BREAKING:** Envelope and system event timestamps now default to host-local time (was UTC) so agents don’t have to constantly convert. - -### Fixes - -- Nodes/macOS: prompt on allowlist miss for node exec approvals, persist allowlist decisions, and flatten node invoke errors. (#1394) Thanks @ngutman. -- Gateway: keep auto bind loopback-first and add explicit tailnet binding to avoid Tailscale taking over local UI. (#1380) -- Memory: prevent CLI hangs by deferring vector probes, adding sqlite-vec/embedding timeouts, and showing sync progress early. -- Agents: enforce 9-char alphanumeric tool call ids for Mistral providers. (#1372) Thanks @zerone0x. -- Embedded runner: persist injected history images so attachments aren’t reloaded each turn. (#1374) Thanks @Nicell. -- Nodes tool: include agent/node/gateway context in tool failure logs to speed approval debugging. -- macOS: exec approvals now respect wildcard agent allowlists (`*`). -- macOS: allow SSH agent auth when no identity file is set. (#1384) Thanks @ameno-. -- Gateway: prevent multiple gateways from sharing the same config/state at once (singleton lock). -- UI: remove the chat stop button and keep the composer aligned to the bottom edge. -- Typing: start instant typing indicators at run start so DMs and mentions show immediately. -- Configure: restrict the model allowlist picker to OAuth-compatible Anthropic models and preselect Opus 4.5. -- Configure: seed model fallbacks from the allowlist selection when multiple models are chosen. -- Model picker: list the full catalog when no model allowlist is configured. -- Discord: honor wildcard channel configs via shared match helpers. (#1334) Thanks @pvoo. -- BlueBubbles: resolve short message IDs safely and expose full IDs in templates. (#1387) Thanks @tyler6204. -- Infra: preserve fetch helper methods when wrapping abort signals. (#1387) -- macOS: default distribution packaging to universal binaries. (#1396) Thanks @JustYannicc. - -## 2026.1.20 - -### Changes - -- Control UI: add copy-as-markdown with error feedback. (#1345) https://docs.openclaw.ai/web/control-ui -- Control UI: drop the legacy list view. (#1345) https://docs.openclaw.ai/web/control-ui -- TUI: add syntax highlighting for code blocks. (#1200) https://docs.openclaw.ai/tui -- TUI: session picker shows derived titles, fuzzy search, relative times, and last message preview. (#1271) https://docs.openclaw.ai/tui -- TUI: add a searchable model picker for quicker model selection. (#1198) https://docs.openclaw.ai/tui -- TUI: add input history (up/down) for submitted messages. (#1348) https://docs.openclaw.ai/tui -- ACP: add `openclaw acp` for IDE integrations. https://docs.openclaw.ai/cli/acp -- ACP: add `openclaw acp client` interactive harness for debugging. https://docs.openclaw.ai/cli/acp -- Skills: add download installs with OS-filtered options. https://docs.openclaw.ai/tools/skills -- Skills: add the local sherpa-onnx-tts skill. https://docs.openclaw.ai/tools/skills -- Memory: add hybrid BM25 + vector search (FTS5) with weighted merging and fallback. https://docs.openclaw.ai/concepts/memory -- Memory: add SQLite embedding cache to speed up reindexing and frequent updates. https://docs.openclaw.ai/concepts/memory -- Memory: add OpenAI batch indexing for embeddings when configured. https://docs.openclaw.ai/concepts/memory -- Memory: enable OpenAI batch indexing by default for OpenAI embeddings. https://docs.openclaw.ai/concepts/memory -- Memory: allow parallel OpenAI batch indexing jobs (default concurrency: 2). https://docs.openclaw.ai/concepts/memory -- Memory: render progress immediately, color batch statuses in verbose logs, and poll OpenAI batch status every 2s by default. https://docs.openclaw.ai/concepts/memory -- Memory: add `--verbose` logging for memory status + batch indexing details. https://docs.openclaw.ai/concepts/memory -- Memory: add native Gemini embeddings provider for memory search. (#1151) https://docs.openclaw.ai/concepts/memory -- Browser: allow config defaults for efficient snapshots in the tool/CLI. (#1336) https://docs.openclaw.ai/tools/browser -- Nostr: add the Nostr channel plugin with profile management + onboarding defaults. (#1323) https://docs.openclaw.ai/channels/nostr -- Matrix: migrate to matrix-bot-sdk with E2EE support, location handling, and group allowlist upgrades. (#1298) https://docs.openclaw.ai/channels/matrix -- Slack: add HTTP webhook mode via Bolt HTTP receiver. (#1143) https://docs.openclaw.ai/channels/slack -- Telegram: enrich forwarded-message context with normalized origin details + legacy fallback. (#1090) https://docs.openclaw.ai/channels/telegram -- Discord: fall back to `/skill` when native command limits are exceeded. (#1287) -- Discord: expose `/skill` globally. (#1287) -- Zalouser: add channel dock metadata, config schema, setup wiring, probe, and status issues. (#1219) https://docs.openclaw.ai/plugins/zalouser -- Plugins: require manifest-embedded config schemas with preflight validation warnings. (#1272) https://docs.openclaw.ai/plugins/manifest -- Plugins: move channel catalog metadata into plugin manifests. (#1290) https://docs.openclaw.ai/plugins/manifest -- Plugins: align Nextcloud Talk policy helpers with core patterns. (#1290) https://docs.openclaw.ai/plugins/manifest -- Plugins/UI: let channel plugin metadata drive UI labels/icons and cron channel options. (#1306) https://docs.openclaw.ai/web/control-ui -- Agents/UI: add agent avatar support in identity config, IDENTITY.md, and the Control UI. (#1329) https://docs.openclaw.ai/gateway/configuration -- Plugins: add plugin slots with a dedicated memory slot selector. https://docs.openclaw.ai/plugins/agent-tools -- Plugins: ship the bundled BlueBubbles channel plugin (disabled by default). https://docs.openclaw.ai/channels/bluebubbles -- Plugins: migrate bundled messaging extensions to the plugin SDK and resolve plugin-sdk imports in the loader. -- Plugins: migrate the Zalo plugin to the shared plugin SDK runtime. https://docs.openclaw.ai/channels/zalo -- Plugins: migrate the Zalo Personal plugin to the shared plugin SDK runtime. https://docs.openclaw.ai/plugins/zalouser -- Plugins: allow optional agent tools with explicit allowlists and add the plugin tool authoring guide. https://docs.openclaw.ai/plugins/agent-tools -- Plugins: auto-enable bundled channel/provider plugins when configuration is present. -- Plugins: sync plugin sources on channel switches and update npm-installed plugins during `openclaw update`. -- Plugins: share npm plugin update logic between `openclaw update` and `openclaw plugins update`. - -- Gateway/API: add `/v1/responses` (OpenResponses) with item-based input + semantic streaming events. (#1229) -- Gateway/API: expand `/v1/responses` to support file/image inputs, tool_choice, usage, and output limits. (#1229) -- Usage: add `/usage cost` summaries and macOS menu cost charts. https://docs.openclaw.ai/reference/api-usage-costs -- Security: warn when <=300B models run without sandboxing while web tools are enabled. https://docs.openclaw.ai/cli/security -- Exec: add host/security/ask routing for gateway + node exec. https://docs.openclaw.ai/tools/exec -- Exec: add `/exec` directive for per-session exec defaults (host/security/ask/node). https://docs.openclaw.ai/tools/exec -- Exec approvals: migrate approvals to `~/.openclaw/exec-approvals.json` with per-agent allowlists + skill auto-allow toggle, and add approvals UI + node exec lifecycle events. https://docs.openclaw.ai/tools/exec-approvals -- Nodes: add headless node host (`openclaw node start`) for `system.run`/`system.which`. https://docs.openclaw.ai/cli/node -- Nodes: add node daemon service install/status/start/stop/restart. https://docs.openclaw.ai/cli/node -- Bridge: add `skills.bins` RPC to support node host auto-allow skill bins. -- Sessions: add daily reset policy with per-type overrides and idle windows (default 4am local), preserving legacy idle-only configs. (#1146) https://docs.openclaw.ai/concepts/session -- Sessions: allow `sessions_spawn` to override thinking level for sub-agent runs. https://docs.openclaw.ai/tools/subagents -- Channels: unify thread/topic allowlist matching + command/mention gating helpers across core providers. https://docs.openclaw.ai/concepts/groups -- Models: add Qwen Portal OAuth provider support. (#1120) https://docs.openclaw.ai/providers/qwen -- Onboarding: add allowlist prompts and username-to-id resolution across core and extension channels. https://docs.openclaw.ai/start/onboarding -- Docs: clarify allowlist input types and onboarding behavior for messaging channels. https://docs.openclaw.ai/start/onboarding -- Docs: refresh Android node discovery docs for the Gateway WS service type. https://docs.openclaw.ai/platforms/android -- Docs: surface Amazon Bedrock in provider lists and clarify Bedrock auth env vars. (#1289) https://docs.openclaw.ai/bedrock -- Docs: clarify WhatsApp voice notes. https://docs.openclaw.ai/channels/whatsapp -- Docs: clarify Windows WSL portproxy LAN access notes. https://docs.openclaw.ai/platforms/windows -- Docs: refresh bird skill install metadata and usage notes. (#1302) https://docs.openclaw.ai/tools/browser-login -- Agents: add local docs path resolution and include docs/mirror/source/community pointers in the system prompt. -- Agents: clarify node_modules read-only guidance in agent instructions. -- Config: stamp last-touched metadata on write and warn if the config is newer than the running build. -- macOS: hide usage section when usage is unavailable instead of showing provider errors. -- Android: migrate node transport to the Gateway WebSocket protocol with TLS pinning support + gateway discovery naming. -- Android: send structured payloads in node events/invokes and include user-agent metadata in gateway connects. -- Android: remove legacy bridge transport code now that nodes use the gateway protocol. -- Android: bump okhttp + dnsjava to satisfy lint dependency checks. -- Build: update workspace + core/plugin deps. -- Build: use tsgo for dev/watch builds by default (opt out with `OPENCLAW_TS_COMPILER=tsc`). -- Repo: remove the Peekaboo git submodule now that the SPM release is used. -- macOS: switch PeekabooBridge integration to the tagged Swift Package Manager release. -- macOS: stop syncing Peekaboo in postinstall. -- Swabble: use the tagged Commander Swift package release. - -### Breaking - -- **BREAKING:** Reject invalid/unknown config entries and refuse to start the gateway for safety. Run `openclaw doctor --fix` to repair, then update plugins (`openclaw plugins update`) if you use any. - -### Fixes - -- Discovery: shorten Bonjour DNS-SD service type to `_moltbot-gw._tcp` and update discovery clients/docs. -- Diagnostics: export OTLP logs, correct queue depth tracking, and document message-flow telemetry. -- Diagnostics: emit message-flow diagnostics across channels via shared dispatch. (#1244) -- Diagnostics: gate heartbeat/webhook logging. (#1244) -- Gateway: strip inbound envelope headers from chat history messages to keep clients clean. -- Gateway: clarify unauthorized handshake responses with token/password mismatch guidance. -- Gateway: allow mobile node client ids for iOS + Android handshake validation. (#1354) -- Gateway: clarify connect/validation errors for gateway params. (#1347) -- Gateway: preserve restart wake routing + thread replies across restarts. (#1337) -- Gateway: reschedule per-agent heartbeats on config hot reload without restarting the runner. -- Gateway: require authorized restarts for SIGUSR1 (restart/apply/update) so config gating can't be bypassed. -- Cron: auto-deliver isolated agent output to explicit targets without tool calls. (#1285) -- Agents: preserve subagent announce thread/topic routing + queued replies across channels. (#1241) -- Agents: propagate accountId into embedded runs so sub-agent announce routing honors the originating account. (#1058) -- Agents: avoid treating timeout errors with "aborted" messages as user aborts, so model fallback still runs. (#1137) -- Agents: sanitize oversized image payloads before send and surface image-dimension errors. -- Sessions: fall back to session labels when listing display names. (#1124) -- Compaction: include tool failure summaries in safeguard compaction to prevent retry loops. (#1084) -- Config: log invalid config issues once per run and keep invalid-config errors stackless. -- Config: allow Perplexity as a web_search provider in config validation. (#1230) -- Config: allow custom fields under `skills.entries..config` for skill credentials/config. (#1226) -- Doctor: clarify plugin auto-enable hint text in the startup banner. -- Doctor: canonicalize legacy session keys in session stores to prevent stale metadata. (#1169) -- Docs: make docs:list fail fast with a clear error if the docs directory is missing. -- Plugins: add Nextcloud Talk manifest for plugin config validation. (#1297) -- Plugins: surface plugin load/register/config errors in gateway logs with plugin/source context. -- CLI: preserve cron delivery settings when editing message payloads. (#1322) -- CLI: keep `openclaw logs` output resilient to broken pipes while preserving progress output. -- CLI: avoid duplicating --profile/--dev flags when formatting commands. -- CLI: centralize CLI command registration to keep fast-path routing and program wiring in sync. (#1207) -- CLI: keep banners on routed commands, restore config guarding outside fast-path routing, and tighten fast-path flag parsing while skipping console capture for extra speed. (#1195) -- CLI: skip runner rebuilds when dist is fresh. (#1231) -- CLI: add WSL2/systemd unavailable hints in daemon status/doctor output. -- Status: route native `/status` to the active agent so model selection reflects the correct profile. (#1301) -- Status: show both usage windows with reset hints when usage data is available. (#1101) -- UI: keep config form enums typed, preserve empty strings, protect sensitive defaults, and deepen config search. (#1315) -- UI: preserve ordered list numbering in chat markdown. (#1341) -- UI: allow Control UI to read gatewayUrl from URL params for remote WebSocket targets. (#1342) -- UI: prevent double-scroll in Control UI chat by locking chat layout to the viewport. (#1283) -- UI: enable shell mode for sync Windows spawns to avoid `pnpm ui:build` EINVAL. (#1212) -- TUI: keep thinking blocks ordered before content during streaming and isolate per-run assembly. (#1202) -- TUI: align custom editor initialization with the latest pi-tui API. (#1298) -- TUI: show generic empty-state text for searchable pickers. (#1201) -- TUI: highlight model search matches and stabilize search ordering. -- Configure: hide OpenRouter auto routing model from the model picker. (#1182) -- Memory: show total file counts + scan issues in `openclaw memory status`. -- Memory: fall back to non-batch embeddings after repeated batch failures. -- Memory: apply OpenAI batch defaults even without explicit remote config. -- Memory: index atomically so failed reindex preserves the previous memory database. (#1151) -- Memory: avoid sqlite-vec unique constraint failures when reindexing duplicate chunk ids. (#1151) -- Memory: retry transient 5xx errors (Cloudflare) during embedding indexing. -- Memory: parallelize embedding indexing with rate-limit retries. -- Memory: split overly long lines to keep embeddings under token limits. -- Memory: skip empty chunks to avoid invalid embedding inputs. -- Memory: split embedding batches to avoid OpenAI token limits during indexing. -- Memory: probe sqlite-vec availability in `openclaw memory status`. -- Exec approvals: enforce allowlist when ask is off. -- Exec approvals: prefer raw command for node approvals/events. -- Tools: show exec elevated flag before the command and keep it outside markdown in tool summaries. -- Tools: return a companion-app-required message when node exec is requested with no paired node. -- Tools: return a companion-app-required message when `system.run` is requested without a supporting node. -- Exec: default gateway/node exec security to allowlist when unset (sandbox stays deny). -- Exec: prefer bash when fish is default shell, falling back to sh if bash is missing. (#1297) -- Exec: merge login-shell PATH for host=gateway exec while keeping daemon PATH minimal. (#1304) -- Streaming: emit assistant deltas for OpenAI-compatible SSE chunks. (#1147) -- Discord: make resolve warnings avoid raw JSON payloads on rate limits. -- Discord: process message handlers in parallel across sessions to avoid event queue blocking. (#1295) -- Discord: stop reconnecting the gateway after aborts to prevent duplicate listeners. -- Discord: only emit slow listener warnings after 30s. -- Discord: inherit parent channel allowlists for thread slash commands and reactions. (#1123) -- Telegram: honor pairing allowlists for native slash commands. -- Telegram: preserve hidden text_link URLs by expanding entities in inbound text. (#1118) -- Slack: resolve Bolt import interop for Bun + Node. (#1191) -- Web search: infer Perplexity base URL from API key source (direct vs OpenRouter). -- Web fetch: harden SSRF protection with shared hostname checks and redirect limits. (#1346) -- Browser: register AI snapshot refs for act commands. (#1282) -- Voice call: include request query in Twilio webhook verification when publicUrl is set. (#864) -- Anthropic: default API prompt caching to 1h with configurable TTL override. -- Anthropic: ignore TTL for OAuth. -- Auth profiles: keep auto-pinned preference while allowing rotation on failover. (#1138) -- Auth profiles: user pins stay locked. (#1138) -- Model catalog: avoid caching import failures, log transient discovery errors, and keep partial results. (#1332) -- Tests: stabilize Windows gateway/CLI tests by skipping sidecars, normalizing argv, and extending timeouts. -- Tests: stabilize plugin SDK resolution and embedded agent timeouts. -- Windows: install gateway scheduled task as the current user. -- Windows: show friendly guidance instead of failing on access denied. -- macOS: load menu session previews asynchronously so items populate while the menu is open. -- macOS: use label colors for session preview text so previews render in menu subviews. -- macOS: suppress usage error text in the menubar cost view. -- macOS: Doctor repairs LaunchAgent bootstrap issues for Gateway + Node when listed but not loaded. (#1166) -- macOS: avoid touching launchd in Remote over SSH so quitting the app no longer disables the remote gateway. (#1105) -- macOS: bundle Textual resources in packaged app builds to avoid code block crashes. (#1006) -- Daemon: include HOME in service environments to avoid missing HOME errors. (#1214) - -Thanks @AlexMikhalev, @CoreyH, @John-Rood, @KrauseFx, @MaudeBot, @Nachx639, @NicholaiVogel, @RyanLisse, @ThePickle31, @VACInc, @Whoaa512, @YuriNachos, @aaronveklabs, @abdaraxus, @alauppe, @ameno-, @artuskg, @austinm911, @bradleypriest, @cheeeee, @dougvk, @fogboots, @gnarco, @gumadeiras, @jdrhyne, @joelklabo, @longmaba, @mukhtharcm, @odysseus0, @oscargavin, @rhjoh, @sebslight, @sibbl, @sleontenko, @steipete, @suminhthanh, @thewilloftheshadow, @tyler6204, @vignesh07, @visionik, @ysqander, @zerone0x. - -## 2026.1.16-2 - -### Changes - -- CLI: stamp build commit into dist metadata so banners show the commit in npm installs. -- CLI: close memory manager after memory commands to avoid hanging processes. (#1127) — thanks @NicholasSpisak. - -## 2026.1.16-1 - -### Highlights - -- Hooks: add hooks system with bundled hooks, CLI tooling, and docs. (#1028) — thanks @ThomsenDrake. https://docs.openclaw.ai/hooks -- Media: add inbound media understanding (image/audio/video) with provider + CLI fallbacks. https://docs.openclaw.ai/nodes/media-understanding -- Plugins: add Zalo Personal plugin (`@openclaw/zalouser`) and unify channel directory for plugins. (#1032) — thanks @suminhthanh. https://docs.openclaw.ai/plugins/zalouser -- Models: add Vercel AI Gateway auth choice + onboarding updates. (#1016) — thanks @timolins. https://docs.openclaw.ai/providers/vercel-ai-gateway -- Sessions: add `session.identityLinks` for cross-platform DM session li nking. (#1033) — thanks @thewilloftheshadow. https://docs.openclaw.ai/concepts/session -- Web search: add `country`/`language` parameters (schema + Brave API) and docs. (#1046) — thanks @YuriNachos. https://docs.openclaw.ai/tools/web - -### Breaking - -- **BREAKING:** `openclaw message` and message tool now require `target` (dropping `to`/`channelId` for destinations). (#1034) — thanks @tobalsan. -- **BREAKING:** Channel auth now prefers config over env for Discord/Telegram/Matrix (env is fallback only). (#1040) — thanks @thewilloftheshadow. -- **BREAKING:** Drop legacy `chatType: "room"` support; use `chatType: "channel"`. -- **BREAKING:** remove legacy provider-specific target resolution fallbacks; target resolution is centralized with plugin hints + directory lookups. -- **BREAKING:** `openclaw hooks` is now `openclaw webhooks`; hooks live under `openclaw hooks`. https://docs.openclaw.ai/cli/webhooks -- **BREAKING:** `openclaw plugins install ` now copies into `~/.openclaw/extensions` (use `--link` to keep path-based loading). - -### Changes - -- Plugins: ship bundled plugins disabled by default and allow overrides by installed versions. (#1066) — thanks @ItzR3NO. -- Plugins: add bundled Antigravity + Gemini CLI OAuth + Copilot Proxy provider plugins. (#1066) — thanks @ItzR3NO. -- Tools: improve `web_fetch` extraction using Readability (with fallback). -- Tools: add Firecrawl fallback for `web_fetch` when configured. -- Tools: send Chrome-like headers by default for `web_fetch` to improve extraction on bot-sensitive sites. -- Tools: Firecrawl fallback now uses bot-circumvention + cache by default; remove basic HTML fallback when extraction fails. -- Tools: default `exec` exit notifications and auto-migrate legacy `tools.bash` to `tools.exec`. -- Tools: add `exec` PTY support for interactive sessions. https://docs.openclaw.ai/tools/exec -- Tools: add tmux-style `process send-keys` and bracketed paste helpers for PTY sessions. -- Tools: add `process submit` helper to send CR for PTY sessions. -- Tools: respond to PTY cursor position queries to unblock interactive TUIs. -- Tools: include tool outputs in verbose mode and expand verbose tool feedback. -- Skills: update coding-agent guidance to prefer PTY-enabled exec runs and simplify tmux usage. -- TUI: refresh session token counts after runs complete or fail. (#1079) — thanks @d-ploutarchos. -- Status: trim `/status` to current-provider usage only and drop the OAuth/token block. -- Directory: unify `openclaw directory` across channels and plugin channels. -- UI: allow deleting sessions from the Control UI. -- Memory: add sqlite-vec vector acceleration with CLI status details. -- Memory: add experimental session transcript indexing for memory_search (opt-in via memorySearch.experimental.sessionMemory + sources). -- Skills: add user-invocable skill commands and expanded skill command registration. -- Telegram: default reaction level to minimal and enable reaction notifications by default. -- Telegram: allow reply-chain messages to bypass mention gating in groups. (#1038) — thanks @adityashaw2. -- iMessage: add remote attachment support for VM/SSH deployments. -- Messages: refresh live directory cache results when resolving targets. -- Messages: mirror delivered outbound text/media into session transcripts. (#1031) — thanks @TSavo. -- Messages: avoid redundant sender envelopes for iMessage + Signal group chats. (#1080) — thanks @tyler6204. -- Media: normalize Deepgram audio upload bytes for fetch compatibility. -- Cron: isolated cron jobs now start a fresh session id on every run to prevent context buildup. -- Docs: add `/help` hub, Node/npm PATH guide, and expand directory CLI docs. -- Config: support env var substitution in config values. (#1044) — thanks @sebslight. -- Health: add per-agent session summaries and account-level health details, and allow selective probes. (#1047) — thanks @gumadeiras. -- Hooks: add hook pack installs (npm/path/zip/tar) with `openclaw.hooks` manifests and `openclaw hooks install/update`. -- Plugins: add zip installs and `--link` to avoid copying local paths. - -### Fixes - -- macOS: drain subprocess pipes before waiting to avoid deadlocks. (#1081) — thanks @thesash. -- Verbose: wrap tool summaries/output in markdown only for markdown-capable channels. -- Tools: include provider/session context in elevated exec denial errors. -- Tools: normalize exec tool alias naming in tool error logs. -- Logging: reuse shared ANSI stripping to keep console capture lint-clean. -- Logging: prefix nested agent output with session/run/channel context. -- Telegram: accept tg/group/telegram prefixes + topic targets for inline button validation. (#1072) — thanks @danielz1z. -- Telegram: split long captions into follow-up messages. -- Config: block startup on invalid config, preserve best-effort doctor config, and keep rolling config backups. (#1083) — thanks @mukhtharcm. -- Sub-agents: normalize announce delivery origin + queue bucketing by accountId to keep multi-account routing stable. (#1061, #1058) — thanks @adam91holt. -- Sessions: include deliveryContext in sessions.list and reuse normalized delivery routing for announce/restart fallbacks. (#1058) -- Sessions: propagate deliveryContext into last-route updates to keep account/channel routing stable. (#1058) -- Sessions: preserve overrides on `/new` reset. -- Memory: prevent unhandled rejections when watch/interval sync fails. (#1076) — thanks @roshanasingh4. -- Memory: avoid gateway crash when embeddings return 429/insufficient_quota (disable tool + surface error). (#1004) -- Gateway: honor explicit delivery targets without implicit accountId fallback; preserve lastAccountId for implicit routing. -- Gateway: avoid reusing last-to/accountId when the requested channel differs; sync deliveryContext with last route fields. -- Build: allow `@lydell/node-pty` builds on supported platforms. -- Repo: fix oxlint config filename and move ignore pattern into config. (#1064) — thanks @connorshea. -- Messages: `/stop` now hard-aborts queued followups and sub-agent runs; suppress zero-count stop notes. -- Messages: honor message tool channel when deduping sends. -- Messages: include sender labels for live group messages across channels, matching queued/history formatting. (#1059) -- Sessions: reset `compactionCount` on `/new` and `/reset`, and preserve `sessions.json` file mode (0600). -- Sessions: repair orphaned user turns before embedded prompts. -- Sessions: hard-stop `sessions.delete` cleanup. -- Channels: treat replies to the bot as implicit mentions across supported channels. -- Channels: normalize object-format capabilities in channel capability parsing. -- Security: default-deny slash/control commands unless a channel computed `CommandAuthorized` (fixes accidental “open” behavior), and ensure WhatsApp + Zalo plugin channels gate inline `/…` tokens correctly. https://docs.openclaw.ai/gateway/security -- Security: redact sensitive text in gateway WS logs. -- Tools: cap pending `exec` process output to avoid unbounded buffers. -- CLI: speed up `openclaw sandbox-explain` by avoiding heavy plugin imports when normalizing channel ids. -- Browser: remote profile tab operations prefer persistent Playwright and avoid silent HTTP fallbacks. (#1057) — thanks @mukhtharcm. -- Browser: remote profile tab ops follow-up: shared Playwright loader, Playwright-based focus, and more coverage (incl. opt-in live Browserless test). (follow-up to #1057) — thanks @mukhtharcm. -- Browser: refresh extension relay tab metadata after navigation so `/json/list` stays current. (#1073) — thanks @roshanasingh4. -- WhatsApp: scope self-chat response prefix; inject pending-only group history and clear after any processed message. -- WhatsApp: include `linked` field in `describeAccount`. -- Agents: drop unsigned Gemini tool calls and avoid JSON Schema `format` keyword collisions. -- Agents: hide the image tool when the primary model already supports images. -- Agents: avoid duplicate sends by replying with `NO_REPLY` after `message` tool sends. -- Auth: inherit/merge sub-agent auth profiles from the main agent. -- Gateway: resolve local auth for security probe and validate gateway token/password file modes. (#1011, #1022) — thanks @ivanrvpereira, @kkarimi. -- Signal/iMessage: bound transport readiness waits to 30s with periodic logging. (#1014) — thanks @Szpadel. -- iMessage: avoid RPC restart loops. -- OpenAI image-gen: handle URL + `b64_json` responses and remove deprecated `response_format` (use URL downloads). -- CLI: auto-update global installs when installed via a package manager. -- Routing: migrate legacy `accountID` bindings to `accountId` and remove legacy fallback lookups. (#1047) — thanks @gumadeiras. -- Discord: truncate skill command descriptions to 100 chars for slash command limits. (#1018) — thanks @evalexpr. -- Security: bump `tar` to 7.5.3. -- Models: align ZAI thinking toggles. -- iMessage/Signal: include sender metadata for non-queued group messages. (#1059) -- Discord: preserve whitespace when chunking long lines so message splits keep spacing intact. -- Skills: fix skills watcher ignored list typing (tsc). - -## 2026.1.15 - -### Highlights - -- Plugins: add provider auth registry + `openclaw models auth login` for plugin-driven OAuth/API key flows. -- Browser: improve remote CDP/Browserless support (auth passthrough, `wss` upgrade, timeouts, clearer errors). -- Heartbeat: per-agent configuration + 24h duplicate suppression. (#980) — thanks @voidserf. -- Security: audit warns on weak model tiers; app nodes store auth tokens encrypted (Keychain/SecurePrefs). - -### Breaking - -- **BREAKING:** iOS minimum version is now 18.0 to support Textual markdown rendering in native chat. (#702) -- **BREAKING:** Microsoft Teams is now a plugin; install `@openclaw/msteams` via `openclaw plugins install @openclaw/msteams`. -- **BREAKING:** Channel auth now prefers config over env for Discord/Telegram/Matrix (env is fallback only). (#1040) — thanks @thewilloftheshadow. - -### Changes - -- UI/Apps: move channel/config settings to schema-driven forms and rename Connections → Channels. (#1040) — thanks @thewilloftheshadow. -- CLI: set process titles to `openclaw-` for clearer process listings. -- CLI/macOS: sync remote SSH target/identity to config and let `gateway status` auto-infer SSH targets (ssh-config aware). -- Telegram: scope inline buttons with allowlist default + callback gating in DMs/groups. -- Telegram: default reaction notifications to own. -- Tools: improve `web_fetch` extraction using Readability (with fallback). -- Heartbeat: tighten prompt guidance + suppress duplicate alerts for 24h. (#980) — thanks @voidserf. -- Repo: ignore local identity files to avoid accidental commits. (#1001) — thanks @gerardward2007. -- Sessions/Security: add `session.dmScope` for multi-user DM isolation and audit warnings. (#948) — thanks @Alphonse-arianee. -- Onboarding: switch channels setup to a single-select loop with per-channel actions and disabled hints in the picker. -- TUI: show provider/model labels for the active session and default model. -- Heartbeat: add per-agent heartbeat configuration and multi-agent docs example. -- UI: show gateway auth guidance + doc link on unauthorized Control UI connections. -- UI: add session deletion action in Control UI sessions list. (#1017) — thanks @Szpadel. -- Security: warn on weak model tiers (Haiku, below GPT-5, below Claude 4.5) in `openclaw security audit`. -- Apps: store node auth tokens encrypted (Keychain/SecurePrefs). -- Daemon: share profile/state-dir resolution across service helpers and honor `CLAWDBOT_STATE_DIR` for Windows task scripts. -- Docs: clarify multi-gateway rescue bot guidance. (#969) — thanks @bjesuiter. -- Agents: add Current Date & Time system prompt section with configurable time format (auto/12/24). -- Tools: normalize Slack/Discord message timestamps with `timestampMs`/`timestampUtc` while keeping raw provider fields. -- macOS: add `system.which` for prompt-free remote skill discovery (with gateway fallback to `system.run`). -- Docs: add Date & Time guide and update prompt/timezone configuration docs. -- Messages: debounce rapid inbound messages across channels with per-connector overrides. (#971) — thanks @juanpablodlc. -- Messages: allow media-only sends (CLI/tool) and show Telegram voice recording status for voice notes. (#957) — thanks @rdev. -- Auth/Status: keep auth profiles sticky per session (rotate on compaction/new), surface provider usage headers in `/status` and `openclaw models status`, and update docs. -- CLI: add `--json` output for `openclaw daemon` lifecycle/install commands. -- Memory: make `node-llama-cpp` an optional dependency (avoid Node 25 install failures) and improve local-embeddings fallback/errors. -- Browser: add `snapshot refs=aria` (Playwright aria-ref ids) for self-resolving refs across `snapshot` → `act`. -- Browser: `profile="chrome"` now defaults to host control and returns clearer “attach a tab” errors. -- Browser: prefer stable Chrome for auto-detect, with Brave/Edge fallbacks and updated docs. (#983) — thanks @cpojer. -- Browser: increase remote CDP reachability timeouts + add `remoteCdpTimeoutMs`/`remoteCdpHandshakeTimeoutMs`. -- Browser: preserve auth/query tokens for remote CDP endpoints and pass Basic auth for CDP HTTP/WS. (#895) — thanks @mukhtharcm. -- Telegram: add bidirectional reaction support with configurable notifications and agent guidance. (#964) — thanks @bohdanpodvirnyi. -- Telegram: allow custom commands in the bot menu (merged with native; conflicts ignored). (#860) — thanks @nachoiacovino. -- Discord: allow allowlisted guilds without channel lists to receive messages when `groupPolicy="allowlist"`. — thanks @thewilloftheshadow. -- Discord: allow emoji/sticker uploads + channel actions in config defaults. (#870) — thanks @JDIVE. - -### Fixes - -- Messages: make `/stop` clear queued followups and pending session lane work for a hard abort. -- Messages: make `/stop` abort active sub-agent runs spawned from the requester session and report how many were stopped. -- WhatsApp: report linked status consistently in channel status. (#1050) — thanks @YuriNachos. -- Sessions: keep per-session overrides when `/new` resets compaction counters. (#1050) — thanks @YuriNachos. -- Skills: allow OpenAI image-gen helper to handle URL or base64 responses. (#1050) — thanks @YuriNachos. -- WhatsApp: default response prefix only for self-chat, using identity name when set. -- Signal/iMessage: bound transport readiness waits to 30s with periodic logging. (#1014) — thanks @Szpadel. -- iMessage: treat missing `imsg rpc` support as fatal to avoid restart loops. -- Auth: merge main auth profiles into per-agent stores for sub-agents and document inheritance. (#1013) — thanks @marcmarg. -- Agents: avoid JSON Schema `format` collisions in tool params by renaming snapshot format fields. (#1013) — thanks @marcmarg. -- Fix: make `openclaw update` auto-update global installs when installed via a package manager. -- Fix: list model picker entries as provider/model pairs for explicit selection. (#970) — thanks @mcinteerj. -- Fix: align OpenAI image-gen defaults with DALL-E 3 standard quality and document output formats. (#880) — thanks @mkbehr. -- Fix: persist `gateway.mode=local` after selecting Local run mode in `openclaw configure`, even if no other sections are chosen. -- Daemon: fix profile-aware service label resolution (env-driven) and add coverage for launchd/systemd/schtasks. (#969) — thanks @bjesuiter. -- Agents: avoid false positives when logging unsupported Google tool schema keywords. -- Agents: skip Gemini history downgrades for google-antigravity to preserve tool calls. (#894) — thanks @mukhtharcm. -- Status: restore usage summary line for current provider when no OAuth profiles exist. -- Fix: guard model fallback against undefined provider/model values. (#954) — thanks @roshanasingh4. -- Fix: refactor session store updates, add chat.inject, and harden subagent cleanup flow. (#944) — thanks @tyler6204. -- Fix: clean up suspended CLI processes across backends. (#978) — thanks @Nachx639. -- Fix: support MiniMax coding plan usage responses with `model_remains`/`current_interval_*` payloads. -- Fix: honor message tool channel for duplicate suppression (prefer `NO_REPLY` after `message` tool sends). (#1053) — thanks @sashcatanzarite. -- Fix: suppress WhatsApp pairing replies for historical catch-up DMs on initial link. (#904) -- Browser: extension mode recovers when only one tab is attached (stale targetId fallback). -- Browser: fix `tab not found` for extension relay snapshots/actions when Playwright blocks `newCDPSession` (use the single available Page). -- Browser: upgrade `ws` → `wss` when remote CDP uses `https` (fixes Browserless handshake). -- Telegram: skip `message_thread_id=1` for General topic sends while keeping typing indicators. (#848) — thanks @azade-c. -- Fix: sanitize user-facing error text + strip `` tags across reply pipelines. (#975) — thanks @ThomsenDrake. -- Fix: normalize pairing CLI aliases, allow extension channels, and harden Zalo webhook payload parsing. (#991) — thanks @longmaba. -- Fix: allow local Tailscale Serve hostnames without treating tailnet clients as direct. (#885) — thanks @oswalpalash. -- Fix: reset sessions after role-ordering conflicts to recover from consecutive user turns. (#998) - -## 2026.1.14-1 - -### Highlights - -- Web search: `web_search`/`web_fetch` tools (Brave API) + first-time setup in onboarding/configure. -- Browser control: Chrome extension relay takeover mode + remote browser control support. -- Plugins: channel plugins (gateway HTTP hooks) + Zalo plugin + onboarding install flow. (#854) — thanks @longmaba. -- Security: expanded `openclaw security audit` (+ `--fix`), detect-secrets CI scan, and a `SECURITY.md` reporting policy. - -### Changes - -- Docs: clarify per-agent auth stores, sandboxed skill binaries, and elevated semantics. -- Docs: add FAQ entries for missing provider auth after adding agents and Gemini thinking signature errors. -- Agents: add optional auth-profile copy prompt on `agents add` and improve auth error messaging. -- Security: expand `openclaw security audit` checks (model hygiene, config includes, plugin allowlists, exposure matrix) and extend `--fix` to tighten more sensitive state paths. -- Security: add `SECURITY.md` reporting policy. -- Channels: add Matrix plugin (external) with docs + onboarding hooks. -- Plugins: add Zalo channel plugin with gateway HTTP hooks and onboarding install prompt. (#854) — thanks @longmaba. -- Onboarding: add a security checkpoint prompt (docs link + sandboxing hint); require `--accept-risk` for `--non-interactive`. -- Docs: expand gateway security hardening guidance and incident response checklist. -- Docs: document DM history limits for channel DMs. (#883) — thanks @pkrmf. -- Security: add detect-secrets CI scan and baseline guidance. (#227) — thanks @Hyaxia. -- Tools: add `web_search`/`web_fetch` (Brave API), auto-enable `web_fetch` for sandboxed sessions, and remove the `brave-search` skill. -- CLI/Docs: add a web tools configure section for storing Brave API keys and update onboarding tips. -- Browser: add Chrome extension relay takeover mode (toolbar button), plus `openclaw browser extension install/path` and remote browser control (standalone server + token auth). - -### Fixes - -- Sessions: refactor session store updates to lock + mutate per-entry, add chat.inject, and harden subagent cleanup flow. (#944) — thanks @tyler6204. -- Browser: add tests for snapshot labels/efficient query params and labeled image responses. -- Google: downgrade unsigned thinking blocks before send to avoid missing signature errors. -- Doctor: avoid re-adding WhatsApp config when only legacy ack reactions are set. (#927, fixes #900) — thanks @grp06. -- Agents: scrub tuple `items` schemas for Gemini tool calls. (#926, fixes #746) — thanks @grp06. -- Agents: harden Antigravity Claude history/tool-call sanitization. (#968) — thanks @rdev. -- Agents: stabilize sub-agent announce status from runtime outcomes and normalize Result/Notes. (#835) — thanks @roshanasingh4. -- Embedded runner: suppress raw API error payloads from replies. (#924) — thanks @grp06. -- Auth: normalize Claude Code CLI profile mode to oauth and auto-migrate config. (#855) — thanks @sebslight. -- Daemon: clear persisted launchd disabled state before bootstrap (fixes `daemon install` after uninstall). (#849) — thanks @ndraiman. -- Logging: tolerate `EIO` from console writes to avoid gateway crashes. (#925, fixes #878) — thanks @grp06. -- Sandbox: restore `docker.binds` config validation for custom bind mounts. (#873) — thanks @akonyer. -- Sandbox: preserve configured PATH for `docker exec` so custom tools remain available. (#873) — thanks @akonyer. -- Slack: respect `channels.slack.requireMention` default when resolving channel mention gating. (#850) — thanks @evalexpr. -- Telegram: aggregate split inbound messages into one prompt (reduces “one reply per fragment”). -- Auto-reply: treat trailing `NO_REPLY` tokens as silent replies. -- Config: prevent partial config writes from clobbering unrelated settings (base hash guard + merge patch for connection saves). - -## 2026.1.14 - -### Changes - -- Usage: add MiniMax coding plan usage tracking. -- Auth: label Claude Code CLI auth options. (#915) — thanks @SeanZoR. -- Docs: standardize Claude Code CLI naming across docs and prompts. (follow-up to #915) -- Telegram: add message delete action in the message tool. (#903) — thanks @sleontenko. -- Config: add `channels..configWrites` gating for channel-initiated config writes; migrate Slack channel IDs. - -### Fixes - -- Mac: pass auth token/password to dashboard URL for authenticated access. (#918) — thanks @rahthakor. -- UI: use application-defined WebSocket close code (browser compatibility). (#918) — thanks @rahthakor. -- TUI: render picker overlays via the overlay stack so /models and /settings display. (#921) — thanks @grizzdank. -- TUI: add a bright spinner + elapsed time in the status line for send/stream/run states. -- TUI: show LLM error messages (rate limits, auth, etc.) instead of `(no output)`. -- Gateway/Dev: ensure `pnpm gateway:dev` always uses the dev profile config + state (`~/.openclaw-dev`). - -#### Agents / Auth / Tools / Sandbox - -- Agents: make user time zone and 24-hour time explicit in the system prompt. (#859) — thanks @CashWilliams. -- Agents: strip downgraded tool call text without eating adjacent replies and filter thinking-tag leaks. (#905) — thanks @erikpr1994. -- Agents: cap tool call IDs for OpenAI/OpenRouter to avoid request rejections. (#875) — thanks @j1philli. -- Agents: scrub tuple `items` schemas for Gemini tool calls. (#926, fixes #746) — thanks @grp06. -- Agents: stabilize sub-agent announce status from runtime outcomes and normalize Result/Notes. (#835) — thanks @roshanasingh4. -- Auth: normalize Claude Code CLI profile mode to oauth and auto-migrate config. (#855) — thanks @sebslight. -- Embedded runner: suppress raw API error payloads from replies. (#924) — thanks @grp06. -- Logging: tolerate `EIO` from console writes to avoid gateway crashes. (#925, fixes #878) — thanks @grp06. -- Sandbox: restore `docker.binds` config validation and preserve configured PATH for `docker exec`. (#873) — thanks @akonyer. -- Google: downgrade unsigned thinking blocks before send to avoid missing signature errors. - -#### macOS / Apps - -- macOS: ensure launchd log directory exists with a test-only override. (#909) — thanks @roshanasingh4. -- macOS: format ConnectionsStore config to satisfy SwiftFormat lint. (#852) — thanks @mneves75. -- macOS: pass auth token/password to dashboard URL for authenticated access. (#918) — thanks @rahthakor. -- macOS: reuse launchd gateway auth and skip wizard when gateway config already exists. (#917) -- macOS: prefer the default bridge tunnel port in remote mode for node bridge connectivity; document macOS remote control + bridge tunnels. (#960, fixes #865) — thanks @kkarimi. -- Apps: use canonical main session keys from gateway defaults across macOS/iOS/Android to avoid creating bare `main` sessions. -- macOS: fix cron preview/testing payload to use `channel` key. (#867) — thanks @wes-davis. -- Telegram: honor `channels.telegram.timeoutSeconds` for grammY API requests. (#863) — thanks @Snaver. -- Telegram: split long captions into media + follow-up text messages. (#907) - thanks @jalehman. -- Telegram: migrate group config when supergroups change chat IDs. (#906) — thanks @sleontenko. -- Messaging: unify markdown formatting + format-first chunking for Slack/Telegram/Signal. (#920) — thanks @TheSethRose. -- Slack: drop Socket Mode events with mismatched `api_app_id`/`team_id`. (#889) — thanks @roshanasingh4. -- Discord: isolate autoThread thread context. (#856) — thanks @davidguttman. -- WhatsApp: fix context isolation using wrong ID (was bot's number, now conversation ID). (#911) — thanks @tristanmanchester. -- WhatsApp: normalize user JIDs with device suffix for allowlist checks in groups. (#838) — thanks @peschee. - -## 2026.1.13 - -### Fixes - -- Postinstall: treat already-applied pnpm patches as no-ops to avoid npm/bun install failures. -- Packaging: pin `@mariozechner/pi-ai` to 0.45.7 and refresh patched dependency to match npm resolution. - -## 2026.1.12-2 - -### Fixes - -- Packaging: include `dist/memory/**` in the npm tarball (fixes `ERR_MODULE_NOT_FOUND` for `dist/memory/index.js`). -- Agents: persist sub-agent registry across gateway restarts and resume announce flow safely. (#831) — thanks @roshanasingh4. -- Agents: strip invalid Gemini thought signatures from OpenRouter history to avoid 400s. (#841, #845) — thanks @MatthieuBizien. - -## 2026.1.12-1 - -### Fixes - -- Packaging: include `dist/channels/**` in the npm tarball (fixes `ERR_MODULE_NOT_FOUND` for `dist/channels/registry.js`). - -## 2026.1.12 - -### Highlights - -- **BREAKING:** rename chat “providers” (Slack/Telegram/WhatsApp/…) to **channels** across CLI/RPC/config; legacy config keys auto-migrate on load (and are written back as `channels.*`). -- Memory: add vector search for agent memories (Markdown-only) with SQLite index, chunking, lazy sync + file watch, and per-agent enablement/fallback. -- Plugins: restore full voice-call plugin parity (Telnyx/Twilio, streaming, inbound policies, tools/CLI). -- Models: add Synthetic provider plus Moonshot Kimi K2 0905 + turbo/thinking variants (with docs). (#811) — thanks @siraht; (#818) — thanks @mickahouan. -- Cron: one-shot schedules accept ISO timestamps (UTC) with optional delete-after-run; cron jobs can target a specific agent (CLI + macOS/Control UI). -- Agents: add compaction mode config with optional safeguard summarization and per-agent model fallbacks. (#700) — thanks @thewilloftheshadow; (#583) — thanks @mitschabaude-bot. - -### New & Improved - -- Memory: add custom OpenAI-compatible embedding endpoints; support OpenAI/local `node-llama-cpp` embeddings with per-agent overrides and provider metadata in tools/CLI. (#819) — thanks @mukhtharcm. -- Memory: new `openclaw memory` CLI plus `memory_search`/`memory_get` tools with snippets + line ranges; index stored under `~/.openclaw/memory/{agentId}.sqlite` with watch-on-by-default. -- Agents: strengthen memory recall guidance; make workspace bootstrap truncation configurable (default 20k) with warnings; add default sub-agent model config. -- Tools/Sandbox: add tool profiles + group shorthands; support tool-policy groups in `tools.sandbox.tools`; drop legacy `memory` shorthand; allow Docker bind mounts via `docker.binds`. (#790) — thanks @akonyer. -- Tools: add provider/model-specific tool policy overrides (`tools.byProvider`) to trim tool exposure per provider. -- Tools: add browser `scrollintoview` action; allow Claude/Gemini tool param aliases; allow thinking `xhigh` for GPT-5.2/Codex with safe downgrades. (#793) — thanks @hsrvc; (#444) — thanks @grp06. -- Gateway/CLI: add Tailscale binary discovery, custom bind mode, and probe auth retry; add `openclaw dashboard` auto-open flow; default native slash commands to `"auto"` with per-provider overrides. (#740) — thanks @jeffersonwarrior. -- Auth/Onboarding: add Chutes OAuth (PKCE + refresh + onboarding choice); normalize API key inputs; default TUI onboarding to `deliver: false`. (#726) — thanks @FrieSei; (#791) — thanks @roshanasingh4. -- Providers: add `discord.allowBots`; trim legacy MiniMax M2 from default catalogs; route MiniMax vision to the Coding Plan VLM endpoint (also accepts `@/path/to/file.png` inputs). (#802) — thanks @zknicker. -- Gateway: allow Tailscale Serve identity headers to satisfy token auth; rebuild Control UI assets when protocol schema is newer. (#823) — thanks @roshanasingh4; (#786) — thanks @meaningfool. -- Heartbeat: default `ackMaxChars` to 300 so short `HEARTBEAT_OK` replies stay internal. - -### Installer - -- Install: run `openclaw doctor --non-interactive` after git installs/updates and nudge daemon restarts when detected. - -### Fixes - -- Doctor: warn on pnpm workspace mismatches, missing Control UI assets, and missing tsx binaries; offer UI rebuilds. -- Tools: apply global tool allow/deny even when agent-specific tool policy is set. -- Models/Providers: treat credential validation failures as auth errors to trigger fallback; normalize `${ENV_VAR}` apiKey values and auto-fill missing provider keys; preserve explicit GitHub Copilot provider config + agent-dir auth profiles. (#822) — thanks @sebslight; (#705) — thanks @TAGOOZ. -- Auth: drop invalid auth profiles from ordering so environment keys can still be used for providers like MiniMax. -- Gemini: normalize Gemini 3 ids to preview variants; strip Gemini CLI tool call/response ids; downgrade missing `thought_signature`; strip Claude `msg_*` thought_signature fields to avoid base64 decode errors. (#795) — thanks @thewilloftheshadow; (#783) — thanks @ananth-vardhan-cn; (#793) — thanks @hsrvc; (#805) — thanks @marcmarg. -- Agents: auto-recover from compaction context overflow by resetting the session and retrying; propagate overflow details from embedded runs so callers can recover. -- MiniMax: strip malformed tool invocation XML; include `MiniMax-VL-01` in implicit provider for image pairing. (#809) — thanks @latitudeki5223. -- Onboarding/Auth: honor `CLAWDBOT_AGENT_DIR` / `PI_CODING_AGENT_DIR` when writing auth profiles (MiniMax). (#829) — thanks @roshanasingh4. -- Anthropic: handle `overloaded_error` with a friendly message and failover classification. (#832) — thanks @danielz1z. -- Anthropic: merge consecutive user turns (preserve newest metadata) before validation to avoid incorrect role errors. (#804) — thanks @ThomsenDrake. -- Messaging: enforce context isolation for message tool sends; keep typing indicators alive during tool execution. (#793) — thanks @hsrvc; (#450, #447) — thanks @thewilloftheshadow. -- Auto-reply: `/status` allowlist behavior, reasoning-tag enforcement on fallback, and system-event enqueueing for elevated/reasoning toggles. (#810) — thanks @mcinteerj. -- System events: include local timestamps when events are injected into prompts. (#245) — thanks @thewilloftheshadow. -- 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. (#800, #807) — thanks @davidguttman; (#744) — thanks @thewilloftheshadow. -- Telegram: preserve forum topic thread ids, persist polling offsets, respect account bindings in webhook mode, and show typing indicator in General topics. (#727, #739) — thanks @thewilloftheshadow; (#821) — thanks @gumadeiras; (#779) — thanks @azade-c. -- Slack: accept slash commands with or without leading `/` for custom command configs. (#798) — thanks @thewilloftheshadow. -- Cron: persist disabled jobs correctly; accept `jobId` aliases for update/run/remove params. (#205, #252) — thanks @thewilloftheshadow. -- Gateway/CLI: honor `CLAWDBOT_LAUNCHD_LABEL` / `CLAWDBOT_SYSTEMD_UNIT` overrides; `agents.list` respects explicit config; reduce noisy loopback WS logs during tests; run `openclaw doctor --non-interactive` during updates. (#781) — thanks @ronyrus. -- Onboarding/Control UI: refuse invalid configs (run doctor first); quote Windows browser URLs for OAuth; keep chat scroll position unless the user is near the bottom. (#764) — thanks @mukhtharcm; (#794) — thanks @roshanasingh4; (#217) — thanks @thewilloftheshadow. -- Tools/UI: harden tool input schemas for strict providers; drop null-only union variants for Gemini schema cleanup; treat `maxChars: 0` as unlimited; keep TUI last streamed response instead of "(no output)". (#782) — thanks @AbhisekBasu1; (#796) — thanks @gabriel-trigo; (#747) — thanks @thewilloftheshadow. -- Connections UI: polish multi-account account cards. (#816) — thanks @steipete. - -### Maintenance - -- Dependencies: bump Pi packages to 0.45.3 and refresh patched pi-ai. -- Testing: update Vitest + browser-playwright to 4.0.17. -- Docs: add Amazon Bedrock provider notes and link from models/FAQ. - -## 2026.1.11 - -### Highlights - -- Plugins are now first-class: loader + CLI management, plus the new Voice Call plugin. -- Config: modular `$include` support for split config files. (#731) — thanks @pasogott. -- Agents/Pi: reserve compaction headroom so pre-compaction memory writes can run before auto-compaction. -- Agents: automatic pre-compaction memory flush turn to store durable memories before compaction. - -### Changes - -- CLI/Onboarding: simplify MiniMax auth choice to a single M2.1 option. -- CLI: configure section selection now loops until Continue. -- Docs: explain MiniMax vs MiniMax Lightning (speed vs cost) and restore LM Studio example. -- Docs: add Cerebras GLM 4.6/4.7 config example (OpenAI-compatible endpoint). -- Onboarding/CLI: group model/auth choice by provider and label Z.AI as GLM 4.7. -- Onboarding/Docs: add Moonshot AI (Kimi K2) auth choice + config example. -- CLI/Onboarding: prompt to reuse detected API keys for Moonshot/MiniMax/Z.AI/Gemini/Anthropic/OpenCode. -- Auto-reply: add compact `/model` picker (models + available providers) and show provider endpoints in `/model status`. -- Control UI: add Config tab model presets (MiniMax M2.1, GLM 4.7, Kimi) for one-click setup. -- Plugins: add extension loader (tools/RPC/CLI/services), discovery paths, and config schema + Control UI labels (uiHints). -- Plugins: add `openclaw plugins install` (path/tgz/npm), plus `list|info|enable|disable|doctor` UX. -- Plugins: voice-call plugin now real (Twilio/log), adds start/status RPC/CLI/tool + tests. -- Docs: add plugins doc + cross-links from tools/skills/gateway config. -- Docs: add beginner-friendly plugin quick start + expand Voice Call plugin docs. -- Tests: add Docker plugin loader + tgz-install smoke test. -- Tests: extend Docker plugin E2E to cover installing from local folders (`plugins.load.paths`) and `file:` npm specs. -- Tests: add coverage for pre-compaction memory flush settings. -- Tests: modernize live model smoke selection for current releases and enforce tools/images/thinking-high coverage. (#769) — thanks @steipete. -- Agents/Tools: add `apply_patch` tool for multi-file edits (experimental; gated by tools.exec.applyPatch; OpenAI-only). -- Agents/Tools: rename the bash tool to exec (config alias maintained). (#748) — thanks @myfunc. -- Agents: add pre-compaction memory flush config (`agents.defaults.compaction.*`) with a soft threshold + system prompt. -- Config: add `$include` directive for modular config files. (#731) — thanks @pasogott. -- Build: set pnpm minimum release age to 2880 minutes (2 days). (#718) — thanks @dan-dr. -- macOS: prompt to install the global `openclaw` CLI when missing in local mode; install via `openclaw.ai/install-cli.sh` (no onboarding) and use external launchd/CLI instead of the embedded gateway runtime. -- Docs: add gog calendar event color IDs from `gog calendar colors`. (#715) — thanks @mjrussell. -- Cron/CLI: add `--model` flag to cron add/edit commands. (#711) — thanks @mjrussell. -- Cron/CLI: trim model overrides on cron edits and document main-session guidance. (#711) — thanks @mjrussell. -- Skills: bundle `skill-creator` to guide creating and packaging skills. -- Providers: add per-DM history limit overrides (`dmHistoryLimit`) with provider-level config. (#728) — thanks @pkrmf. -- Discord: expose channel/category management actions in the message tool. (#730) — thanks @NicholasSpisak. -- Docs: rename README “macOS app” section to “Apps”. (#733) — thanks @AbhisekBasu1. -- Gateway: require `client.id` in WebSocket connect params; use `client.instanceId` for presence de-dupe; update docs/tests. -- macOS: remove the attach-only gateway setting; local mode now always manages launchd while still attaching to an existing gateway if present. - -### Installer - -- Postinstall: replace `git apply` with builtin JS patcher (works npm/pnpm/bun; no git dependency) plus regression tests. -- Postinstall: skip pnpm patch fallback when the new patcher is active. -- Installer tests: add root+non-root docker smokes, CI workflow to fetch openclaw.ai scripts and run install sh/cli with onboarding skipped. -- Installer UX: support `CLAWDBOT_NO_ONBOARD=1` for non-interactive installs; fix npm prefix on Linux and auto-install git. -- Installer UX: add `install.sh --help` with flags/env and git install hint. -- Installer UX: add `--install-method git|npm` and auto-detect source checkouts (prompt to update git checkout vs migrate to npm). - -### Fixes - -- Models/Onboarding: configure MiniMax (minimax.io) via Anthropic-compatible `/anthropic` endpoint by default (keep `minimax-api` as a legacy alias). -- Models: normalize Gemini 3 Pro/Flash IDs to preview names for live model lookups. (#769) — thanks @steipete. -- CLI: fix guardCancel typing for configure prompts. (#769) — thanks @steipete. -- Gateway/WebChat: include handshake validation details in the WebSocket close reason for easier debugging; preserve close codes. -- Gateway/Auth: send invalid connect responses before closing the handshake; stabilize invalid-connect auth test. -- Gateway: tighten gateway listener detection. -- Control UI: hide onboarding chat when configured and guard the mobile chat sidebar overlay. -- Auth: read Codex keychain credentials and make the lookup platform-aware. -- macOS/Release: avoid bundling dist artifacts in relay builds and generate appcasts from zip-only sources. -- Doctor: surface plugin diagnostics in the report. -- Plugins: treat `plugins.load.paths` directory entries as package roots when they contain `package.json` + `openclaw.extensions`; load plugin packages from config dirs; extract archives without system tar. -- Config: expand `~` in `CLAWDBOT_CONFIG_PATH` and common path-like config fields (including `plugins.load.paths`); guard invalid `$include` paths. (#731) — thanks @pasogott. -- Agents: stop pre-creating session transcripts so first user messages persist in JSONL history. -- Agents: skip pre-compaction memory flush when the session workspace is read-only. -- Auto-reply: ignore inline `/status` directives unless the message is directive-only. -- Auto-reply: align `/think` default display with model reasoning defaults. (#751) — thanks @gabriel-trigo. -- Auto-reply: flush block reply buffers on tool boundaries. (#750) — thanks @sebslight. -- Auto-reply: allow sender fallback for command authorization when `SenderId` is empty (WhatsApp self-chat). (#755) — thanks @juanpablodlc. -- Auto-reply: treat whitespace-only sender ids as missing for command authorization (WhatsApp self-chat). (#766) — thanks @steipete. -- Heartbeat: refresh prompt text for updated defaults. -- Agents/Tools: use PowerShell on Windows to capture system utility output. (#748) — thanks @myfunc. -- Docker: tolerate unset optional env vars in docker-setup.sh under strict mode. (#725) — thanks @petradonka. -- CLI/Update: preserve base environment when passing overrides to update subprocesses. (#713) — thanks @danielz1z. -- Agents: treat message tool errors as failures so fallback replies still send; require `to` + `message` for `action=send`. (#717) — thanks @theglove44. -- Agents: preserve reasoning items on tool-only turns. -- Agents/Subagents: wait for completion before announcing, align wait timeout with run timeout, and make announce prompts more emphatic. -- Agents: route subagent transcripts to the target agent sessions directory and add regression coverage. (#708) — thanks @xMikeMickelson. -- Agents/Tools: preserve action enums when flattening tool schemas. (#708) — thanks @xMikeMickelson. -- Gateway/Agents: canonicalize main session aliases for store writes and add regression coverage. (#709) — thanks @xMikeMickelson. -- Agents: reset sessions and retry when auto-compaction overflows instead of crashing the gateway. -- Providers/Telegram: normalize command mentions for consistent parsing. (#729) — thanks @obviyus. -- Providers: skip DM history limit handling for non-DM sessions. (#728) — thanks @pkrmf. -- Sandbox: fix non-main mode incorrectly sandboxing the main DM session and align `/status` runtime reporting with effective sandbox state. -- Sandbox/Gateway: treat `agent::main` as a main-session alias when `session.mainKey` is customized (backwards compatible). -- Auto-reply: fast-path allowlisted slash commands (inline `/help`/`/commands`/`/status`/`/whoami` stripped before model). - -## 2026.1.10 - -### Highlights - -- CLI: `openclaw status` now table-based + shows OS/update/gateway/daemon/agents/sessions; `status --all` adds a full read-only debug report (tables, log tails, Tailscale summary, and scan progress via OSC-9 + spinner). -- CLI Backends: add Codex CLI fallback with resume support (text output) and JSONL parsing for new runs, plus a live CLI resume probe. -- CLI: add `openclaw update` (safe-ish git checkout update) + `--update` shorthand. (#673) — thanks @fm1randa. -- Gateway: add OpenAI-compatible `/v1/chat/completions` HTTP endpoint (auth, SSE streaming, per-agent routing). (#680). - -### Changes - -- Onboarding/Models: add first-class Z.AI (GLM) auth choice (`zai-api-key`) + `--zai-api-key` flag. -- CLI/Onboarding: add OpenRouter API key auth option in configure/onboard. (#703) — thanks @mteam88. -- Agents: add human-delay pacing between block replies (modes: off/natural/custom, per-agent configurable). (#446) — thanks @tony-freedomology. -- Agents/Browser: add `browser.target` (sandbox/host/custom) with sandbox host-control gating via `agents.defaults.sandbox.browser.allowHostControl`, allowlists for custom control URLs/hosts/ports, and expand browser tool docs (remote control, profiles, internals). -- Onboarding/Models: add catalog-backed default model picker to onboarding + configure. (#611) — thanks @jonasjancarik. -- Agents/OpenCode Zen: update fallback models + defaults, keep legacy alias mappings. (#669) — thanks @magimetal. -- CLI: add `openclaw reset` and `openclaw uninstall` flows (interactive + non-interactive) plus docker cleanup smoke test. -- Providers: move provider wiring to a plugin architecture. (#661). -- Providers: unify group history context wrappers across providers with per-provider/per-account `historyLimit` overrides (fallback to `messages.groupChat.historyLimit`). Set `0` to disable. (#672). -- Gateway/Heartbeat: optionally deliver heartbeat `Reasoning:` output (`agents.defaults.heartbeat.includeReasoning`). (#690) -- Docker: allow optional home volume + extra bind mounts in `docker-setup.sh`. (#679) — thanks @gabriel-trigo. - -### Fixes - -- Auto-reply: suppress draft/typing streaming for `NO_REPLY` (silent system ops) so it doesn’t leak partial output. -- CLI/Status: expand tables to full terminal width; clarify provider setup vs runtime warnings; richer per-provider detail; token previews in `status` while keeping `status --all` redacted; add troubleshooting link footer; keep log tails pasteable; show gateway auth used when reachable; surface provider runtime errors (Signal/iMessage/Slack); harden `tailscale status --json` parsing; make `status --all` scan progress determinate; and replace the footer with a 3-line “Next steps” recommendation (share/debug/probe). -- CLI/Gateway: clarify that `openclaw gateway status` reports RPC health (connect + RPC) and shows RPC failures separately from connect failures. -- CLI/Update: gate progress spinner on stdout TTY and align clean-check step label. (#701) — thanks @bjesuiter. -- Telegram: add `/whoami` + `/id` commands to reveal sender id for allowlists; allow `@username` and prefixed ids in `allowFrom` prompts (with stability warning). -- Heartbeat: strip markup-wrapped `HEARTBEAT_OK` so acks don’t leak to external providers (e.g., Telegram). -- Control UI: stop auto-writing `telegram.groups["*"]` and warn/confirm before enabling wildcard groups. -- WhatsApp: send ack reactions only for handled messages and ignore legacy `messages.ackReaction` (doctor copies to `whatsapp.ackReaction`). (#629) — thanks @pasogott. -- Sandbox/Skills: mirror skills into sandbox workspaces for read-only mounts so SKILL.md stays accessible. -- Terminal/Table: ANSI-safe wrapping to prevent table clipping/color loss; add regression coverage. -- Docker: allow optional apt packages during image build and document the build arg. (#697) — thanks @gabriel-trigo. -- Gateway/Heartbeat: deliver reasoning even when the main heartbeat reply is `HEARTBEAT_OK`. (#694) — thanks @antons. -- Agents/Pi: inject config `temperature`/`maxTokens` into streaming without replacing the session streamFn; cover with live maxTokens probe. (#732) — thanks @peschee. -- macOS: clear unsigned launchd overrides on signed restarts and warn via doctor when attach-only/disable markers are set. (#695) — thanks @jeffersonwarrior. -- Agents: enforce single-writer session locks and drop orphan tool results to prevent tool-call ID failures (MiniMax/Anthropic-compatible APIs). -- Docs: make `openclaw status` the first diagnostic step, clarify `status --deep` behavior, and document `/whoami` + `/id`. -- Docs/Testing: clarify live tool+image probes and how to list your testable `provider/model` ids. -- Tests/Live: make gateway bash+read probes resilient to provider formatting while still validating real tool calls. -- WhatsApp: detect @lid mentions in groups using authDir reverse mapping + resolve self JID E.164 for mention gating. (#692) — thanks @peschee. -- Gateway/Auth: default to token auth on loopback during onboarding, add doctor token generation flow, and tighten audio transcription config to Whisper-only. -- Providers: dedupe inbound messages across providers to avoid duplicate LLM runs on redeliveries/reconnects. (#689) — thanks @adam91holt. -- Agents: strip ``/`` tags from hidden reasoning output and cover tag variants in tests. (#688) — thanks @theglove44. -- macOS: save model picker selections as normalized provider/model IDs and keep manual entries aligned. (#683) — thanks @benithors. -- Agents: recognize "usage limit" errors as rate limits for failover. (#687) — thanks @evalexpr. -- CLI: avoid success message when daemon restart is skipped. (#685) — thanks @carlulsoe. -- Commands: disable `/config` + `/debug` by default; gate via `commands.config`/`commands.debug` and hide from native registration/help output. -- Agents/System: clarify that sub-agents remain sandboxed and cannot use elevated host access. -- Gateway: disable the OpenAI-compatible `/v1/chat/completions` endpoint by default; enable via `gateway.http.endpoints.chatCompletions.enabled=true`. -- macOS: stabilize bridge tunnels, guard invoke senders on disconnect, and drain stdout/stderr to avoid deadlocks. (#676) — thanks @ngutman. -- Agents/System: clarify sandboxed runtime in system prompt and surface elevated availability when sandboxed. -- Auto-reply: prefer `RawBody` for command/directive parsing (WhatsApp + Discord) and prevent fallback runs from clobbering concurrent session updates. (#643) — thanks @mcinteerj. -- WhatsApp: fix group reactions by preserving message IDs and sender JIDs in history; normalize participant phone numbers to JIDs in outbound reactions. (#640) — thanks @mcinteerj. -- WhatsApp: expose group participant IDs to the model so reactions can target the right sender. -- Cron: `wakeMode: "now"` waits for heartbeat completion (and retries when the main lane is busy). (#666) — thanks @roshanasingh4. -- Agents/OpenAI: fix Responses tool-only → follow-up turn handling (avoid standalone `reasoning` items that trigger 400 “required following item”) and replay reasoning items in Responses/Codex Responses history for tool-call-only turns. -- Sandbox: add `openclaw sandbox explain` (effective policy inspector + fix-it keys); improve “sandbox jail” tool-policy/elevated errors with actionable config key paths; link to docs. -- Hooks/Gmail: keep Tailscale serve path at `/` while preserving the public path. (#668) — thanks @antons. -- Hooks/Gmail: allow Tailscale target URLs to preserve internal serve paths. -- Auth: update Claude Code keychain credentials in-place during refresh sync; share JSON file helpers; add CLI fallback coverage. -- Auth: throttle external CLI credential syncs (Claude/Codex), reduce Keychain reads, and skip sync when cached credentials are still fresh. -- CLI: respect `CLAWDBOT_STATE_DIR` for node pairing + voice wake settings storage. (#664) — thanks @azade-c. -- Onboarding/Gateway: persist non-interactive gateway token auth in config; add WS wizard + gateway tool-calling regression coverage. -- Gateway/Control UI: make `chat.send` non-blocking, wire Stop to `chat.abort`, and treat `/stop` as an out-of-band abort. (#653) -- Gateway/Control UI: allow `chat.abort` without `runId` (abort active runs), suppress post-abort chat streaming, and prune stuck chat runs. (#653) -- Gateway/Control UI: sniff image attachments for chat.send, drop non-images, and log mismatches. (#670) — thanks @cristip73. -- macOS: force `restart-mac.sh --sign` to require identities and keep bundled Node signed for relay verification. (#580) — thanks @jeffersonwarrior. -- Gateway/Agent: accept image attachments on `agent` (multimodal message) and add live gateway image probe (`CLAWDBOT_LIVE_GATEWAY_IMAGE_PROBE=1`). -- CLI: `openclaw sessions` now includes `elev:*` + `usage:*` flags in the table output. -- CLI/Pairing: accept positional provider for `pairing list|approve` (npm-run compatible); update docs/bot hints. -- Branding: normalize legacy casing/branding to “OpenClaw” (CLI, status, docs). -- Auto-reply: fix native `/model` not updating the actual chat session (Telegram/Slack/Discord). (#646) -- Doctor: offer to run `openclaw update` first on git installs (keeps doctor output aligned with latest). -- Doctor: avoid false legacy workspace warning when install dir is `~/openclaw`. (#660) -- iMessage: fix reasoning persistence across DMs; avoid partial/duplicate replies when reasoning is enabled. (#655) — thanks @antons. -- Models/Auth: allow MiniMax API configs without `models.providers.minimax.apiKey` (auth profiles / `MINIMAX_API_KEY`). (#656) — thanks @mneves75. -- Agents: avoid duplicate replies when the message tool sends. (#659) — thanks @mickahouan. -- Agents: harden Cloud Code Assist tool ID sanitization (toolUse/toolCall/toolResult) and scrub extra JSON Schema constraints. (#665) — thanks @sebslight. -- Agents: sanitize tool results + Cloud Code Assist tool IDs at context-build time (prevents mid-run strict-provider request rejects). -- Agents/Tools: resolve workspace-relative Read/Write/Edit paths; align bash default cwd. (#642) — thanks @mukhtharcm. -- Discord: include forwarded message snapshots in agent session context. (#667) — thanks @rubyrunsstuff. -- Telegram: add `telegram.draftChunk` to tune draft streaming chunking for `streamMode: "block"`. (#667) — thanks @rubyrunsstuff. -- Tests/Agents: add regression coverage for workspace tool path resolution and bash cwd defaults. -- iOS/Android: enable stricter concurrency/lint checks; fix Swift 6 strict concurrency issues + Android lint errors (ExifInterface, obsolete SDK check). (#662) — thanks @KristijanJovanovski. -- Auth: read Codex CLI keychain tokens on macOS before falling back to `~/.codex/auth.json`, preventing stale refresh tokens from breaking gateway live tests. -- Security/Exec approvals: reject shell command substitution (`$()` and backticks) inside double quotes to prevent exec allowlist bypass when exec allowlist mode is explicitly enabled (the default configuration does not use this mode). Thanks @simecek. -- iOS/macOS: share `AsyncTimeout`, require explicit `bridgeStableID` on connect, and harden tool display defaults (avoids missing-resource label fallbacks). -- Telegram: serialize media-group processing to avoid missed albums under load. -- Signal: handle `dataMessage.reaction` events (signal-cli SSE) to avoid broken attachment errors. (#637) — thanks @neist. -- Docs: showcase entries for ParentPay, R2 Upload, iOS TestFlight, and Oura Health. (#650) — thanks @henrino3. -- Agents: repair session transcripts by dropping duplicate tool results across the whole history (unblocks Anthropic-compatible APIs after retries). -- Tests/Live: reset the gateway session between model runs to avoid cross-provider transcript incompatibilities (notably OpenAI Responses reasoning replay rules). - -## 2026.1.9 - -### Highlights - -- Microsoft Teams provider: polling, attachments, outbound CLI send, per-channel policy. -- Models/Auth expansion: OpenCode Zen + MiniMax API onboarding; token auth profiles + auth order; OAuth health in doctor/status. -- CLI/Gateway UX: message subcommands, gateway discover/status/SSH, /config + /debug, sandbox CLI. -- Provider reliability sweep: WhatsApp contact cards/targets, Telegram audio-as-voice + streaming, Signal reactions, Slack threading, Discord stability. -- Auto-reply + status: block-streaming controls, reasoning handling, usage/cost reporting. -- Control UI/TUI: queued messages, session links, reasoning view, mobile polish, logs UX. - -### Breaking - -- CLI: `openclaw message` now subcommands (`message send|poll|...`) and requires `--provider` unless only one provider configured. -- Commands/Tools: `/restart` and gateway restart tool disabled by default; enable with `commands.restart=true`. - -### New Features and Changes - -- Models/Auth: OpenCode Zen onboarding (#623) — thanks @magimetal; MiniMax Anthropic-compatible API + hosted onboarding (#590, #495) — thanks @mneves75, @tobiasbischoff. -- Models/Auth: setup-token + token auth profiles; `openclaw models auth order {get,set,clear}`; per-agent auth candidates in `/model status`; OAuth expiry checks in doctor/status. -- Agent/System: claude-cli runner; `session_status` tool (and sandbox allow); adaptive context pruning default; system prompt messaging guidance + no auto self-update; eligible skills list injection; sub-agent context trimmed. -- Commands: `/commands` list; `/models` alias; `/usage` alias; `/debug` runtime overrides + effective config view; `/config` chat updates + `/config get`; `config --section`. -- CLI/Gateway: unified message tool + message subcommands; gateway discover (local + wide-area DNS-SD) with JSON/timeout; gateway status human-readable + JSON + SSH loopback; wide-area records include gatewayPort/sshPort/cliPath + tailnet DNS fallback. -- CLI UX: logs output modes (pretty/plain/JSONL) + colorized health/daemon output; global `--no-color`; lobster palette in onboarding/config. -- Dev ergonomics: gateway `--dev/--reset` + dev profile auto-config; C-3PO dev templates; dev gateway/TUI helper scripts. -- Sandbox/Workspace: sandbox list/recreate commands; sync skills into sandbox workspace; sandbox browser auto-start. -- Config/Onboarding: inline env vars; OpenAI API key flow to shared `~/.openclaw/.env`; Opus 4.5 default prompt for Anthropic auth; QuickStart auto-install gateway (Node-only) + provider picker tweaks + skip-systemd flags; TUI bootstrap prompt (`tui --message`); remove Bun runtime choice. -- Providers: Microsoft Teams provider (polling, attachments, outbound sends, requireMention, config reload/DM policy). (#404) — thanks @onutc -- Providers: WhatsApp broadcast groups for multi-agent replies (#547) — thanks @pasogott; inbound media size cap configurable (#505) — thanks @koala73; identity-based message prefixes (#578) — thanks @p6l-richard. -- Providers: Telegram inline keyboard buttons + callback payload routing (#491) — thanks @azade-c; cron topic delivery targets (#474/#478) — thanks @mitschabaude-bot, @nachoiacovino; `[[audio_as_voice]]` tag support (#490) — thanks @jarvis-medmatic. -- Providers: Signal reactions + notifications with allowlist support. -- Status/Usage: /status cost reporting + `/cost` lines; auth profile snippet; provider usage windows. -- Control UI: mobile responsiveness (#558) — thanks @carlulsoe; queued messages + Enter-to-send (#527) — thanks @YuriNachos; session links (#471) — thanks @HazAT; reasoning view; skill install feedback (#445) — thanks @pkrmf; chat layout refresh (#475) — thanks @rahthakor; docs link + new session button; drop explicit `ui:install`. -- TUI: agent picker + agents list RPC; improved status line. -- Doctor/Daemon: audit/repair flows, permissions checks, supervisor config audits; provider status probes + warnings for Discord intents and Telegram privacy; last activity timestamps; gateway restart guidance. -- Docs: Hetzner Docker VPS guide + cross-links (#556/#592) — thanks @Iamadig; Ansible guide (#545) — thanks @pasogott; provider troubleshooting index; hook parameter expansion (#532) — thanks @mcinteerj; model allowlist notes; OAuth deep dive; showcase refresh. -- Apps/Branding: refreshed iOS/Android/macOS icons (#521) — thanks @fishfisher. - -### Fixes - -- Packaging: include MS Teams send module in npm tarball. -- Sandbox/Browser: auto-start CDP endpoint; proxy CDP out of container for attachOnly; relax Bun fetch typing; align sandbox list output with config images. -- Agents/Runtime: gate heartbeat prompt to default sessions; /stop aborts between tool calls; require explicit system-event session keys; guard small context windows; fix model fallback stringification; sessions_spawn inherits provider; failover on billing/credits; respect auth cooldown ordering; restore Anthropic OAuth tool dispatch + tool-name bypass; avoid OpenAI invalid reasoning replay; harden Gmail hook model defaults. -- Agent history/schema: strip/skip empty assistant/error blocks to prevent session corruption/Claude 400s; scrub unsupported JSON Schema keywords + sanitize tool call IDs for Cloud Code Assist; simplify Gemini-compatible tool/session schemas; require raw for config.apply. -- Auto-reply/Streaming: default audioAsVoice false; preserve audio_as_voice propagation + buffer audio blocks + guard voice notes; block reply ordering (timeout) + forced-block fence-safe; avoid chunk splits inside parentheses + fence-close breaks + invalid UTF-16 truncation; preserve inline directive spacing + allow whitespace in reply tags; filter NO_REPLY prefixes + normalize routed replies; suppress leakage with separate Reasoning; block streaming defaults (off by default, minChars/idle tuning) + coalesced blocks; dedupe followup queue; restore explicit responsePrefix default. -- Status/Commands: provider prefix in /status model display; usage filtering + provider mapping; auth label + usage snapshots (claude-cli fallback + optional claude.ai); show Verbose/Elevated only when enabled; compact usage/cost line + restore emoji-rich status; /status in directive-only + multi-directive handling; mention-bypass elevated handling; surface provider usage errors; wire /usage to /status; restore hidden gateway-daemon alias; fallback /model list when catalog unavailable. -- WhatsApp: vCard/contact cards (prefer FN, include numbers, show all contacts, keep summary counts, better empty summaries); preserve group JIDs + normalize targets; resolve @lid mappings/JIDs (Baileys/auth-dir) + inbound mapping; route queued replies to sender; improve web listener errors + remove provider name from errors; record outbound activity account id; fix web media fetch errors; broadcast group history consistency. -- Telegram: keep streamMode draft-only; long-poll conflict retries + update dedupe; grammY fetch mismatch fixes + restrict native fetch to Bun; suppress getUpdates stack traces; include user id in pairing; audio_as_voice handling fixes. -- Discord/Slack: thread context helpers + forum thread starters; avoid category parent overrides; gateway reconnect logs + HELLO timeout + stop provider after reconnect exhaustion; DM recipient parsing for numeric IDs; remove incorrect limited warning; reply threading + mrkdwn edge cases; remove ack reactions after reply; gateway debug event visibility. -- Signal: reaction handling safety; own-reaction matching (uuid+phone); UUID-only senders accepted; ignore reaction-only messages. -- MS Teams: download image attachments reliably; fix top-level replies; stop on shutdown + honor chunk limits; normalize poll providers/deps; pairing label fixes. -- iMessage: isolate group-ish threads by chat_id. -- Gateway/Daemon/Doctor: atomic config writes; repair gateway service entrypoint + install switches; non-interactive legacy migrations; systemd unit alignment + KillMode=process; node bridge keepalive/pings; Launch at Login persistence; bundle MoltbotKit resources + Swift 6.2 compat dylib; relay version check + remove smoke test; regen Swift GatewayModels + keep agent provider string; cron jobId alias + channel alias migration + main session key normalization; heartbeat Telegram accountId resolution; avoid WhatsApp fallback for internal runs; gateway listener error wording; serveBaseUrl param; honor gateway --dev; fix wide-area discovery updates; align agents.defaults schema; provider account metadata in daemon status; refresh Carbon patch for gateway fixes; restore doctor prompter initialValue handling. -- Control UI/TUI: persist per-session verbose off + hide tool cards; logs tab opens at bottom; relative asset paths + landing cleanup; session labels lookup/persistence; stop pinning main session in recents; start logs at bottom; TUI status bar refresh + timeout handling + hide reasoning label when off. -- Onboarding/Configure: QuickStart single-select provider picker; avoid Codex CLI false-expiry warnings; clarify WhatsApp owner prompt; fix Minimax hosted onboarding (agents.defaults + msteams heartbeat target); remove configure Control UI prompt; honor gateway --dev flag. - -### Maintenance - -- Dependencies: bump pi-\* stack to 0.42.2. -- Dependencies: Pi 0.40.0 bump (#543) — thanks @mcinteerj. -- Build: Docker build cache layer (#605) — thanks @zknicker. - -- Auth: enable OAuth token refresh for Claude Code CLI credentials (`anthropic:claude-cli`) with bidirectional sync back to Claude Code storage (file on Linux/Windows, Keychain on macOS). This allows long-running agents to operate autonomously without manual re-authentication (#654 — thanks @radek-paclt). - -## 2026.1.8 - -### Highlights - -- Security: DMs locked down by default across providers; pairing-first + allowlist guidance. -- Sandbox: per-agent scope defaults + workspace access controls; tool/session isolation tuned. -- Agent loop: compaction, pruning, streaming, and error handling hardened. -- Providers: Telegram/WhatsApp/Discord/Slack reliability, threading, reactions, media, and retries improved. -- Control UI: logs tab, streaming stability, focus mode, and large-output rendering fixes. -- CLI/Gateway/Doctor: daemon/logs/status, auth migration, and diagnostics significantly expanded. - -### Breaking - -- **SECURITY (update ASAP):** inbound DMs are now **locked down by default** on Telegram/WhatsApp/Signal/iMessage/Discord/Slack. - - Previously, if you didn’t configure an allowlist, your bot could be **open to anyone** (especially discoverable Telegram bots). - - New default: DM pairing (`dmPolicy="pairing"` / `discord.dm.policy="pairing"` / `slack.dm.policy="pairing"`). - - To keep old “open to everyone” behavior: set `dmPolicy="open"` and include `"*"` in the relevant `allowFrom` (Discord/Slack: `discord.dm.allowFrom` / `slack.dm.allowFrom`). - - Approve requests via `openclaw pairing list ` + `openclaw pairing approve `. -- Sandbox: default `agent.sandbox.scope` to `"agent"` (one container/workspace per agent). Use `"session"` for per-session isolation; `"shared"` disables cross-session isolation. -- Timestamps in agent envelopes are now UTC (compact `YYYY-MM-DDTHH:mmZ`); removed `messages.timestampPrefix`. Add `agent.userTimezone` to tell the model the user’s local time (system prompt only). -- Model config schema changes (auth profiles + model lists); doctor auto-migrates and the gateway rewrites legacy configs on startup. -- Commands: gate all slash commands to authorized senders; add `/compact` to manually compact session context. -- Groups: `whatsapp.groups`, `telegram.groups`, and `imessage.groups` now act as allowlists when set. Add `"*"` to keep allow-all behavior. -- Auto-reply: removed `autoReply` from Discord/Slack/Telegram channel configs; use `requireMention` instead (Telegram topics now support `requireMention` overrides). -- CLI: remove `update`, `gateway-daemon`, `gateway {install|uninstall|start|stop|restart|daemon status|wake|send|agent}`, and `telegram` commands; move `login/logout` to `providers login/logout` (top-level aliases hidden); use `daemon` for service control, `send`/`agent`/`wake` for RPC, and `nodes canvas` for canvas ops. - -### Fixes - -- **CLI/Gateway/Doctor:** daemon runtime selection + improved logs/status/health/errors; auth/password handling for local CLI; richer close/timeout details; auto-migrate legacy config/sessions/state; integrity checks + repair prompts; `--yes`/`--non-interactive`; `--deep` gateway scans; better restart/service hints. -- **Agent loop + compaction:** compaction/pruning tuning, overflow handling, safer bootstrap context, and per-provider threading/confirmations; opt-in tool-result pruning + compact tracking. -- **Sandbox + tools:** per-agent sandbox overrides, workspaceAccess controls, session tool visibility, tool policy overrides, process isolation, and tool schema/timeout/reaction unification. -- **Providers (Telegram/WhatsApp/Discord/Slack/Signal/iMessage):** retry/backoff, threading, reactions, media groups/attachments, mention gating, typing behavior, and error/log stability; long polling + forum topic isolation for Telegram. -- **Gateway/CLI UX:** `openclaw logs`, cron list colors/aliases, docs search, agents list/add/delete flows, status usage snapshots, runtime/auth source display, and `/status`/commands auth unification. -- **Control UI/Web:** logs tab, focus mode polish, config form resilience, streaming stability, tool output caps, windowed chat history, and reconnect/password URL auth. -- **macOS/Android/TUI/Build:** macOS gateway races, QR bundling, JSON5 config safety, Voice Wake hardening; Android EXIF rotation + APK naming/versioning; TUI key handling; tooling/bundling fixes. -- **Packaging/compat:** npm dist folder coverage, Node 25 qrcode-terminal import fixes, Bun/Playwright/WebSocket patches, and Docker Bun install. -- **Docs:** new FAQ/ClawHub/config examples/showcase entries and clarified auth, sandbox, and systemd docs. - -### Maintenance - -- Skills additions (Himalaya email, CodexBar, 1Password). -- Dependency refreshes (pi-\* stack, Slack SDK, discord-api-types, file-type, zod, Biome, Vite). - -## 2026.1.5 - -### Highlights - -- Models: add image-specific model config (`agent.imageModel` + fallbacks) and scan support. -- Agent tools: new `image` tool routed to the image model (when configured). -- Config: default model shorthands (`opus`, `sonnet`, `gpt`, `gpt-mini`, `gemini`, `gemini-flash`). -- Docs: document built-in model shorthands + precedence (user config wins). -- Bun: optional local install/build workflow without maintaining a Bun lockfile (see `docs/bun.md`). - -### Fixes - -- Control UI: render Markdown in tool result cards. -- Control UI: prevent overlapping action buttons in Discord guild rules on narrow layouts. -- Android: tapping the foreground service notification brings the app to the front. (#179) — thanks @Syhids -- Cron tool uses `id` for update/remove/run/runs (aligns with gateway params). (#180) — thanks @adamgall -- Control UI: chat view uses page scroll with sticky header/sidebar and fixed composer (no inner scroll frame). -- macOS: treat location permission as always-only to avoid iOS-only enums. (#165) — thanks @Nachx639 -- macOS: make generated gateway protocol models `Sendable` for Swift 6 strict concurrency. (#195) — thanks @andranik-sahakyan -- macOS: bundle QR code renderer modules so DMG gateway boot doesn't crash on missing qrcode-terminal vendor files. -- macOS: parse JSON5 config safely to avoid wiping user settings when comments are present. -- WhatsApp: suppress typing indicator during heartbeat background tasks. (#190) — thanks @mcinteerj -- WhatsApp: mark offline history sync messages as read without auto-reply. (#193) — thanks @mcinteerj -- Discord: avoid duplicate replies when a provider emits late streaming `text_end` events (OpenAI/GPT). -- CLI: use tailnet IP for local gateway calls when bind is tailnet/auto (fixes #176). -- Env: load global `$OPENCLAW_STATE_DIR/.env` (`~/.openclaw/.env`) as a fallback after CWD `.env`. -- Env: optional login-shell env fallback (opt-in; imports expected keys without overriding existing env). -- Agent tools: OpenAI-compatible tool JSON Schemas (fix `browser`, normalize union schemas). -- Onboarding: when running from source, auto-build missing Control UI assets (`bun run ui:build`). -- Discord/Slack: route reaction + system notifications to the correct session (no main-session bleed). -- Agent tools: honor `agent.tools` allow/deny policy even when sandbox is off. -- Discord: avoid duplicate replies when OpenAI emits repeated `message_end` events. -- Commands: unify /status (inline) and command auth across providers; group bypass for authorized control commands; remove Discord /clawd slash handler. -- CLI: run `openclaw agent` via the Gateway by default; use `--local` to force embedded mode. diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 120000 index c317064255..0000000000 --- a/CLAUDE.md +++ /dev/null @@ -1 +0,0 @@ -AGENTS.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index eddb13348e..0000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,141 +0,0 @@ -# Contributing to OpenClaw - -Welcome to the lobster tank! 🦞 - -## Quick Links - -- **GitHub:** https://github.com/openclaw/openclaw -- **Vision:** [`VISION.md`](VISION.md) -- **Discord:** https://discord.gg/qkhbAGHRBT -- **X/Twitter:** [@steipete](https://x.com/steipete) / [@openclaw](https://x.com/openclaw) - -## Maintainers - -- **Peter Steinberger** - Benevolent Dictator - - GitHub: [@steipete](https://github.com/steipete) · X: [@steipete](https://x.com/steipete) - -- **Shadow** - Discord subsystem, Discord admin, Clawhub, all community moderation - - GitHub: [@thewilloftheshadow](https://github.com/thewilloftheshadow) · X: [@4shad0wed](https://x.com/4shad0wed) - -- **Vignesh** - Memory (QMD), formal modeling, TUI, IRC, and Lobster - - GitHub: [@vignesh07](https://github.com/vignesh07) · X: [@\_vgnsh](https://x.com/_vgnsh) - -- **Jos** - Telegram, API, Nix mode - - GitHub: [@joshp123](https://github.com/joshp123) · X: [@jjpcodes](https://x.com/jjpcodes) - -- **Ayaan Zaidi** - Telegram subsystem, iOS app - - GitHub: [@obviyus](https://github.com/obviyus) · X: [@0bviyus](https://x.com/0bviyus) - -- **Tyler Yust** - Agents/subagents, cron, BlueBubbles, macOS app - - GitHub: [@tyler6204](https://github.com/tyler6204) · X: [@tyleryust](https://x.com/tyleryust) - -- **Mariano Belinky** - iOS app, Security - - GitHub: [@mbelinky](https://github.com/mbelinky) · X: [@belimad](https://x.com/belimad) - -- **Seb Slight** - Docs, Agent Reliability, Runtime Hardening - - GitHub: [@sebslight](https://github.com/sebslight) · X: [@sebslig](https://x.com/sebslig) - -- **Christoph Nakazawa** - JS Infra - - GitHub: [@cpojer](https://github.com/cpojer) · X: [@cnakazawa](https://x.com/cnakazawa) - -- **Gustavo Madeira Santana** - Multi-agents, CLI, web UI - - GitHub: [@gumadeiras](https://github.com/gumadeiras) · X: [@gumadeiras](https://x.com/gumadeiras) - -## How to Contribute - -1. **Bugs & small fixes** → Open a PR! -2. **New features / architecture** → Start a [GitHub Discussion](https://github.com/openclaw/openclaw/discussions) or ask in Discord first -3. **Questions** → Discord #setup-help - -## Before You PR - -- Test locally with your OpenClaw instance -- Run tests: `pnpm build && pnpm check && pnpm test` -- Ensure CI checks pass -- Keep PRs focused (one thing per PR; do not mix unrelated concerns) -- Describe what & why - -## Control UI Decorators - -The Control UI uses Lit with **legacy** decorators (current Rollup parsing does not support -`accessor` fields required for standard decorators). When adding reactive fields, keep the -legacy style: - -```ts -@state() foo = "bar"; -@property({ type: Number }) count = 0; -``` - -The root `tsconfig.json` is configured for legacy decorators (`experimentalDecorators: true`) -with `useDefineForClassFields: false`. Avoid flipping these unless you are also updating the UI -build tooling to support standard decorators. - -## AI/Vibe-Coded PRs Welcome! 🤖 - -Built with Codex, Claude, or other AI tools? **Awesome - just mark it!** - -Please include in your PR: - -- [ ] Mark as AI-assisted in the PR title or description -- [ ] Note the degree of testing (untested / lightly tested / fully tested) -- [ ] Include prompts or session logs if possible (super helpful!) -- [ ] Confirm you understand what the code does - -AI PRs are first-class citizens here. We just want transparency so reviewers know what to look for. - -## Current Focus & Roadmap 🗺 - -We are currently prioritizing: - -- **Stability**: Fixing edge cases in channel connections (WhatsApp/Telegram). -- **UX**: Improving the onboarding wizard and error messages. -- **Skills**: For skill contributions, head to [ClawHub](https://clawhub.ai/) — the community hub for OpenClaw skills. -- **Performance**: Optimizing token usage and compaction logic. - -Check the [GitHub Issues](https://github.com/openclaw/openclaw/issues) for "good first issue" labels! - -## Maintainers - -We're selectively expanding the maintainer team. -If you're an experienced contributor who wants to help shape OpenClaw's direction — whether through code, docs, or community — we'd like to hear from you. - -Being a maintainer is a responsibility, not an honorary title. We expect active, consistent involvement — triaging issues, reviewing PRs, and helping move the project forward. - -Still interested? Email contributing@openclaw.ai with: - -- Links to your PRs on OpenClaw (if you don't have any, start there first) -- Links to open source projects you maintain or actively contribute to -- Your GitHub, Discord, and X/Twitter handles -- A brief intro: background, experience, and areas of interest -- Languages you speak and where you're based -- How much time you can realistically commit - -We welcome people across all skill sets — engineering, documentation, community management, and more. -We review every human-only-written application carefully and add maintainers slowly and deliberately. -Please allow a few weeks for a response. - -## Report a Vulnerability - -We take security reports seriously. Report vulnerabilities directly to the repository where the issue lives: - -- **Core CLI and gateway** — [openclaw/openclaw](https://github.com/openclaw/openclaw) -- **macOS desktop app** — [openclaw/openclaw](https://github.com/openclaw/openclaw) (apps/macos) -- **iOS app** — [openclaw/openclaw](https://github.com/openclaw/openclaw) (apps/ios) -- **Android app** — [openclaw/openclaw](https://github.com/openclaw/openclaw) (apps/android) -- **ClawHub** — [openclaw/clawhub](https://github.com/openclaw/clawhub) -- **Trust and threat model** — [openclaw/trust](https://github.com/openclaw/trust) - -For issues that don't fit a specific repo, or if you're unsure, email **security@openclaw.ai** and we'll route it. - -### Required in Reports - -1. **Title** -2. **Severity Assessment** -3. **Impact** -4. **Affected Component** -5. **Technical Reproduction** -6. **Demonstrated Impact** -7. **Environment** -8. **Remediation Advice** - -Reports without reproduction steps, demonstrated impact, and remediation advice will be deprioritized. Given the volume of AI-generated scanner findings, we must ensure we're receiving vetted reports from researchers who understand the issues. diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 1b40c2da35..0000000000 --- a/Dockerfile +++ /dev/null @@ -1,61 +0,0 @@ -FROM node:22-bookworm@sha256:cd7bcd2e7a1e6f72052feb023c7f6b722205d3fcab7bbcbd2d1bfdab10b1e935 - -# Install Bun (required for build scripts) -RUN curl -fsSL https://bun.sh/install | bash -ENV PATH="/root/.bun/bin:${PATH}" - -RUN corepack enable - -WORKDIR /app - -ARG OPENCLAW_DOCKER_APT_PACKAGES="" -RUN if [ -n "$OPENCLAW_DOCKER_APT_PACKAGES" ]; then \ - apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends $OPENCLAW_DOCKER_APT_PACKAGES && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*; \ - fi - -COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./ -COPY ui/package.json ./ui/package.json -COPY patches ./patches -COPY scripts ./scripts - -RUN pnpm install --frozen-lockfile - -# Optionally install Chromium and Xvfb for browser automation. -# Build with: docker build --build-arg OPENCLAW_INSTALL_BROWSER=1 ... -# Adds ~300MB but eliminates the 60-90s Playwright install on every container start. -# Must run after pnpm install so playwright-core is available in node_modules. -ARG OPENCLAW_INSTALL_BROWSER="" -RUN if [ -n "$OPENCLAW_INSTALL_BROWSER" ]; then \ - apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends xvfb && \ - node /app/node_modules/playwright-core/cli.js install --with-deps chromium && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*; \ - fi - -COPY . . -RUN pnpm build -# Force pnpm for UI build (Bun may fail on ARM/Synology architectures) -ENV OPENCLAW_PREFER_PNPM=1 -RUN pnpm ui:build - -ENV NODE_ENV=production - -# Allow non-root user to write temp files during runtime/tests. -RUN chown -R node:node /app - -# Security hardening: Run as non-root user -# The node:22-bookworm image includes a 'node' user (uid 1000) -# This reduces the attack surface by preventing container escape via root privileges -USER node - -# Start gateway server with default config. -# Binds to loopback (127.0.0.1) by default for security. -# -# For container platforms requiring external health checks: -# 1. Set OPENCLAW_GATEWAY_TOKEN or OPENCLAW_GATEWAY_PASSWORD env var -# 2. Override CMD: ["node","openclaw.mjs","gateway","--allow-unconfigured","--bind","lan"] -CMD ["node", "openclaw.mjs", "gateway", "--allow-unconfigured"] diff --git a/Dockerfile.sandbox b/Dockerfile.sandbox deleted file mode 100644 index a463d4a102..0000000000 --- a/Dockerfile.sandbox +++ /dev/null @@ -1,20 +0,0 @@ -FROM debian:bookworm-slim@sha256:98f4b71de414932439ac6ac690d7060df1f27161073c5036a7553723881bffbe - -ENV DEBIAN_FRONTEND=noninteractive - -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - bash \ - ca-certificates \ - curl \ - git \ - jq \ - python3 \ - ripgrep \ - && rm -rf /var/lib/apt/lists/* - -RUN useradd --create-home --shell /bin/bash sandbox -USER sandbox -WORKDIR /home/sandbox - -CMD ["sleep", "infinity"] diff --git a/Dockerfile.sandbox-browser b/Dockerfile.sandbox-browser deleted file mode 100644 index ec9faf7111..0000000000 --- a/Dockerfile.sandbox-browser +++ /dev/null @@ -1,32 +0,0 @@ -FROM debian:bookworm-slim@sha256:98f4b71de414932439ac6ac690d7060df1f27161073c5036a7553723881bffbe - -ENV DEBIAN_FRONTEND=noninteractive - -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - bash \ - ca-certificates \ - chromium \ - curl \ - fonts-liberation \ - fonts-noto-color-emoji \ - git \ - jq \ - novnc \ - python3 \ - socat \ - websockify \ - x11vnc \ - xvfb \ - && rm -rf /var/lib/apt/lists/* - -COPY scripts/sandbox-browser-entrypoint.sh /usr/local/bin/openclaw-sandbox-browser -RUN chmod +x /usr/local/bin/openclaw-sandbox-browser - -RUN useradd --create-home --shell /bin/bash sandbox -USER sandbox -WORKDIR /home/sandbox - -EXPOSE 9222 5900 6080 - -CMD ["openclaw-sandbox-browser"] diff --git a/Dockerfile.sandbox-common b/Dockerfile.sandbox-common deleted file mode 100644 index 71f80070ad..0000000000 --- a/Dockerfile.sandbox-common +++ /dev/null @@ -1,45 +0,0 @@ -ARG BASE_IMAGE=openclaw-sandbox:bookworm-slim -FROM ${BASE_IMAGE} - -USER root - -ENV DEBIAN_FRONTEND=noninteractive - -ARG PACKAGES="curl wget jq coreutils grep nodejs npm python3 git ca-certificates golang-go rustc cargo unzip pkg-config libasound2-dev build-essential file" -ARG INSTALL_PNPM=1 -ARG INSTALL_BUN=1 -ARG BUN_INSTALL_DIR=/opt/bun -ARG INSTALL_BREW=1 -ARG BREW_INSTALL_DIR=/home/linuxbrew/.linuxbrew -ARG FINAL_USER=sandbox - -ENV BUN_INSTALL=${BUN_INSTALL_DIR} -ENV HOMEBREW_PREFIX=${BREW_INSTALL_DIR} -ENV HOMEBREW_CELLAR=${BREW_INSTALL_DIR}/Cellar -ENV HOMEBREW_REPOSITORY=${BREW_INSTALL_DIR}/Homebrew -ENV PATH=${BUN_INSTALL_DIR}/bin:${BREW_INSTALL_DIR}/bin:${BREW_INSTALL_DIR}/sbin:${PATH} - -RUN apt-get update \ - && apt-get install -y --no-install-recommends ${PACKAGES} \ - && rm -rf /var/lib/apt/lists/* - -RUN if [ "${INSTALL_PNPM}" = "1" ]; then npm install -g pnpm; fi - -RUN if [ "${INSTALL_BUN}" = "1" ]; then \ - curl -fsSL https://bun.sh/install | bash; \ - ln -sf "${BUN_INSTALL_DIR}/bin/bun" /usr/local/bin/bun; \ -fi - -RUN if [ "${INSTALL_BREW}" = "1" ]; then \ - if ! id -u linuxbrew >/dev/null 2>&1; then useradd -m -s /bin/bash linuxbrew; fi; \ - mkdir -p "${BREW_INSTALL_DIR}"; \ - chown -R linuxbrew:linuxbrew "$(dirname "${BREW_INSTALL_DIR}")"; \ - su - linuxbrew -c "NONINTERACTIVE=1 CI=1 /bin/bash -c '$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)'"; \ - if [ ! -e "${BREW_INSTALL_DIR}/Library" ]; then ln -s "${BREW_INSTALL_DIR}/Homebrew/Library" "${BREW_INSTALL_DIR}/Library"; fi; \ - if [ ! -x "${BREW_INSTALL_DIR}/bin/brew" ]; then echo \"brew install failed\"; exit 1; fi; \ - ln -sf "${BREW_INSTALL_DIR}/bin/brew" /usr/local/bin/brew; \ -fi - -# Default is sandbox, but allow BASE_IMAGE overrides to select another final user. -USER ${FINAL_USER} - diff --git a/INSTALLATION.md b/INSTALLATION.md new file mode 100644 index 0000000000..cba3f135f5 --- /dev/null +++ b/INSTALLATION.md @@ -0,0 +1,237 @@ +# 安装指南 + +## 📋 前置要求 + +### 必需软件 + +1. **Node.js** (v22.12 或更高版本) + ```bash + node --version + # 应该显示 v22.12.x 或更高 + ``` + +2. **npm** (通常随 Node.js 一起安装) + ```bash + npm --version + # 应该显示 8.x.x 或更高 + ``` + +3. **pnpm** (用于构建 Web UI) + ```bash + pnpm --version + # 如果未安装,可执行: + # corepack enable + # corepack prepare pnpm@latest --activate + ``` + +4. **Google Chrome** (用于调试浏览器) + - macOS: 已安装 + - Linux: `sudo apt install google-chrome-stable` + - Windows: 下载安装 + +### Shell 环境说明(Windows 用户必读) + +- `onboard.sh` / `server.sh` / `start-chrome-debug.sh` 需要在 **Bash 环境**运行。 +- Windows 推荐使用 **WSL**(优先)或 **Git Bash**。 +- 纯 `cmd.exe` / 原生 PowerShell 不能直接执行 `.sh` 脚本。 + +### 可选软件 + +- **Git** (用于克隆代码) + ```bash + git --version + ``` + +--- + +## 🚀 安装步骤 + +### 步骤 1:克隆或下载代码 + +**使用 Git**: +```bash +git clone +cd openclaw-zero-token +``` + +**或者直接下载**: +- 下载 ZIP 文件 +- 解压到目录 +- 进入目录 + +--- + +### 步骤 2:安装依赖 + +```bash +npm install +``` + +**预期输出**: +``` +added 500+ packages in 30s +``` + +**如果遇到错误**: +```bash +# 清理缓存 +npm cache clean --force + +# 删除 node_modules 和 package-lock.json +rm -rf node_modules package-lock.json + +# 重新安装 +npm install +``` + +--- + +### 步骤 3:编译代码 + +```bash +npm run build +pnpm ui:build # 构建 Web UI,访问 http://127.0.0.1:3001 时需要 +``` + +**预期输出**: +``` +✔ Build complete in 7919ms +✓ built in 1.13s # ui:build +``` + +**验证编译成功**: +```bash +ls dist/index.mjs +ls dist/control-ui/index.html # Web UI 资源 +# 应该看到文件存在 +``` + +--- + +### 步骤 4:验证安装 + +```bash +# 检查编译后的文件 +ls -lh dist/index.mjs + +# 应该看到类似输出: +# -rw-r--r-- 1 user staff 2.5M Feb 27 10:00 dist/index.mjs +``` + +--- + +## 🔧 配置环境 + +### 创建配置目录 + +配置目录会在首次运行时自动创建(推荐,不需要手动创建): + +```bash +./onboard.sh +``` + +### 检查配置文件 + +```bash +# 查看配置文件(如果存在) +cat .openclaw-zero-state/openclaw.json + +# 查看认证配置(如果存在) +cat .openclaw-zero-state/agents/main/agent/auth-profiles.json +``` + +> 关键规则:只有在 `./onboard.sh` 中完成配置的平台,才会被写入 `openclaw.json` 并出现在最终 `/models` 列表中。 + +--- + +## ✅ 安装完成检查清单 + +- [ ] Node.js 已安装(v22.12+) +- [ ] npm 已安装 +- [ ] pnpm 已安装 +- [ ] 依赖已安装(`npm install`) +- [ ] 代码已编译(`npm run build`) +- [ ] `dist/index.mjs` 文件存在 +- [ ] Google Chrome 已安装 + +--- + +## 🎯 下一步 + +安装完成后,继续阅读: + +1. **START_HERE.md** - 快速开始指南 +2. **TEST_STEPS.md** - 详细测试步骤 + +--- + +## 🔧 常见问题 + +### Q1: npm install 失败 + +**A**: 尝试以下方法: +```bash +# 使用国内镜像(如果在中国) +npm config set registry https://registry.npmmirror.com + +# 重新安装 +npm install +``` + +### Q2: npm run build 失败 + +**A**: 检查 Node.js 版本: +```bash +node --version +# 必须是 v22.12 或更高 + +# 如果版本太低,升级 Node.js +``` + +### Q3: 权限错误 + +**A**: 不要使用 sudo: +```bash +# 错误:sudo npm install +# 正确:npm install +``` + +### Q4: 磁盘空间不足 + +**A**: 检查磁盘空间: +```bash +df -h + +# node_modules 大约需要 500MB +# dist 大约需要 10MB +``` + +--- + +## 📚 相关命令 + +```bash +# 安装依赖 +npm install + +# 编译代码 +npm run build + +# 清理编译产物 +rm -rf dist + +# 重新编译 +npm run build + +# 查看 npm 脚本 +npm run + +# 检查依赖版本 +npm list --depth=0 +``` + +--- + +## 🎉 安装成功! + +现在你可以开始测试了。继续阅读 **START_HERE.md** 开始测试流程。 diff --git a/LICENSE b/LICENSE deleted file mode 100644 index f7b526698b..0000000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2025 Peter Steinberger - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md index fe96768c95..d6c76045c4 100644 --- a/README.md +++ b/README.md @@ -1,550 +1,583 @@ -# 🦞 OpenClaw — Personal AI Assistant +# OpenClaw Zero Token -

- - - OpenClaw - -

+**Zero API Token Cost** — Free access to AI models via browser-based authentication (ChatGPT, Claude, Gemini, DeepSeek, Qwen International & China, Doubao, Kimi, GLM, Grok, Manus, and more). -

- EXFOLIATE! EXFOLIATE! -

+[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -

- CI status - GitHub release - Discord - MIT License -

+[English](README.md) | [简体中文](README_zh-CN.md) -**OpenClaw** is a _personal AI assistant_ you run on your own devices. -It answers you on the channels you already use (WhatsApp, Telegram, Slack, Discord, Google Chat, Signal, iMessage, Microsoft Teams, WebChat), plus extension channels like BlueBubbles, Matrix, Zalo, and Zalo Personal. It can speak and listen on macOS/iOS/Android, and can render a live Canvas you control. The Gateway is just the control plane — the product is the assistant. +--- -If you want a personal, single-user assistant that feels local, fast, and always-on, this is it. +## Table of Contents -[Website](https://openclaw.ai) · [Docs](https://docs.openclaw.ai) · [Vision](VISION.md) · [DeepWiki](https://deepwiki.com/openclaw/openclaw) · [Getting Started](https://docs.openclaw.ai/start/getting-started) · [Updating](https://docs.openclaw.ai/install/updating) · [Showcase](https://docs.openclaw.ai/start/showcase) · [FAQ](https://docs.openclaw.ai/start/faq) · [Wizard](https://docs.openclaw.ai/start/wizard) · [Nix](https://github.com/openclaw/nix-openclaw) · [Docker](https://docs.openclaw.ai/install/docker) · [Discord](https://discord.gg/clawd) +- [Overview](#overview) +- [Quick Start](#quick-start) +- [System Architecture](#system-architecture) +- [How It Works](#how-it-works) +- [Roadmap](#roadmap) +- [Adding New Platforms](#adding-new-platforms) +- [File Structure](#file-structure) +- [Usage](#usage) +- [Configuration](#configuration) +- [Troubleshooting](#troubleshooting) +- [Security](#security) +- [Upstream Sync](#upstream-sync) +- [Contributing](#contributing) +- [License](#license) +- [Acknowledgments](#acknowledgments) +- [Disclaimer](#disclaimer) -Preferred setup: run the onboarding wizard (`openclaw onboard`) in your terminal. -The wizard guides you step by step through setting up the gateway, workspace, channels, and skills. The CLI wizard is the recommended path and works on **macOS, Linux, and Windows (via WSL2; strongly recommended)**. -Works with npm, pnpm, or bun. -New install? Start here: [Getting started](https://docs.openclaw.ai/start/getting-started) +--- -**Subscriptions (OAuth):** +## Overview -- **[Anthropic](https://www.anthropic.com/)** (Claude Pro/Max) -- **[OpenAI](https://openai.com/)** (ChatGPT/Codex) +OpenClaw Zero Token is a fork of [OpenClaw](https://github.com/openclaw/openclaw) with a core mission: **eliminate API token costs** by capturing session credentials through browser automation, enabling free access to major AI platforms. -Model note: while any model is supported, I strongly recommend **Anthropic Pro/Max (100/200) + Opus 4.6** for long‑context strength and better prompt‑injection resistance. See [Onboarding](https://docs.openclaw.ai/start/onboarding). +### Why Zero Token? -## Models (selection + auth) +| Traditional Approach | Zero Token Approach | +|---------------------|---------------------| +| Requires purchasing API tokens | **Completely free** | +| Pay per API call | No usage limits | +| Credit card binding required | Only web login needed | +| Potential token leakage | Credentials stored locally | -- Models config + CLI: [Models](https://docs.openclaw.ai/concepts/models) -- Auth profile rotation (OAuth vs API keys) + fallbacks: [Model failover](https://docs.openclaw.ai/concepts/model-failover) +### Supported Platforms -## Install (recommended) +| Platform | Status | Models | +|----------|--------|--------| +| DeepSeek | ✅ **Tested** | deepseek-chat, deepseek-reasoner | +| Qwen (International) | ✅ **Tested** | Qwen 3.5 Plus, Qwen 3.5 Turbo | +| Qwen (China) | ✅ **Tested** | Qwen 3.5 Plus, Qwen 3.5 Turbo | +| Kimi | ✅ **Tested** | Moonshot v1 8K, 32K, 128K | +| Claude Web | ✅ **Tested** | claude-sonnet-4-6, claude-opus-4-6, claude-haiku-4-6 | +| Doubao (豆包) | ✅ **Tested** | doubao-seed-2.0, doubao-pro | +| ChatGPT Web | ✅ **Tested** | GPT-4, GPT-4 Turbo | +| Gemini Web | ✅ **Tested** | Gemini Pro, Gemini Ultra | +| Grok Web | ✅ **Tested** | Grok 1, Grok 2 | +| GLM Web (智谱清言) | ✅ **Tested** | glm-4-Plus, glm-4-Think | +| GLM Web (International) | ✅ **Tested** | GLM-4 Plus, GLM-4 Think | +| Manus API | ✅ **Tested** | Manus 1.6, Manus 1.6 Lite (API key, free tier) | -Runtime: **Node ≥22**. +> **Qwen International vs China:** +> - **Qwen International** (chat.qwen.ai) — For global users, no VPN required +> - **Qwen China** (qianwen.com) — For China users, faster speed, more features (deep search, code assistant, image generation, etc.) -```bash -npm install -g openclaw@latest -# or: pnpm add -g openclaw@latest +> **Note:** All web-based providers use browser automation (Playwright) for authentication and API access. Platforms marked **Tested** have been verified to work. -openclaw onboard --install-daemon -``` +### Tool Calling (Local Tools) -The wizard installs the Gateway daemon (launchd/systemd user service) so it stays running. +All supported models can call **local tools** (e.g. exec, read_file, list_dir, browser, apply_patch) so the agent can run commands, read/write files in the workspace, and automate the browser. -## Quick start (TL;DR) +| Provider type | Tool support | Notes | +|---------------|--------------|--------| +| **Web (DeepSeek, Qwen, Kimi, Claude, Doubao, GLM, Grok)** | ✅ | XML-based tool instructions in system prompt; stream parser extracts `` and executes locally. | +| **ChatGPT Web / Gemini Web / Manus API** | ✅ | Same approach: tool instructions + multi-turn context + `` parsing (see [Tool Calling doc](docs/TOOL_CALLING_MODELS.md)). | +| **OpenRouter / OpenAI-compatible API** | ✅ | Native `tools` / `tool_calls` API. | +| **Ollama** | ✅ | Native `/api/chat` tools. | -Runtime: **Node ≥22**. +The agent’s file access is limited to the configured **workspace** directory (see `agents.defaults.workspace` in config). For details and verification steps, see **[docs/TOOL_CALLING_MODELS.md](docs/TOOL_CALLING_MODELS.md)**. -Full beginner guide (auth, pairing, channels): [Getting started](https://docs.openclaw.ai/start/getting-started) +### Additional Features -```bash -openclaw onboard --install-daemon +**Ask once, get answers from all AI models.** — AskOnce lets you query multiple configured AI models at once and compare their responses in a single view. -openclaw gateway --port 18789 --verbose +![AskOnce - Ask once, get answers from all AI models](askonce.png) -# Send a message -openclaw message send --to +1234567890 --message "Hello from OpenClaw" +### Setup Steps (6 Steps) -# Talk to the assistant (optionally deliver back to any connected channel: WhatsApp/Telegram/Slack/Discord/Google Chat/Signal/iMessage/BlueBubbles/Microsoft Teams/Matrix/Zalo/Zalo Personal/WebChat) -openclaw agent --message "Ship checklist" --thinking high -``` +```bash +# 1. Build +pnpm install && pnpm build && pnpm ui:build -Upgrading? [Updating guide](https://docs.openclaw.ai/install/updating) (and run `openclaw doctor`). +# 2. Open browser debug +./start-chrome-debug.sh -## Development channels +# 3. Login to platforms (Qwen, Kimi, Claude, etc. — exclude DeepSeek) +# 4. Configure onboard +./onboard.sh -- **stable**: tagged releases (`vYYYY.M.D` or `vYYYY.M.D-`), npm dist-tag `latest`. -- **beta**: prerelease tags (`vYYYY.M.D-beta.N`), npm dist-tag `beta` (macOS app may be missing). -- **dev**: moving head of `main`, npm dist-tag `dev` (when published). +# 5. Login DeepSeek (Chrome + onboard select deepseek-web) +# 6. Start server +./server.sh start +``` -Switch channels (git + npm): `openclaw update --channel stable|beta|dev`. -Details: [Development channels](https://docs.openclaw.ai/install/development-channels). +> **Important:** Only platforms completed in `./onboard.sh` are written into `openclaw.json` and shown in `/models`. -## From source (development) +> **Platform support:** +> - **macOS / Linux:** Follow [START_HERE.md](START_HERE.md) for the step-by-step flow; see [INSTALLATION.md](INSTALLATION.md) for detailed setup. Run `./check-setup.sh` (on macOS you can also use `./check-mac-setup.sh`). +> - **Windows:** Use WSL2, then follow the Linux flow ([START_HERE.md](START_HERE.md), [INSTALLATION.md](INSTALLATION.md)). Install WSL2: `wsl --install`; guide: https://docs.microsoft.com/en-us/windows/wsl/install. -Prefer `pnpm` for builds from source. Bun is optional for running TypeScript directly. +See **START_HERE.md**, **INSTALLATION.md**, and **TEST_STEPS.md** for details. -```bash -git clone https://github.com/openclaw/openclaw.git -cd openclaw +### Notes -pnpm install -pnpm ui:build # auto-installs UI deps on first run -pnpm build +- **Session validity**: Sessions may expire periodically; re-login when needed +- **Browser dependency**: Chrome must run in debug mode +- **Compliance**: For personal learning and research only; use official APIs for commercial use -pnpm openclaw onboard --install-daemon +--- -# Dev loop (auto-reload on TS changes) -pnpm gateway:watch -``` +## Quick Start -Note: `pnpm openclaw ...` runs TypeScript directly (via `tsx`). `pnpm build` produces `dist/` for running via Node / the packaged `openclaw` binary. +> **Platform support:** +> +> - 🍎 **macOS** / 🐧 **Linux**: Follow [START_HERE.md](START_HERE.md) for step-by-step flow; see [INSTALLATION.md](INSTALLATION.md) for detailed setup. +> - 🪟 **Windows**: Use WSL2, then follow the Linux flow ([START_HERE.md](START_HERE.md), [INSTALLATION.md](INSTALLATION.md)). Install WSL2: `wsl --install`; guide: https://docs.microsoft.com/en-us/windows/wsl/install -## Security defaults (DM access) +### Environment Requirements -OpenClaw connects to real messaging surfaces. Treat inbound DMs as **untrusted input**. +- Node.js >= 22.12.0 +- pnpm >= 9.0.0 +- Chrome browser +- **OS**: macOS, Linux, or Windows (WSL2) -Full security guide: [Security](https://docs.openclaw.ai/gateway/security) +### Script Overview -Default behavior on Telegram/WhatsApp/Signal/iMessage/Microsoft Teams/Discord/Google Chat/Slack: +The project provides several helper scripts for different scenarios: -- **DM pairing** (`dmPolicy="pairing"` / `channels.discord.dmPolicy="pairing"` / `channels.slack.dmPolicy="pairing"`; legacy: `channels.discord.dm.policy`, `channels.slack.dm.policy`): unknown senders receive a short pairing code and the bot does not process their message. -- Approve with: `openclaw pairing approve ` (then the sender is added to a local allowlist store). -- Public inbound DMs require an explicit opt-in: set `dmPolicy="open"` and include `"*"` in the channel allowlist (`allowFrom` / `channels.discord.allowFrom` / `channels.slack.allowFrom`; legacy: `channels.discord.dm.allowFrom`, `channels.slack.dm.allowFrom`). +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ Script Flow Diagram │ +├─────────────────────────────────────────────────────────────────────┤ +│ │ +│ First-time setup: │ +│ ┌──────────────────────────────────────────────────────────────┐ │ +│ │ 1. Build pnpm install && pnpm build && pnpm ui:build │ │ +│ │ 2. Open browser debug ./start-chrome-debug.sh │ │ +│ │ 3. Login to platforms Qwen, Kimi, Claude, etc. (excl. DeepSeek) │ │ +│ │ 4. Configure onboard ./onboard.sh │ │ +│ │ 5. Login DeepSeek Chrome + onboard select deepseek-web │ │ +│ │ 6. Start server ./server.sh start │ │ +│ └──────────────────────────────────────────────────────────────┘ │ +│ │ +│ Daily use: │ +│ ┌──────────────────────────────────────────────────────────────┐ │ +│ │ start-chrome-debug.sh → onboard.sh → server.sh start │ │ +│ │ server.sh [start|stop|restart|status] Manage Gateway │ │ +│ └──────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────┘ +``` -Run `openclaw doctor` to surface risky/misconfigured DM policies. +**Core scripts (3):** -## Highlights +| Script | Purpose | When to use | +|--------|---------|-------------| +| `start-chrome-debug.sh` | Launch Chrome in debug mode | Step 2: Opens browser on port 9222 for platform login and onboard connection | +| `onboard.sh` | Auth configuration wizard | Steps 4–5: Select platform (deepseek-web, etc.), capture Cookie/Token | +| `server.sh` | Manage Gateway service | Step 6 and daily: `start` / `stop` / `restart` / `status`, port 3001 | -- **[Local-first Gateway](https://docs.openclaw.ai/gateway)** — single control plane for sessions, channels, tools, and events. -- **[Multi-channel inbox](https://docs.openclaw.ai/channels)** — WhatsApp, Telegram, Slack, Discord, Google Chat, Signal, BlueBubbles (iMessage), iMessage (legacy), Microsoft Teams, Matrix, Zalo, Zalo Personal, WebChat, macOS, iOS/Android. -- **[Multi-agent routing](https://docs.openclaw.ai/gateway/configuration)** — route inbound channels/accounts/peers to isolated agents (workspaces + per-agent sessions). -- **[Voice Wake](https://docs.openclaw.ai/nodes/voicewake) + [Talk Mode](https://docs.openclaw.ai/nodes/talk)** — always-on speech for macOS/iOS/Android with ElevenLabs. -- **[Live Canvas](https://docs.openclaw.ai/platforms/mac/canvas)** — agent-driven visual workspace with [A2UI](https://docs.openclaw.ai/platforms/mac/canvas#canvas-a2ui). -- **[First-class tools](https://docs.openclaw.ai/tools)** — browser, canvas, nodes, cron, sessions, and Discord/Slack actions. -- **[Companion apps](https://docs.openclaw.ai/platforms/macos)** — macOS menu bar app + iOS/Android [nodes](https://docs.openclaw.ai/nodes). -- **[Onboarding](https://docs.openclaw.ai/start/wizard) + [skills](https://docs.openclaw.ai/tools/skills)** — wizard-driven setup with bundled/managed/workspace skills. +### Installation -## Star History +```bash +# Clone repo +git clone https://github.com/linuxhsj/openclaw-zero-token.git +cd openclaw-zero-token -[![Star History Chart](https://api.star-history.com/svg?repos=openclaw/openclaw&type=date&legend=top-left)](https://www.star-history.com/#openclaw/openclaw&type=date&legend=top-left) +# Install dependencies +pnpm install +``` -## Everything we built so far +### Startup -### Core platform +#### Step 1: Build -- [Gateway WS control plane](https://docs.openclaw.ai/gateway) with sessions, presence, config, cron, webhooks, [Control UI](https://docs.openclaw.ai/web), and [Canvas host](https://docs.openclaw.ai/platforms/mac/canvas#canvas-a2ui). -- [CLI surface](https://docs.openclaw.ai/tools/agent-send): gateway, agent, send, [wizard](https://docs.openclaw.ai/start/wizard), and [doctor](https://docs.openclaw.ai/gateway/doctor). -- [Pi agent runtime](https://docs.openclaw.ai/concepts/agent) in RPC mode with tool streaming and block streaming. -- [Session model](https://docs.openclaw.ai/concepts/session): `main` for direct chats, group isolation, activation modes, queue modes, reply-back. Group rules: [Groups](https://docs.openclaw.ai/concepts/groups). -- [Media pipeline](https://docs.openclaw.ai/nodes/images): images/audio/video, transcription hooks, size caps, temp file lifecycle. Audio details: [Audio](https://docs.openclaw.ai/nodes/audio). +```bash +pnpm build +pnpm ui:build # Build Web UI (required for http://127.0.0.1:3001) +``` -### Channels +#### Step 2: Configure Auth -- [Channels](https://docs.openclaw.ai/channels): [WhatsApp](https://docs.openclaw.ai/channels/whatsapp) (Baileys), [Telegram](https://docs.openclaw.ai/channels/telegram) (grammY), [Slack](https://docs.openclaw.ai/channels/slack) (Bolt), [Discord](https://docs.openclaw.ai/channels/discord) (discord.js), [Google Chat](https://docs.openclaw.ai/channels/googlechat) (Chat API), [Signal](https://docs.openclaw.ai/channels/signal) (signal-cli), [BlueBubbles](https://docs.openclaw.ai/channels/bluebubbles) (iMessage, recommended), [iMessage](https://docs.openclaw.ai/channels/imessage) (legacy imsg), [Microsoft Teams](https://docs.openclaw.ai/channels/msteams) (extension), [Matrix](https://docs.openclaw.ai/channels/matrix) (extension), [Zalo](https://docs.openclaw.ai/channels/zalo) (extension), [Zalo Personal](https://docs.openclaw.ai/channels/zalouser) (extension), [WebChat](https://docs.openclaw.ai/web/webchat). -- [Group routing](https://docs.openclaw.ai/concepts/group-messages): mention gating, reply tags, per-channel chunking and routing. Channel rules: [Channels](https://docs.openclaw.ai/channels). +```bash +# First: launch Chrome debug mode and login to platforms in the browser +./start-chrome-debug.sh +# Then visit and login: Qwen, Kimi, Claude, Doubao, ChatGPT, Gemini, Grok, GLM, etc. -### Apps + nodes +# Run config wizard (onboard or server will copy from .openclaw-state.example if config is missing) +./onboard.sh -- [macOS app](https://docs.openclaw.ai/platforms/macos): menu bar control plane, [Voice Wake](https://docs.openclaw.ai/nodes/voicewake)/PTT, [Talk Mode](https://docs.openclaw.ai/nodes/talk) overlay, [WebChat](https://docs.openclaw.ai/web/webchat), debug tools, [remote gateway](https://docs.openclaw.ai/gateway/remote) control. -- [iOS node](https://docs.openclaw.ai/platforms/ios): [Canvas](https://docs.openclaw.ai/platforms/mac/canvas), [Voice Wake](https://docs.openclaw.ai/nodes/voicewake), [Talk Mode](https://docs.openclaw.ai/nodes/talk), camera, screen recording, Bonjour pairing. -- [Android node](https://docs.openclaw.ai/platforms/android): [Canvas](https://docs.openclaw.ai/platforms/mac/canvas), [Talk Mode](https://docs.openclaw.ai/nodes/talk), camera, screen recording, optional SMS. -- [macOS node mode](https://docs.openclaw.ai/nodes): system.run/notify + canvas/camera exposure. +# Or use built version +node openclaw.mjs onboard -### Tools + automation +# Select auth provider +? Auth provider: DeepSeek (Browser Login) -- [Browser control](https://docs.openclaw.ai/tools/browser): dedicated openclaw Chrome/Chromium, snapshots, actions, uploads, profiles. -- [Canvas](https://docs.openclaw.ai/platforms/mac/canvas): [A2UI](https://docs.openclaw.ai/platforms/mac/canvas#canvas-a2ui) push/reset, eval, snapshot. -- [Nodes](https://docs.openclaw.ai/nodes): camera snap/clip, screen record, [location.get](https://docs.openclaw.ai/nodes/location-command), notifications. -- [Cron + wakeups](https://docs.openclaw.ai/automation/cron-jobs); [webhooks](https://docs.openclaw.ai/automation/webhook); [Gmail Pub/Sub](https://docs.openclaw.ai/automation/gmail-pubsub). -- [Skills platform](https://docs.openclaw.ai/tools/skills): bundled, managed, and workspace skills with install gating + UI. +# Select login mode +? DeepSeek Auth Mode: + > Automated Login (Recommended) # Auto-capture credentials -### Runtime + safety +# Once you see auth success, you're done. To add more models, run ./onboard.sh again. +``` -- [Channel routing](https://docs.openclaw.ai/concepts/channel-routing), [retry policy](https://docs.openclaw.ai/concepts/retry), and [streaming/chunking](https://docs.openclaw.ai/concepts/streaming). -- [Presence](https://docs.openclaw.ai/concepts/presence), [typing indicators](https://docs.openclaw.ai/concepts/typing-indicators), and [usage tracking](https://docs.openclaw.ai/concepts/usage-tracking). -- [Models](https://docs.openclaw.ai/concepts/models), [model failover](https://docs.openclaw.ai/concepts/model-failover), and [session pruning](https://docs.openclaw.ai/concepts/session-pruning). -- [Security](https://docs.openclaw.ai/gateway/security) and [troubleshooting](https://docs.openclaw.ai/channels/troubleshooting). +#### Step 3: Start Gateway -### Ops + packaging +```bash +# Use helper script (recommended) +./server.sh start +``` -- [Control UI](https://docs.openclaw.ai/web) + [WebChat](https://docs.openclaw.ai/web/webchat) served directly from the Gateway. -- [Tailscale Serve/Funnel](https://docs.openclaw.ai/gateway/tailscale) or [SSH tunnels](https://docs.openclaw.ai/gateway/remote) with token/password auth. -- [Nix mode](https://docs.openclaw.ai/install/nix) for declarative config; [Docker](https://docs.openclaw.ai/install/docker)-based installs. -- [Doctor](https://docs.openclaw.ai/gateway/doctor) migrations, [logging](https://docs.openclaw.ai/logging). +--- -## How it works (short) +## System Architecture ``` -WhatsApp / Telegram / Slack / Discord / Google Chat / Signal / iMessage / BlueBubbles / Microsoft Teams / Matrix / Zalo / Zalo Personal / WebChat - │ - ▼ -┌───────────────────────────────┐ -│ Gateway │ -│ (control plane) │ -│ ws://127.0.0.1:18789 │ -└──────────────┬────────────────┘ - │ - ├─ Pi agent (RPC) - ├─ CLI (openclaw …) - ├─ WebChat UI - ├─ macOS app - └─ iOS / Android nodes +┌─────────────────────────────────────────────────────────────────────────────┐ +│ OpenClaw Zero Token │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ +│ │ Web UI │ │ CLI/TUI │ │ Gateway │ │ Channels │ │ +│ │ (Lit 3.x) │ │ │ │ (Port API) │ │ (Telegram…) │ │ +│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ +│ │ │ │ │ │ +│ └──────────────────┴──────────────────┴──────────────────┘ │ +│ │ │ +│ ┌────────▼────────┐ │ +│ │ Agent Core │ │ +│ │ (PI-AI Engine) │ │ +│ └────────┬────────┘ │ +│ │ │ +│ ┌───────────────────────────────────────────────────────────────────────┐ │ +│ │ Provider Layer │ │ +│ │ DeepSeek Web (Zero Token) ✅ │ │ +│ │ Qwen Web Int'l/CN (Zero Token) ✅ │ │ +│ │ Kimi (Zero Token) ✅ │ │ +│ │ Claude Web (Zero Token) ✅ │ │ +│ │ Doubao (Zero Token) ✅ │ │ +│ │ ChatGPT Web (Zero Token) ✅ │ │ +│ │ Gemini Web (Zero Token) ✅ │ │ +│ │ Grok Web (Zero Token) ✅ │ │ +│ │ GLM Web (Zero Token) ✅ │ │ +│ │ Manus API (Token) ✅ │ │ +│ └───────────────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────────┘ ``` -## Key subsystems +--- -- **[Gateway WebSocket network](https://docs.openclaw.ai/concepts/architecture)** — single WS control plane for clients, tools, and events (plus ops: [Gateway runbook](https://docs.openclaw.ai/gateway)). -- **[Tailscale exposure](https://docs.openclaw.ai/gateway/tailscale)** — Serve/Funnel for the Gateway dashboard + WS (remote access: [Remote](https://docs.openclaw.ai/gateway/remote)). -- **[Browser control](https://docs.openclaw.ai/tools/browser)** — openclaw‑managed Chrome/Chromium with CDP control. -- **[Canvas + A2UI](https://docs.openclaw.ai/platforms/mac/canvas)** — agent‑driven visual workspace (A2UI host: [Canvas/A2UI](https://docs.openclaw.ai/platforms/mac/canvas#canvas-a2ui)). -- **[Voice Wake](https://docs.openclaw.ai/nodes/voicewake) + [Talk Mode](https://docs.openclaw.ai/nodes/talk)** — always‑on speech and continuous conversation. -- **[Nodes](https://docs.openclaw.ai/nodes)** — Canvas, camera snap/clip, screen record, `location.get`, notifications, plus macOS‑only `system.run`/`system.notify`. +## How It Works -## Tailscale access (Gateway dashboard) +### Zero Token Authentication Flow -OpenClaw can auto-configure Tailscale **Serve** (tailnet-only) or **Funnel** (public) while the Gateway stays bound to loopback. Configure `gateway.tailscale.mode`: +``` +┌────────────────────────────────────────────────────────────────────────────┐ +│ DeepSeek Web Authentication Flow │ +├────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ 1. Launch Browser │ +│ ┌─────────────┐ │ +│ │ openclaw │ ──start──▶ Chrome (CDP Port: 18892) │ +│ │ gateway │ with user data directory │ +│ └─────────────┘ │ +│ │ +│ 2. User Login │ +│ ┌─────────────┐ │ +│ │ User logs in│ ──visit──▶ https://chat.deepseek.com │ +│ │ browser │ scan QR / password login │ +│ └─────────────┘ │ +│ │ +│ 3. Capture Credentials │ +│ ┌─────────────┐ │ +│ │ Playwright │ ──listen──▶ Network requests │ +│ │ CDP Connect │ Intercept Authorization Header │ +│ └─────────────┘ Extract Cookies │ +│ │ +│ 4. Store Credentials │ +│ ┌─────────────┐ │ +│ │ auth.json │ ◀──save── { cookie, bearer, userAgent } │ +│ └─────────────┘ │ +│ │ +│ 5. API Calls │ +│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ +│ │ DeepSeek │ ──▶ │ DeepSeek │ ──▶ │ chat.deep- │ │ +│ │ WebClient │ │ Web API │ │ seek.com │ │ +│ └─────────────┘ └─────────────┘ └─────────────┘ │ +│ Using stored Cookie + Bearer Token │ +│ │ +└────────────────────────────────────────────────────────────────────────────┘ +``` -- `off`: no Tailscale automation (default). -- `serve`: tailnet-only HTTPS via `tailscale serve` (uses Tailscale identity headers by default). -- `funnel`: public HTTPS via `tailscale funnel` (requires shared password auth). +### Key Technical Components -Notes: +| Component | Implementation | +|-----------|----------------| +| **Browser Automation** | Playwright CDP connection to Chrome | +| **Credential Capture** | Network request interception, Authorization Header extraction | +| **PoW Challenge** | WASM SHA3 computation for anti-bot bypass | +| **Streaming Response** | SSE parsing + custom tag parser | -- `gateway.bind` must stay `loopback` when Serve/Funnel is enabled (OpenClaw enforces this). -- Serve can be forced to require a password by setting `gateway.auth.mode: "password"` or `gateway.auth.allowTailscale: false`. -- Funnel refuses to start unless `gateway.auth.mode: "password"` is set. -- Optional: `gateway.tailscale.resetOnExit` to undo Serve/Funnel on shutdown. +--- -Details: [Tailscale guide](https://docs.openclaw.ai/gateway/tailscale) · [Web surfaces](https://docs.openclaw.ai/web) +## Roadmap -## Remote Gateway (Linux is great) +### Current Focus +- ✅ DeepSeek Web, Qwen International, Qwen CN, Kimi, Claude Web, Doubao, ChatGPT Web, Gemini Web, Grok Web, GLM Web, GLM International, Manus API — all **tested and working** +- 🔧 Improving credential capture reliability +- 📝 Documentation improvements -It’s perfectly fine to run the Gateway on a small Linux instance. Clients (macOS app, CLI, WebChat) can connect over **Tailscale Serve/Funnel** or **SSH tunnels**, and you can still pair device nodes (macOS/iOS/Android) to execute device‑local actions when needed. +### Planned Features +- 🔜 Auto-refresh for expired sessions -- **Gateway host** runs the exec tool and channel connections by default. -- **Device nodes** run device‑local actions (`system.run`, camera, screen recording, notifications) via `node.invoke`. - In short: exec runs where the Gateway lives; device actions run where the device lives. +--- -Details: [Remote access](https://docs.openclaw.ai/gateway/remote) · [Nodes](https://docs.openclaw.ai/nodes) · [Security](https://docs.openclaw.ai/gateway/security) +## Adding New Platforms -## macOS permissions via the Gateway protocol +To add support for a new platform, create the following files: -The macOS app can run in **node mode** and advertises its capabilities + permission map over the Gateway WebSocket (`node.list` / `node.describe`). Clients can then execute local actions via `node.invoke`: +### 1. Authentication Module (`src/providers/{platform}-web-auth.ts`) -- `system.run` runs a local command and returns stdout/stderr/exit code; set `needsScreenRecording: true` to require screen-recording permission (otherwise you’ll get `PERMISSION_MISSING`). -- `system.notify` posts a user notification and fails if notifications are denied. -- `canvas.*`, `camera.*`, `screen.record`, and `location.get` are also routed via `node.invoke` and follow TCC permission status. +```typescript +export async function loginPlatformWeb(params: { + onProgress: (msg: string) => void; + openUrl: (url: string) => Promise; +}): Promise<{ cookie: string; bearer: string; userAgent: string }> { + // Browser automation login, capture credentials +} +``` -Elevated bash (host permissions) is separate from macOS TCC: +### 2. API Client (`src/providers/{platform}-web-client.ts`) -- Use `/elevated on|off` to toggle per‑session elevated access when enabled + allowlisted. -- Gateway persists the per‑session toggle via `sessions.patch` (WS method) alongside `thinkingLevel`, `verboseLevel`, `model`, `sendPolicy`, and `groupActivation`. +```typescript +export class PlatformWebClient { + constructor(options: { cookie: string; bearer?: string }) {} + + async chatCompletions(params: ChatParams): Promise { + // Call platform Web API + } +} +``` -Details: [Nodes](https://docs.openclaw.ai/nodes) · [macOS app](https://docs.openclaw.ai/platforms/macos) · [Gateway protocol](https://docs.openclaw.ai/concepts/architecture) +### 3. Stream Handler (`src/agents/{platform}-web-stream.ts`) -## Agent to Agent (sessions\_\* tools) +```typescript +export function createPlatformWebStreamFn(credentials: string): StreamFn { + // Handle platform-specific response format +} +``` -- Use these to coordinate work across sessions without jumping between chat surfaces. -- `sessions_list` — discover active sessions (agents) and their metadata. -- `sessions_history` — fetch transcript logs for a session. -- `sessions_send` — message another session; optional reply‑back ping‑pong + announce step (`REPLY_SKIP`, `ANNOUNCE_SKIP`). +--- -Details: [Session tools](https://docs.openclaw.ai/concepts/session-tool) +## File Structure -## Skills registry (ClawHub) +``` +openclaw-zero-token/ +├── src/ +│ ├── providers/ # Web auth & API clients +│ │ ├── *-web-auth.ts # Platform login & credential capture +│ │ └── *-web-client.ts # Platform API client +│ ├── agents/ # Stream handlers +│ │ └── *-web-stream.ts # Platform response parsing +│ ├── commands/ # Auth flows (auth-choice.apply.*.ts) +│ └── browser/ # Chrome automation (chrome.ts) +├── ui/ # Web UI (Lit 3.x) +├── .openclaw-zero-state/ # Local state (not committed) +│ ├── openclaw.json # Config +│ └── agents/main/agent/ +│ └── auth.json # Credentials (sensitive) +└── .gitignore # Includes .openclaw-zero-state/ +``` -ClawHub is a minimal skill registry. With ClawHub enabled, the agent can search for skills automatically and pull in new ones as needed. +--- -[ClawHub](https://clawhub.com) +## Usage -## Chat commands +### Web UI -Send these in WhatsApp/Telegram/Slack/Google Chat/Microsoft Teams/WebChat (group commands are owner-only): +After running `./server.sh start`, the Web UI starts automatically. Use AI models directly in the chat interface. You can also open the chat directly at `http://127.0.0.1:3001/chat?session=`. -- `/status` — compact session status (model + tokens, cost when available) -- `/new` or `/reset` — reset the session -- `/compact` — compact session context (summary) -- `/think ` — off|minimal|low|medium|high|xhigh (GPT-5.2 + Codex models only) -- `/verbose on|off` -- `/usage off|tokens|full` — per-response usage footer -- `/restart` — restart the gateway (owner-only in groups) -- `/activation mention|always` — group activation toggle (groups only) +#### Switching Models -## Apps (optional) +Use the `/model` command in the chat interface to switch AI models: -The Gateway alone delivers a great experience. All apps are optional and add extra features. +```bash +/model claude-web +/model doubao-web +/model deepseek-web + +# Or specify a concrete model +/model claude-web/claude-sonnet-4-6 +/model doubao-web/doubao-seed-2.0 +/model deepseek-web/deepseek-chat +``` -If you plan to build/run companion apps, follow the platform runbooks below. +#### List Available Models -### macOS (OpenClaw.app) (optional) +Use `/models` to see all configured models: -- Menu bar control for the Gateway and health. -- Voice Wake + push-to-talk overlay. -- WebChat + debug tools. -- Remote gateway control over SSH. +```bash +/models +``` -Note: signed builds required for macOS permissions to stick across rebuilds (see `docs/mac/permissions.md`). +> **Rule:** Only platforms completed in `./onboard.sh` are written to `openclaw.json` and shown in `/models`. -### iOS node (optional) +This displays: -- Pairs as a node via the Bridge. -- Voice trigger forwarding + Canvas surface. -- Controlled via `openclaw nodes …`. +- All available providers (claude-web, doubao-web, deepseek-web, etc.) +- Model list under each provider +- Currently active model +- Model aliases and config info -Runbook: [iOS connect](https://docs.openclaw.ai/platforms/ios). +**Example output:** -### Android node (optional) +``` +Model Input Ctx Local Auth Tags +doubao-web/doubao-seed-2.0 text 63k no no default,configured,alias:Doubao Browser +claude-web/claude-sonnet-4-6 text+image 195k no no configured,alias:Claude Web +deepseek-web/deepseek-chat text 64k no no configured +``` -- Pairs via the same Bridge + pairing flow as iOS. -- Exposes Canvas, Camera, and Screen capture commands. -- Runbook: [Android connect](https://docs.openclaw.ai/platforms/android). +### API -## Agent workspace + skills +```bash +curl http://127.0.0.1:3001/v1/chat/completions \ + -H "Authorization: Bearer YOUR_GATEWAY_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "model": "deepseek-web/deepseek-chat", + "messages": [{"role": "user", "content": "Hello!"}] + }' +``` + +### CLI -- Workspace root: `~/.openclaw/workspace` (configurable via `agents.defaults.workspace`). -- Injected prompt files: `AGENTS.md`, `SOUL.md`, `TOOLS.md`. -- Skills: `~/.openclaw/workspace/skills//SKILL.md`. +```bash +node openclaw.mjs tui +``` + +--- ## Configuration -Minimal `~/.openclaw/openclaw.json` (model + defaults): +### openclaw.json -```json5 +```json { - agent: { - model: "anthropic/claude-opus-4-6", + "auth": { + "profiles": { + "deepseek-web:default": { + "provider": "deepseek-web", + "mode": "api_key" + } + } + }, + "models": { + "providers": { + "deepseek-web": { + "baseUrl": "https://chat.deepseek.com", + "api": "deepseek-web", + "models": [ + { + "id": "deepseek-chat", + "name": "DeepSeek Chat", + "contextWindow": 64000, + "maxTokens": 4096 + }, + { + "id": "deepseek-reasoner", + "name": "DeepSeek Reasoner", + "reasoning": true, + "contextWindow": 64000, + "maxTokens": 8192 + } + ] + } + } }, + "gateway": { + "port": 3001, + "auth": { + "mode": "token", + "token": "your-gateway-token" + } + } } ``` -[Full configuration reference (all keys + examples).](https://docs.openclaw.ai/gateway/configuration) +--- -## Security model (important) +## Troubleshooting -- **Default:** tools run on the host for the **main** session, so the agent has full access when it’s just you. -- **Group/channel safety:** set `agents.defaults.sandbox.mode: "non-main"` to run **non‑main sessions** (groups/channels) inside per‑session Docker sandboxes; bash then runs in Docker for those sessions. -- **Sandbox defaults:** allowlist `bash`, `process`, `read`, `write`, `edit`, `sessions_list`, `sessions_history`, `sessions_send`, `sessions_spawn`; denylist `browser`, `canvas`, `nodes`, `cron`, `discord`, `gateway`. +### First Run: Use Config Wizard (Recommended) -Details: [Security guide](https://docs.openclaw.ai/gateway/security) · [Docker + sandboxing](https://docs.openclaw.ai/install/docker) · [Sandbox config](https://docs.openclaw.ai/gateway/configuration) - -### [WhatsApp](https://docs.openclaw.ai/channels/whatsapp) +```bash +./onboard.sh +``` -- Link the device: `pnpm openclaw channels login` (stores creds in `~/.openclaw/credentials`). -- Allowlist who can talk to the assistant via `channels.whatsapp.allowFrom`. -- If `channels.whatsapp.groups` is set, it becomes a group allowlist; include `"*"` to allow all. +The wizard creates all required files and directories. -### [Telegram](https://docs.openclaw.ai/channels/telegram) +### Fix Issues: Use Doctor Command -- Set `TELEGRAM_BOT_TOKEN` or `channels.telegram.botToken` (env wins). -- Optional: set `channels.telegram.groups` (with `channels.telegram.groups."*".requireMention`); when set, it is a group allowlist (include `"*"` to allow all). Also `channels.telegram.allowFrom` or `channels.telegram.webhookUrl` + `channels.telegram.webhookSecret` as needed. +If the project has run before but you hit missing directories or files: -```json5 -{ - channels: { - telegram: { - botToken: "123456:ABCDEF", - }, - }, -} +```bash +node dist/index.mjs doctor ``` -### [Slack](https://docs.openclaw.ai/channels/slack) +The doctor command will: -- Set `SLACK_BOT_TOKEN` + `SLACK_APP_TOKEN` (or `channels.slack.botToken` + `channels.slack.appToken`). +- ✅ Check required directories +- ✅ Create missing directories +- ✅ Fix file permissions +- ✅ Validate config integrity +- ✅ Detect state directory conflicts +- ✅ Provide repair suggestions -### [Discord](https://docs.openclaw.ai/channels/discord) +**Limitations:** -- Set `DISCORD_BOT_TOKEN` or `channels.discord.token` (env wins). -- Optional: set `commands.native`, `commands.text`, or `commands.useAccessGroups`, plus `channels.discord.allowFrom`, `channels.discord.guilds`, or `channels.discord.mediaMaxMb` as needed. +- ❌ `doctor` does **not** create `openclaw.json` +- ❌ `doctor` does **not** create `auth-profiles.json` +- ✅ If config is missing or broken, run `./onboard.sh` again -```json5 -{ - channels: { - discord: { - token: "1234abcd", - }, - }, -} +**When to use:** Directory deleted, permission errors, environment check, session history lost. **Not for first run** — use `onboard.sh` instead. + +--- + +## Security + +1. **Credentials**: Cookies and Bearer tokens are stored locally in `auth.json` — **never commit to Git** +2. **Session expiry**: Web sessions may expire; re-login when needed +3. **Rate limits**: Web APIs may have rate limits; not suitable for high-frequency calls +4. **Compliance**: For personal learning and research only; follow platform ToS + +--- + +## Upstream Sync + +This project is based on [OpenClaw](https://github.com/openclaw/openclaw). To sync upstream: + +```bash +git remote add upstream https://github.com/openclaw/openclaw.git +git fetch upstream +git merge upstream/main ``` -### [Signal](https://docs.openclaw.ai/channels/signal) +--- -- Requires `signal-cli` and a `channels.signal` config section. +## Contributing -### [BlueBubbles (iMessage)](https://docs.openclaw.ai/channels/bluebubbles) +Contributions are welcome, especially: -- **Recommended** iMessage integration. -- Configure `channels.bluebubbles.serverUrl` + `channels.bluebubbles.password` and a webhook (`channels.bluebubbles.webhookPath`). -- The BlueBubbles server runs on macOS; the Gateway can run on macOS or elsewhere. +- Bug fixes +- Documentation improvements -### [iMessage (legacy)](https://docs.openclaw.ai/channels/imessage) +--- -- Legacy macOS-only integration via `imsg` (Messages must be signed in). -- If `channels.imessage.groups` is set, it becomes a group allowlist; include `"*"` to allow all. +## License -### [Microsoft Teams](https://docs.openclaw.ai/channels/msteams) +[MIT License](LICENSE) -- Configure a Teams app + Bot Framework, then add a `msteams` config section. -- Allowlist who can talk via `msteams.allowFrom`; group access via `msteams.groupAllowFrom` or `msteams.groupPolicy: "open"`. +--- -### [WebChat](https://docs.openclaw.ai/web/webchat) +## Acknowledgments -- Uses the Gateway WebSocket; no separate WebChat port/config. +- [OpenClaw](https://github.com/openclaw/openclaw) — Original project +- [DeepSeek](https://deepseek.com) — Excellent AI models -Browser control (optional): +--- -```json5 -{ - browser: { - enabled: true, - color: "#FF4500", - }, -} -``` +## Disclaimer -## Docs - -Use these when you’re past the onboarding flow and want the deeper reference. - -- [Start with the docs index for navigation and “what’s where.”](https://docs.openclaw.ai) -- [Read the architecture overview for the gateway + protocol model.](https://docs.openclaw.ai/concepts/architecture) -- [Use the full configuration reference when you need every key and example.](https://docs.openclaw.ai/gateway/configuration) -- [Run the Gateway by the book with the operational runbook.](https://docs.openclaw.ai/gateway) -- [Learn how the Control UI/Web surfaces work and how to expose them safely.](https://docs.openclaw.ai/web) -- [Understand remote access over SSH tunnels or tailnets.](https://docs.openclaw.ai/gateway/remote) -- [Follow the onboarding wizard flow for a guided setup.](https://docs.openclaw.ai/start/wizard) -- [Wire external triggers via the webhook surface.](https://docs.openclaw.ai/automation/webhook) -- [Set up Gmail Pub/Sub triggers.](https://docs.openclaw.ai/automation/gmail-pubsub) -- [Learn the macOS menu bar companion details.](https://docs.openclaw.ai/platforms/mac/menu-bar) -- [Platform guides: Windows (WSL2)](https://docs.openclaw.ai/platforms/windows), [Linux](https://docs.openclaw.ai/platforms/linux), [macOS](https://docs.openclaw.ai/platforms/macos), [iOS](https://docs.openclaw.ai/platforms/ios), [Android](https://docs.openclaw.ai/platforms/android) -- [Debug common failures with the troubleshooting guide.](https://docs.openclaw.ai/channels/troubleshooting) -- [Review security guidance before exposing anything.](https://docs.openclaw.ai/gateway/security) - -## Advanced docs (discovery + control) - -- [Discovery + transports](https://docs.openclaw.ai/gateway/discovery) -- [Bonjour/mDNS](https://docs.openclaw.ai/gateway/bonjour) -- [Gateway pairing](https://docs.openclaw.ai/gateway/pairing) -- [Remote gateway README](https://docs.openclaw.ai/gateway/remote-gateway-readme) -- [Control UI](https://docs.openclaw.ai/web/control-ui) -- [Dashboard](https://docs.openclaw.ai/web/dashboard) - -## Operations & troubleshooting - -- [Health checks](https://docs.openclaw.ai/gateway/health) -- [Gateway lock](https://docs.openclaw.ai/gateway/gateway-lock) -- [Background process](https://docs.openclaw.ai/gateway/background-process) -- [Browser troubleshooting (Linux)](https://docs.openclaw.ai/tools/browser-linux-troubleshooting) -- [Logging](https://docs.openclaw.ai/logging) - -## Deep dives - -- [Agent loop](https://docs.openclaw.ai/concepts/agent-loop) -- [Presence](https://docs.openclaw.ai/concepts/presence) -- [TypeBox schemas](https://docs.openclaw.ai/concepts/typebox) -- [RPC adapters](https://docs.openclaw.ai/reference/rpc) -- [Queue](https://docs.openclaw.ai/concepts/queue) - -## Workspace & skills - -- [Skills config](https://docs.openclaw.ai/tools/skills-config) -- [Default AGENTS](https://docs.openclaw.ai/reference/AGENTS.default) -- [Templates: AGENTS](https://docs.openclaw.ai/reference/templates/AGENTS) -- [Templates: BOOTSTRAP](https://docs.openclaw.ai/reference/templates/BOOTSTRAP) -- [Templates: IDENTITY](https://docs.openclaw.ai/reference/templates/IDENTITY) -- [Templates: SOUL](https://docs.openclaw.ai/reference/templates/SOUL) -- [Templates: TOOLS](https://docs.openclaw.ai/reference/templates/TOOLS) -- [Templates: USER](https://docs.openclaw.ai/reference/templates/USER) - -## Platform internals - -- [macOS dev setup](https://docs.openclaw.ai/platforms/mac/dev-setup) -- [macOS menu bar](https://docs.openclaw.ai/platforms/mac/menu-bar) -- [macOS voice wake](https://docs.openclaw.ai/platforms/mac/voicewake) -- [iOS node](https://docs.openclaw.ai/platforms/ios) -- [Android node](https://docs.openclaw.ai/platforms/android) -- [Windows (WSL2)](https://docs.openclaw.ai/platforms/windows) -- [Linux app](https://docs.openclaw.ai/platforms/linux) - -## Email hooks (Gmail) - -- [docs.openclaw.ai/gmail-pubsub](https://docs.openclaw.ai/automation/gmail-pubsub) - -## Molty - -OpenClaw was built for **Molty**, a space lobster AI assistant. 🦞 -by Peter Steinberger and the community. - -- [openclaw.ai](https://openclaw.ai) -- [soul.md](https://soul.md) -- [steipete.me](https://steipete.me) -- [@openclaw](https://x.com/openclaw) - -## Community - -See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines, maintainers, and how to submit PRs. -AI/vibe-coded PRs welcome! 🤖 - -Special thanks to [Mario Zechner](https://mariozechner.at/) for his support and for -[pi-mono](https://github.com/badlogic/pi-mono). -Special thanks to Adam Doppelt for lobster.bot. - -Thanks to all clawtributors: - -

- steipete joshp123 cpojer Mariano Belinky sebslight Takhoffman quotentiroler bohdanpodvirnyi tyler6204 iHildy - jaydenfyi gumadeiras joaohlisboa mneves75 MatthieuBizien Glucksberg MaudeBot rahthakor vrknetha vignesh07 - radek-paclt abdelsfane Tobias Bischoff christianklotz czekaj ethanpalm mukhtharcm maxsumrall rodrigouroz xadenryan - VACInc juanpablodlc conroywhitney hsrvc magimetal zerone0x advaitpaliwal meaningfool patelhiren NicholasSpisak - jonisjongithub abhisekbasu1 theonejvo jamesgroat BunsDev claude JustYannicc Hyaxia dantelex SocialNerd42069 - daveonkels Yida-Dev google-labs-jules[bot] riccardogiorato lc0rp adam91holt mousberg clawdinator[bot] hougangdev shakkernerd - coygeek mteam88 hirefrank M00N7682 joeynyc orlyjamie dbhurley Eng. Juan Combetto TSavo aerolalit - julianengel bradleypriest benithors lsh411 gut-puncture rohannagpal timolins f-trycua benostein elliotsecops - nachx639 pvoo sreekaransrinath gupsammy cristip73 stefangalescu nachoiacovino Vasanth Rao Naik Sabavat thewilloftheshadow petter-b - leszekszpunar scald pycckuu AnonO6 andranik-sahakyan davidguttman jarvis89757 sleontenko denysvitali TinyTb - sircrumpet peschee nicolasstanley davidiach nonggia.liang ironbyte-rgb dominicnunez lploc94 ratulsarna sfo2001 - lutr0 kiranjd danielz1z Iranb cdorsey AdeboyeDN obviyus Alg0rix papago2355 peetzweg/ - emanuelst evanotero KristijanJovanovski jlowin rdev rhuanssauro joshrad-dev osolmaz adityashaw2 shadril238 - CashWilliams sheeek ryan jasonsschin artuskg onutc pauloportella HirokiKobayashi-R ThanhNguyxn 18-RAJAT - kimitaka yuting0624 neooriginal manuelhettich unisone baccula manikv12 sbking travisirby fujiwara-tofu-shop - buddyh connorshea bjesuiter kyleok mcinteerj slonce70 calvin-hpnet gitpds ide-rea badlogic - grp06 dependabot[bot] amitbiswal007 John-Rood timkrase gerardward2007 roshanasingh4 tosh-hamburg azade-c dlauer - ezhikkk JonUleis shivamraut101 cheeeee jabezborja robbyczgw-cla YuriNachos Josh Phillips Wangnov kaizen403 - patrickshao Whoaa512 chriseidhof ngutman wangai-studio ysqander Yurii Chukhlib aj47 kennyklee superman32432432 - Hisleren antons austinm911 blacksmith-sh[bot] damoahdominic dan-dr doodlewind GHesericsu HeimdallStrategy imfing - jalehman jarvis-medmatic kkarimi Lukavyi mahmoudashraf93 pkrmf RandyVentures Ryan Lisse Yeom-JinHo dougvk - erikpr1994 fal3 Ghost hyf0-agent jonasjancarik Keith the Silly Goose L36 Server Marc mitschabaude-bot mkbehr - neist orenyomtov sibbl zats abhijeet117 chrisrodz Friederike Seiler gabriel-trigo hudson-rivera iamadig - itsjling Jonathan D. Rhyne (DJ-D) Joshua Mitchell kelvinCB Kit koala73 lailoo manmal mattqdev mcaxtr - mitsuhiko ogulcancelik petradonka rubyrunsstuff rybnikov siddhantjain suminhthanh svkozak wes-davis 24601 - ameno- bonald bravostation Chris Taylor damaozi dguido Django Navarro evalexpr henrino3 humanwritten - j2h4u larlyssa liuxiaopai-ai odysseus0 oswalpalash pcty-nextgen-service-account pi0 rmorse Roopak Nijhara Syhids - tmchow Ubuntu xiaose Aaron Konyer aaronveklabs akramcodez aldoeliacim andreabadesso Andrii BinaryMuse - bqcfjwhz85-arch cash-echo-bot Clawd ClawdFx danballance danielcadenhead Elarwei001 EnzeD erik-agens Evizero - fcatuhe gildo hclsys itsjaydesu ivancasco ivanrvpereira Jarvis jayhickey jeffersonwarrior jeffersonwarrior - jverdi longmaba Marco Marandiz MarvinCui mattezell mjrussell odnxe optimikelabs p6l-richard philipp-spiess - Pocket Clawd RayBB robaxelsen Sash Catanzarite Suksham-sharma T5-AndyML thejhinvirtuoso travisp VAC william arzt - yudshj zknicker 0oAstro Abdul535 abhaymundhara aduk059 aisling404 alejandro maza Alex-Alaniz alexanderatallah - alexstyl AlexZhangji andrewting19 anpoirier araa47 arthyn Asleep123 Ayush Ojha Ayush10 bguidolim - bolismauro caelum0x championswimmer chenyuan99 Chloe-VP Claude Code Clawdbot Maintainers conhecendoia dasilva333 David-Marsh-Photo - deepsoumya617 Developer Dimitrios Ploutarchos Drake Thomsen dvrshil dxd5001 dylanneve1 Felix Krause foeken frankekn - fredheir Fronut ganghyun kim grrowl gtsifrikas HassanFleyah HazAT hrdwdmrbl hugobarauna iamEvanYT - ichbinlucaskim Jamie Openshaw Jane Jarvis Deploy Jefferson Nunn jogi47 kentaro Kevin Lin kira-ariaki kitze - Kiwitwitter kossoy levifig liuy Lloyd loganaden longjos loukotal mac mimi markusbkoch - martinpucik Matt mini mertcicekci0 Miles minghinmatthewlam mrdbstn MSch mudrii Mustafa Tag Eldeen myfunc - mylukin nathanbosse ndraiman nexty5870 Noctivoro Omar-Khaleel ozgur-polat pasogott plum-dawg pookNast - ppamment prathamdby ptn1411 rafaelreis-r rafelbev reeltimeapps RLTCmpe robhparker rohansachinpatil Rony Kelner - ryancnelson Samrat Jha seans-openclawbot senoldogann Seredeep sergical shatner shiv19 shiyuanhai Shrinija17 - siraht snopoke spiceoogway stephenchen2025 succ985 Suvink techboss testingabc321 tewatia The Admiral - therealZpoint-bot thesash uos-status vcastellm Vibe Kanban vincentkoc void Vultr-Clawd Admin Wimmie wolfred - wstock wytheme YangHuang2280 yazinsai yevhen YiWang24 ymat19 Zach Knickerbocker zackerthescar zhixian - 0xJonHoldsCrypto aaronn Alphonse-arianee atalovesyou Azade carlulsoe ddyo Erik jiulingyun latitudeki5223 - Manuel Maly minghinmatthewlam Mourad Boustani odrobnik pcty-nextgen-ios-builder Quentin rafaelreis-r Randy Torres rhjoh Rolf Fredheim - ronak-guliani William Stock - Akash Kobal -

+This project is for learning and research only. When using it to access third-party services, ensure you comply with their terms of service. The developers are not responsible for any issues arising from use of this project. diff --git a/README_zh-CN.md b/README_zh-CN.md new file mode 100644 index 0000000000..50cca0d39a --- /dev/null +++ b/README_zh-CN.md @@ -0,0 +1,574 @@ +# OpenClaw Zero Token + +**免 API Token 使用大模型** - 通过浏览器登录方式免费使用 ChatGPT、Claude、Gemini、DeepSeek、千问国际版、千问国内版、豆包、Kimi、智谱清言、Grok、Manus 等 AI 模型。 + +[License: MIT](https://opensource.org/licenses/MIT) + +[English](README.md) | 简体中文 + +--- + +## 项目简介 + +OpenClaw Zero Token 是 [OpenClaw](https://github.com/openclaw/openclaw) 的分支版本,核心目标是**免除 API Token 费用**,实现对各大 AI 平台的免费访问。 + +### 为什么选择 Zero Token? + + +| 传统方式 | Zero Token 方式 | +| -------------- | ------------- | +| 需要购买 API Token | **完全免费** | +| 按调用次数计费 | 无使用限制 | +| 需要绑定信用卡 | 仅需网页登录 | +| Token 可能泄露 | 凭证本地存储 | + + +### 支持的平台 + + +| 平台 | 状态 | 模型 | +| -------------------------- | --------- | ---------------------------------------------------- | +| DeepSeek | ✅ **已测试** | deepseek-chat, deepseek-reasoner | +| 千问国际版 (Qwen International) | ✅ **已测试** | Qwen 3.5 Plus, Qwen 3.5 Turbo | +| 千问国内版 (Qwen 国内版) | ✅ **已测试** | Qwen 3.5 Plus, Qwen 3.5 Turbo | +| Kimi | ✅ **已测试** | Moonshot v1 8K, 32K, 128K | +| Claude Web | ✅ **已测试** | claude-sonnet-4-6, claude-opus-4-6, claude-haiku-4-6 | +| 豆包 (Doubao) | ✅ **已测试** | doubao-seed-2.0, doubao-pro | +| ChatGPT Web | ✅ **已测试** | GPT-4, GPT-4 Turbo | +| Gemini Web | ✅ **已测试** | Gemini Pro, Gemini Ultra | +| Grok Web | ✅ **已测试** | Grok 1, Grok 2 | +| GLM Web (智谱清言) | ✅ **已测试** | glm-4-Plus, glm-4-Think | +| GLM Web (国际版) | ✅ **已测试** | GLM-4 Plus, GLM-4 Think | +| Manus API | ✅ **已测试** | Manus 1.6, Manus 1.6 Lite(API key,免费额度) | + + + + +### 工具调用支持 + +当前支持的模型均可调用**本地工具**(如 exec、read_file、list_dir、browser、apply_patch 等),从而执行命令、读写工作区文件、进行网页自动化等。 + + +| 提供商类型 | 工具支持 | 说明 | +| ---------------------------------------------- | ---- | -------------------------------------------------------------------------------- | +| **Web(DeepSeek、千问、Kimi、Claude、豆包、GLM、Grok 等)** | ✅ | 在 system 中注入 XML 工具说明,流式解析 `` 并在本地执行。 | +| **ChatGPT Web / Gemini Web / Manus API** | ✅ | 同样通过工具说明 + 多轮上下文 + `` 解析实现。 | +| **OpenRouter / OpenAI 兼容 API** | ✅ | 使用原生 `tools` / `tool_calls` 接口。 | +| **Ollama** | ✅ | 使用原生 `/api/chat` 的 tools。 | + + +Agent 的文件访问范围受配置中的**工作区**目录限制(见配置项 `agents.defaults.workspace`)。 + +### 补充功能 + +**一次提问,获取所有 AI 模型的答案** — AskOnce 支持同时向多个已配置的 AI 模型发起查询,一次输入即可获得各模型回复。 + +![AskOnce 一次提问多模型回答](askonce.png) + +--- + +## 实现原理 + +### 系统架构 +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ OpenClaw Zero Token │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ +│ │ Web UI │ │ CLI/TUI │ │ Gateway │ │ Channels │ │ +│ │ (Lit 3.x) │ │ │ │ (Port API) │ │ (Telegram…) │ │ +│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ +│ │ │ │ │ │ +│ └──────────────────┴──────────────────┴──────────────────┘ │ +│ │ │ +│ ┌────────▼────────┐ │ +│ │ Agent Core │ │ +│ │ (PI-AI Engine) │ │ +│ └────────┬────────┘ │ +│ │ │ +│ ┌───────────────────────────────────────────────────────────────────────┐ │ +│ │ Provider Layer │ │ +│ │ DeepSeek Web (Zero Token) ✅ │ │ +│ │ Qwen Web 国际版/国内版 (Zero Token) ✅ │ │ +│ │ Kimi (Zero Token) ✅ │ │ +│ │ Claude Web (Zero Token) ✅ │ │ +│ │ Doubao (Zero Token) ✅ │ │ +│ │ ChatGPT Web (Zero Token) ✅ │ │ +│ │ Gemini Web (Zero Token) ✅ │ │ +│ │ Grok Web (Zero Token) ✅ │ │ +│ │ GLM Web 智谱清言/国际版 (Zero Token) ✅ │ │ +│ │ Manus API (Token) ✅ │ │ +│ └───────────────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +--- + + +### 流程图 + +``` +┌────────────────────────────────────────────────────────────────────────────┐ +│ DeepSeek Web 认证流程 │ +├────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ 1. 启动浏览器 │ +│ ┌─────────────┐ │ +│ │ openclaw │ ──启动──▶ Chrome (CDP Port: 18892) │ +│ │ gateway │ 带用户数据目录 │ +│ └─────────────┘ │ +│ │ +│ 2. 用户登录 │ +│ ┌─────────────┐ │ +│ │ 用户在浏览器 │ ──访问──▶ https://chat.deepseek.com │ +│ │ 中手动登录 │ 扫码/账号密码登录 │ +│ └─────────────┘ │ +│ │ +│ 3. 捕获凭证 │ +│ ┌─────────────┐ │ +│ │ Playwright │ ──监听──▶ 网络请求 │ +│ │ CDP 连接 │ 拦截 Authorization Header │ +│ └─────────────┘ 获取 Cookie │ +│ │ +│ 4. 存储凭证 │ +│ ┌─────────────┐ │ +│ │ auth.json │ ◀──保存── { cookie, bearer, userAgent } │ +│ └─────────────┘ │ +│ │ +│ 5. API 调用 │ +│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ +│ │ DeepSeek │ ──▶ │ DeepSeek │ ──▶ │ chat.deep- │ │ +│ │ WebClient │ │ Web API │ │ seek.com │ │ +│ └─────────────┘ └─────────────┘ └─────────────┘ │ +│ 使用存储的 Cookie + Bearer Token │ +│ │ +└────────────────────────────────────────────────────────────────────────────┘ +``` + + + +### 配置步骤 + +1. **编译**:下载项目后执行`npm install && npm run build && pnpm ui:build` +2. **打开浏览器调试**:`./start-chrome-debug.sh` +3. **登录各大网站**:在 Chrome 中登录各模型网页版 +4. **配置 onboard**:`./onboard.sh` +5. **启动 server**:`./server.sh start` + +### 注意事项 + +- **会话有效期**:会话可能定期失效,需重新登录 +- **浏览器依赖**:需要保持 Chrome 调试模式运行 +- **合规使用**:仅供个人学习研究,商用请使用官方API + +## 快速开始 + +> **平台支持:** +> +> - 🍎 **macOS** / 🐧 **Linux**:按 [START_HERE.md](START_HERE.md) 步骤操作;详细安装与配置见 [INSTALLATION.md](INSTALLATION.md)。 +> - 🪟 **Windows**:推荐使用 WSL2,安装后按 Linux 流程操作([START_HERE.md](START_HERE.md)、[INSTALLATION.md](INSTALLATION.md))。WSL2 安装:`wsl --install`;指南: + +### 环境要求 + +- Node.js >= 22.12.0 +- pnpm >= 9.0.0 +- Chrome 浏览器 +- **操作系统**: macOS, Linux, 或 Windows (WSL2) + +### 脚本说明 + +本项目提供了多个辅助脚本,适用于不同场景: + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ 脚本关系图 │ +├─────────────────────────────────────────────────────────────────────┤ +│ │ +│ 首次使用流程: │ +│ ┌──────────────────────────────────────────────────────────────┐ │ +│ │ 1. 编译 npm install && npm run build && pnpm ui:build │ │ +│ │ 2. 打开浏览器调试 ./start-chrome-debug.sh │ │ +│ │ 3. 登录各大网站 千问国际版/国内版、Kimi 等 +│ │ 4. 配置 onboard ./onboard.sh │ │ +│ │ 5. 启动 server ./server.sh start │ │ +│ └──────────────────────────────────────────────────────────────┘ │ +│ │ +│ 日常使用: │ +│ ┌──────────────────────────────────────────────────────────────┐ │ +│ │ start-chrome-debug.sh → onboard.sh → server.sh start │ │ +│ │ server.sh [start|stop|restart|status] 管理 Gateway │ │ +│ └──────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +**脚本对比:**(核心 3 个脚本) + + +| 脚本 | 用途 | 使用场景 | +| ----------------------- | -------------- | -------------------------------------------------------- | +| `start-chrome-debug.sh` | 启动 Chrome 调试模式 | 步骤 2:打开浏览器,端口 9222,供各平台登录与 onboard 连接 | +| `onboard.sh` | 配置认证向导 | 步骤 4、5:选择平台(deepseek-web 等),捕获 Cookie/Token | +| `server.sh` | 管理 Gateway 服务 | 步骤 6 及日常:`start` / `stop` / `restart` / `status`,端口 3001 | + + +### 安装说明 + +#### 克隆仓库 + +```bash +git clone https://github.com/linuxhsj/openclaw-zero-token.git +``` + +#### 进入项目 +```bash +cd openclaw-zero-token +``` +#### 安装依赖 +```bash +pnpm install +``` + +#### 启动项目 + +#### 步骤 1:编译 + +```bash +pnpm build +pnpm ui:build +``` + +#### 步骤 2:配置认证 + +```bash +# 拷贝配置文件(可选:若不存在,onboard 或 server 会自动从 .openclaw-state.example 复制) + +首次运行可复制 .openclaw-state.example/openclaw.json 到 .openclaw-zero-state/openclaw.json + +# 启动浏览器调式模式 +./start-chrome-debug.sh + +# 登录各模型网页 +以deepseek为例,登录https://chat.deepseek.com/ + +# 运行配置向导 +./onboard.sh +# 或使用编译后的版本 +node openclaw.mjs onboard + +# 选择认证方式 +以deepseek为例 +? Auth provider: DeepSeek (Browser Login) + +# 选择登录模式 +? DeepSeek Auth Mode: + > Automated Login (Recommended) # 自动捕获凭证 + +看到认证成功就可以了,如果要增加其他模型,再运行一次./onboard.sh +``` + +#### 步骤 3:启动 Gateway + +```bash +# 使用辅助脚本(推荐) +./server.sh +``` + +--- + +## 使用方式 + +### Web UI + +执行./server.sh 后会自动启动webui,在聊天界面直接使用 AI 模型。 +后续也可以自己启动http://127.0.0.1:3001/chat?session=62b791625fa441be036acd3c206b7e14e2bb13c803355823 + +#### 切换模型 + +在聊天界面中使用 `/model` 命令可以切换不同的 AI 模型: + +```bash +# 切换到 Claude Web +/model claude-web + +# 切换到豆包 +/model doubao-web + +# 切换到 DeepSeek +/model deepseek-web + +# 或者指定具体的模型 +/model claude-web/claude-sonnet-4-6 +/model doubao-web/doubao-seed-2.0 +/model deepseek-web/deepseek-chat +``` + +#### 查看可用模型 + +使用 `/models` 命令可以查看所有已配置的模型: + +```bash +/models +``` + +> **关键规则:** 只有在 `./onboard.sh` 中完成配置的平台,才会写入 `openclaw.json` 并显示在 `/models` 列表中。 + +这将显示: + +- 所有可用的提供商(claude-web、doubao-web、deepseek-web 等) +- 每个提供商下的模型列表 +- 当前激活的模型 +- 模型别名和配置信息 + +**示例输出:** + +``` +Model Input Ctx Local Auth Tags +doubao-web/doubao-seed-2.0 text 63k no no default,configured,alias:Doubao Browser +claude-web/claude-sonnet-4-6 text+image 195k no no configured,alias:Claude Web +deepseek-web/deepseek-chat text 64k no no configured +``` + +### API 调用 + +```bash +# 使用 Gateway Token 调用 +curl http://127.0.0.1:3001/v1/chat/completions \ + -H "Authorization: Bearer YOUR_GATEWAY_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "model": "deepseek-web/deepseek-chat", + "messages": [{"role": "user", "content": "你好!"}] + }' +``` + +### CLI 模式 + +```bash +# 交互式命令行 +node openclaw.mjs tui +``` + +--- + +## 配置说明 + +### openclaw.json + +```json +{ + "auth": { + "profiles": { + "deepseek-web:default": { + "provider": "deepseek-web", + "mode": "api_key" + } + } + }, + "models": { + "providers": { + "deepseek-web": { + "baseUrl": "https://chat.deepseek.com", + "api": "deepseek-web", + "models": [ + { + "id": "deepseek-chat", + "name": "DeepSeek Chat", + "contextWindow": 64000, + "maxTokens": 4096 + }, + { + "id": "deepseek-reasoner", + "name": "DeepSeek Reasoner", + "reasoning": true, + "contextWindow": 64000, + "maxTokens": 8192 + } + ] + } + } + }, + "gateway": { + "port": 3001, + "auth": { + "mode": "token", + "token": "your-gateway-token" + } + } +} +``` + +--- + +## 故障排查 + +### 首次运行:使用配置向导(推荐) + +**首次运行项目时,直接运行配置向导:** + +```bash +./onboard.sh +``` + +**配置向导会自动创建所有必需的文件和目录!** + +### 修复问题:使用诊断命令 + +**如果项目已经运行过,但遇到目录或文件缺失问题,运行诊断命令:** + +```bash +node dist/index.mjs doctor +``` + +**诊断命令会自动:** + +- ✅ 检查所有必需的目录 +- ✅ 自动创建缺失的目录 +- ✅ 修复文件权限问题 +- ✅ 检查配置文件完整性 +- ✅ 检测多个状态目录冲突 +- ✅ 提供详细的修复建议 + +**⚠️ 重要限制:** + +- ❌ `doctor` 命令**不会**创建配置文件(`openclaw.json`) +- ❌ `doctor` 命令**不会**创建认证文件(`auth-profiles.json`) +- ✅ 如果配置文件缺失或损坏,需要重新运行 `./onboard.sh` + +**何时使用:** + +- 目录被意外删除 +- 遇到"权限被拒绝"错误 +- 验证环境是否正常 +- 会话历史丢失 +- **不适合首次运行**(应该用 `onboard.sh`) + + +--- + +## 开发路线 + +### 当前重点 + +- ✅ DeepSeek Web、千问国际版、千问国内版、Kimi、Claude Web、豆包、ChatGPT Web、Gemini Web、Grok Web、GLM Web、GLM 国际版、Manus API — **均已测试通过** +- 🔧 提高凭证捕获可靠性 +- 📝 文档改进 + +### 计划功能 + +- 🔜 过期会话自动刷新 + +--- + +## 扩展其他平台 + +要添加新的 Web 认证平台,需要创建以下文件: + +### 1. 认证模块 (`src/providers/{platform}-web-auth.ts`) + +```typescript +export async function loginPlatformWeb(params: { + onProgress: (msg: string) => void; + openUrl: (url: string) => Promise; +}): Promise<{ cookie: string; bearer: string; userAgent: string }> { + // 浏览器自动化登录,捕获凭证 +} +``` + +### 2. API 客户端 (`src/providers/{platform}-web-client.ts`) + +```typescript +export class PlatformWebClient { + constructor(options: { cookie: string; bearer?: string }) {} + + async chatCompletions(params: ChatParams): Promise { + // 调用平台 Web API + } +} +``` + +### 3. 流处理器 (`src/agents/{platform}-web-stream.ts`) + +```typescript +export function createPlatformWebStreamFn(credentials: string): StreamFn { + // 处理平台特有的响应格式 +} +``` + +--- + +## 文件结构 + +``` +openclaw-zero-token/ +├── src/ +│ ├── providers/ +│ │ ├── deepseek-web-auth.ts # DeepSeek 登录捕获 +│ │ └── deepseek-web-client.ts # DeepSeek API 客户端 +│ ├── agents/ +│ │ └── deepseek-web-stream.ts # 流式响应处理 +│ ├── commands/ +│ │ └── auth-choice.apply.deepseek-web.ts # 认证流程 +│ └── browser/ +│ └── chrome.ts # Chrome 自动化 +├── ui/ # Web UI (Lit 3.x) +├── .openclaw-zero-state/ # 本地状态 (不提交) +│ ├── openclaw.json # 配置 +│ └── agents/main/agent/ +│ └── auth.json # 凭证 (敏感) +└── .gitignore # 包含 .openclaw-zero-state/ +``` + +--- + +## 安全注意事项 + +1. **凭证存储**: Cookie 和 Bearer Token 存储在本地 `auth.json`,**绝不提交到 Git** +2. **会话有效期**: Web 会话可能过期,需要定期重新登录 +3. **使用限制**: Web API 可能有速率限制,不适合高频调用 +4. **合规使用**: 仅用于个人学习研究,请遵守平台服务条款 + +--- + +## 与上游同步 + +本项目基于 OpenClaw,可以通过以下方式同步上游更新: + +```bash +# 添加上游仓库 +git remote add upstream https://github.com/openclaw/openclaw.git + +# 同步上游更新 +git fetch upstream +git merge upstream/main +``` + +--- + +## 贡献指南 + +欢迎贡献代码,特别是: + +- Bug 修复 +- 文档改进 + +--- + +## 许可证 + +[MIT License](LICENSE) + +--- + +## 致谢 + +- [OpenClaw](https://github.com/openclaw/openclaw) - 原始项目 +- [DeepSeek](https://deepseek.com) - 优秀的 AI 模型 + +--- + +## 免责声明 + +本项目仅供学习和研究使用。使用本项目访问任何第三方服务时,请确保遵守该服务的使用条款。开发者不对因使用本项目而产生的任何问题负责。 \ No newline at end of file diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index d02b9fb801..0000000000 --- a/SECURITY.md +++ /dev/null @@ -1,128 +0,0 @@ -# Security Policy - -If you believe you've found a security issue in OpenClaw, please report it privately. - -## Reporting - -Report vulnerabilities directly to the repository where the issue lives: - -- **Core CLI and gateway** — [openclaw/openclaw](https://github.com/openclaw/openclaw) -- **macOS desktop app** — [openclaw/openclaw](https://github.com/openclaw/openclaw) (apps/macos) -- **iOS app** — [openclaw/openclaw](https://github.com/openclaw/openclaw) (apps/ios) -- **Android app** — [openclaw/openclaw](https://github.com/openclaw/openclaw) (apps/android) -- **ClawHub** — [openclaw/clawhub](https://github.com/openclaw/clawhub) -- **Trust and threat model** — [openclaw/trust](https://github.com/openclaw/trust) - -For issues that don't fit a specific repo, or if you're unsure, email **security@openclaw.ai** and we'll route it. - -For full reporting instructions see our [Trust page](https://trust.openclaw.ai). - -### Required in Reports - -1. **Title** -2. **Severity Assessment** -3. **Impact** -4. **Affected Component** -5. **Technical Reproduction** -6. **Demonstrated Impact** -7. **Environment** -8. **Remediation Advice** - -Reports without reproduction steps, demonstrated impact, and remediation advice will be deprioritized. Given the volume of AI-generated scanner findings, we must ensure we're receiving vetted reports from researchers who understand the issues. - -## Security & Trust - -**Jamieson O'Reilly** ([@theonejvo](https://twitter.com/theonejvo)) is Security & Trust at OpenClaw. Jamieson is the founder of [Dvuln](https://dvuln.com) and brings extensive experience in offensive security, penetration testing, and security program development. - -## Bug Bounties - -OpenClaw is a labor of love. There is no bug bounty program and no budget for paid reports. Please still disclose responsibly so we can fix issues quickly. -The best way to help the project right now is by sending PRs. - -## Maintainers: GHSA Updates via CLI - -When patching a GHSA via `gh api`, include `X-GitHub-Api-Version: 2022-11-28` (or newer). Without it, some fields (notably CVSS) may not persist even if the request returns 200. - -## Out of Scope - -- Public Internet Exposure -- Using OpenClaw in ways that the docs recommend not to -- Prompt injection attacks - -## Plugin Trust Boundary - -Plugins/extensions are loaded **in-process** with the Gateway and are treated as trusted code. - -- Plugins can execute with the same OS privileges as the OpenClaw process. -- Runtime helpers (for example `runtime.system.runCommandWithTimeout`) are convenience APIs, not a sandbox boundary. -- Only install plugins you trust, and prefer `plugins.allow` to pin explicit trusted plugin ids. - -## Operational Guidance - -For threat model + hardening guidance (including `openclaw security audit --deep` and `--fix`), see: - -- `https://docs.openclaw.ai/gateway/security` - -### Tool filesystem hardening - -- `tools.exec.applyPatch.workspaceOnly: true` (recommended): keeps `apply_patch` writes/deletes within the configured workspace directory. -- `tools.fs.workspaceOnly: true` (optional): restricts `read`/`write`/`edit`/`apply_patch` paths to the workspace directory. -- Avoid setting `tools.exec.applyPatch.workspaceOnly: false` unless you fully trust who can trigger tool execution. - -### Web Interface Safety - -OpenClaw's web interface (Gateway Control UI + HTTP endpoints) is intended for **local use only**. - -- Recommended: keep the Gateway **loopback-only** (`127.0.0.1` / `::1`). - - Config: `gateway.bind="loopback"` (default). - - CLI: `openclaw gateway run --bind loopback`. -- Canvas host note: network-visible canvas is **intentional** for trusted node scenarios (LAN/tailnet). - - Expected setup: non-loopback bind + Gateway auth (token/password/trusted-proxy) + firewall/tailnet controls. - - Expected routes: `/__openclaw__/canvas/`, `/__openclaw__/a2ui/`. - - This deployment model alone is not a security vulnerability. -- Do **not** expose it to the public internet (no direct bind to `0.0.0.0`, no public reverse proxy). It is not hardened for public exposure. -- If you need remote access, prefer an SSH tunnel or Tailscale serve/funnel (so the Gateway still binds to loopback), plus strong Gateway auth. -- The Gateway HTTP surface includes the canvas host (`/__openclaw__/canvas/`, `/__openclaw__/a2ui/`). Treat canvas content as sensitive/untrusted and avoid exposing it beyond loopback unless you understand the risk. - -## Runtime Requirements - -### Node.js Version - -OpenClaw requires **Node.js 22.12.0 or later** (LTS). This version includes important security patches: - -- CVE-2025-59466: async_hooks DoS vulnerability -- CVE-2026-21636: Permission model bypass vulnerability - -Verify your Node.js version: - -```bash -node --version # Should be v22.12.0 or later -``` - -### Docker Security - -When running OpenClaw in Docker: - -1. The official image runs as a non-root user (`node`) for reduced attack surface -2. Use `--read-only` flag when possible for additional filesystem protection -3. Limit container capabilities with `--cap-drop=ALL` - -Example secure Docker run: - -```bash -docker run --read-only --cap-drop=ALL \ - -v openclaw-data:/app/data \ - openclaw/openclaw:latest -``` - -## Security Scanning - -This project uses `detect-secrets` for automated secret detection in CI/CD. -See `.detect-secrets.cfg` for configuration and `.secrets.baseline` for the baseline. - -Run locally: - -```bash -pip install detect-secrets==1.5.0 -detect-secrets scan --baseline .secrets.baseline -``` diff --git a/START_HERE.md b/START_HERE.md new file mode 100644 index 0000000000..55203e13a1 --- /dev/null +++ b/START_HERE.md @@ -0,0 +1,148 @@ +# 🚀 从这里开始 + +## 📖 文档导航 + +### 🔧 安装 +- **INSTALLATION.md** - 安装指南(首次使用必读) + +### 🎯 快速开始 +- **TEST_STEPS.md** - 完整测试步骤(推荐阅读) + +### 📚 详细文档 +- **ARCHITECTURE.md** - 系统架构说明 +- **README.md** / **README_zh-CN.md** - 项目总览与支持平台 + +--- + +## ⚡ 配置步骤(6 步) + +**首次使用?先阅读 INSTALLATION.md 完成安装!** + +```bash +# 1. 编译 +npm install +npm run build +pnpm ui:build # 构建 Web UI + +# 2. 打开浏览器调试 +./start-chrome-debug.sh + +# 3. 登录各大网站(千问、Kimi 等,不含 DeepSeek,在 Chrome 中登录) + +# 4. 配置 onboard +./onboard.sh + +# 5. 登录 DeepSeek(在 onboard 中选择 deepseek-web 完成认证) + +# 6. 启动 server +./server.sh start +``` + +> **关键规则:** 只有在 `./onboard.sh` 中完成配置的平台,才会写入 `openclaw.json` 并出现在 `/models` 列表中。 + +然后访问:http://127.0.0.1:3001/#token=62b791625fa441be036acd3c206b7e14e2bb13c803355823 + +--- + +## 📋 需要登录的平台 + +**步骤 3**(不含 DeepSeek):千问国际版、千问国内版、Kimi、Claude、Doubao、ChatGPT、Gemini、Grok、GLM Web(智谱清言)、GLM 国际版 +**步骤 5**(仅 DeepSeek):https://chat.deepseek.com + +**Manus API**(已测试):在 onboard 中配置 API Key,无需浏览器登录 + +--- + +## ✅ 测试状态 + +| 平台 | 状态 | +|------|------| +| DeepSeek、千问国际版、千问国内版、Kimi、Claude Web、豆包、ChatGPT Web、Gemini Web、Grok Web、GLM Web、GLM 国际版、Manus API | ✅ 已测试可用 | + +--- + +## 🎯 预期结果 + +测试完成后,你将拥有: + +- ✅ 12 个可用的平台(含 11 个 Web 平台 + Manus API) +- ✅ 28+ 个可选的 AI 模型 +- ✅ 完全免费的 AI 对话服务 +- ✅ 统一的浏览器方案 + +--- + +## 📞 需要帮助? + +查看 **TEST_STEPS.md** 获取详细的测试步骤和故障排查指南。 + +--- + +开始测试吧!🎉 + +--- + +## English Version + +### 🚀 Start Here + +#### Quick Setup (6 Steps) + +**First time? Read INSTALLATION.md first!** + +```bash +# 1. Build +npm install +npm run build + +# 2. Open browser debug mode +./start-chrome-debug.sh + +# 3. Login to platforms (Qwen, Kimi, Claude, etc. — exclude DeepSeek) +# 4. Configure onboard +./onboard.sh + +# 5. Login DeepSeek (Chrome + onboard deepseek-web) +# 6. Start server +./server.sh start +``` + +> **Important:** Only platforms completed in `./onboard.sh` are written into `openclaw.json` and shown in `/models`. + +Then visit: http://127.0.0.1:3001/#token=62b791625fa441be036acd3c206b7e14e2bb13c803355823 + +#### Platforms to Login + +**Step 3 (exclude DeepSeek)** +1. https://chat.qwen.ai +2. https://www.qianwen.com +3. https://kimi.moonshot.cn +4. https://claude.ai +5. https://www.doubao.com/chat/ +6. https://chatgpt.com +7. https://gemini.google.com/app +8. https://grok.com +9. https://chatglm.cn +10. https://chat.z.ai/ + +**Step 5 (DeepSeek only)** +11. https://chat.deepseek.com + +#### Test Status + +| Platform | Status | +|----------|--------| +| DeepSeek, Qwen International, Qwen CN, Kimi, Claude Web, Doubao, ChatGPT Web, Gemini Web, Grok Web, GLM Web, GLM International, Manus API | ✅ Tested | + +#### Expected Results + +After testing, you will have: + +- ✅ 12 available platforms (11 Web platforms + Manus API) +- ✅ 28+ selectable AI models +- ✅ Completely free AI conversation service +- ✅ Unified browser approach + +#### Need Help? + +See **TEST_STEPS.md** for detailed testing steps and troubleshooting. diff --git a/Swabble/.github/workflows/ci.yml b/Swabble/.github/workflows/ci.yml deleted file mode 100644 index aff600f6df..0000000000 --- a/Swabble/.github/workflows/ci.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: CI - -on: - push: - branches: [main] - pull_request: - -jobs: - build-and-test: - runs-on: macos-latest - defaults: - run: - shell: bash - working-directory: swabble - steps: - - name: Checkout swabble - uses: actions/checkout@v4 - with: - path: swabble - - - name: Select Xcode 26.1 (prefer 26.1.1) - run: | - set -euo pipefail - # pick the newest installed 26.1.x, fallback to newest 26.x - CANDIDATE="$(ls -d /Applications/Xcode_26.1*.app 2>/dev/null | sort -V | tail -1 || true)" - if [[ -z "$CANDIDATE" ]]; then - CANDIDATE="$(ls -d /Applications/Xcode_26*.app 2>/dev/null | sort -V | tail -1 || true)" - fi - if [[ -z "$CANDIDATE" ]]; then - echo "No Xcode 26.x found on runner" >&2 - exit 1 - fi - echo "Selecting $CANDIDATE" - sudo xcode-select -s "$CANDIDATE" - xcodebuild -version - - - name: Show Swift version - run: swift --version - - - name: Install tooling - run: | - brew update - brew install swiftlint swiftformat - - - name: Format check - run: | - ./scripts/format.sh - git diff --exit-code - - - name: Lint - run: ./scripts/lint.sh - - - name: Test - run: swift test --parallel diff --git a/Swabble/.gitignore b/Swabble/.gitignore deleted file mode 100644 index e988a5b232..0000000000 --- a/Swabble/.gitignore +++ /dev/null @@ -1,33 +0,0 @@ -# macOS -.DS_Store - -# SwiftPM / Build -/.build -/.swiftpm -/DerivedData -xcuserdata/ -*.xcuserstate - -# Editors -/.vscode -.idea/ - -# Xcode artifacts -*.hmap -*.ipa -*.dSYM.zip -*.dSYM - -# Playgrounds -*.xcplayground -playground.xcworkspace -timeline.xctimeline - -# Carthage -Carthage/Build/ - -# fastlane -fastlane/report.xml -fastlane/Preview.html -fastlane/screenshots/**/*.png -fastlane/test_output diff --git a/Swabble/.swiftformat b/Swabble/.swiftformat deleted file mode 100644 index 2686269a27..0000000000 --- a/Swabble/.swiftformat +++ /dev/null @@ -1,8 +0,0 @@ ---swiftversion 6.2 ---indent 4 ---maxwidth 120 ---wraparguments before-first ---wrapcollections before-first ---stripunusedargs closure-only ---self remove ---header "" diff --git a/Swabble/.swiftlint.yml b/Swabble/.swiftlint.yml deleted file mode 100644 index f63ff5dbb1..0000000000 --- a/Swabble/.swiftlint.yml +++ /dev/null @@ -1,43 +0,0 @@ -# SwiftLint for swabble -included: - - Sources -excluded: - - .build - - DerivedData - - "**/.swiftpm" - - "**/.build" - - "**/DerivedData" - - "**/.DS_Store" -opt_in_rules: - - array_init - - closure_spacing - - explicit_init - - fatal_error_message - - first_where - - joined_default_parameter - - last_where - - literal_expression_end_indentation - - multiline_arguments - - multiline_parameters - - operator_usage_whitespace - - redundant_nil_coalescing - - sorted_first_last - - switch_case_alignment - - vertical_parameter_alignment_on_call - - vertical_whitespace_opening_braces - - vertical_whitespace_closing_braces - -disabled_rules: - - trailing_whitespace - - trailing_newline - - indentation_width - - identifier_name - - explicit_self - - file_header - - todo - -line_length: - warning: 140 - error: 180 - -reporter: "xcode" diff --git a/Swabble/CHANGELOG.md b/Swabble/CHANGELOG.md deleted file mode 100644 index e8f2ad60d8..0000000000 --- a/Swabble/CHANGELOG.md +++ /dev/null @@ -1,11 +0,0 @@ -# Changelog - -## 0.2.0 — 2025-12-23 - -### Highlights -- Added `SwabbleKit` (multi-platform wake-word gate utilities with segment-aware gap detection). -- Swabble package now supports iOS + macOS consumers; CLI remains macOS 26-only. - -### Changes -- CLI wake-word matching/stripping routed through `SwabbleKit` helpers. -- Speech pipeline types now explicitly gated to macOS 26 / iOS 26 availability. diff --git a/Swabble/LICENSE b/Swabble/LICENSE deleted file mode 100644 index f7b526698b..0000000000 --- a/Swabble/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2025 Peter Steinberger - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/Swabble/Package.resolved b/Swabble/Package.resolved deleted file mode 100644 index f52a51fbe5..0000000000 --- a/Swabble/Package.resolved +++ /dev/null @@ -1,69 +0,0 @@ -{ - "originHash" : "24a723309d7a0039d3df3051106f77ac1ed7068a02508e3a6804e41d757e6c72", - "pins" : [ - { - "identity" : "commander", - "kind" : "remoteSourceControl", - "location" : "https://github.com/steipete/Commander.git", - "state" : { - "revision" : "9e349575c8e3c6745e81fe19e5bb5efa01b078ce", - "version" : "0.2.1" - } - }, - { - "identity" : "elevenlabskit", - "kind" : "remoteSourceControl", - "location" : "https://github.com/steipete/ElevenLabsKit", - "state" : { - "revision" : "7e3c948d8340abe3977014f3de020edf221e9269", - "version" : "0.1.0" - } - }, - { - "identity" : "swift-concurrency-extras", - "kind" : "remoteSourceControl", - "location" : "https://github.com/pointfreeco/swift-concurrency-extras", - "state" : { - "revision" : "5a3825302b1a0d744183200915a47b508c828e6f", - "version" : "1.3.2" - } - }, - { - "identity" : "swift-syntax", - "kind" : "remoteSourceControl", - "location" : "https://github.com/swiftlang/swift-syntax.git", - "state" : { - "revision" : "0687f71944021d616d34d922343dcef086855920", - "version" : "600.0.1" - } - }, - { - "identity" : "swift-testing", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-testing", - "state" : { - "revision" : "399f76dcd91e4c688ca2301fa24a8cc6d9927211", - "version" : "0.99.0" - } - }, - { - "identity" : "swiftui-math", - "kind" : "remoteSourceControl", - "location" : "https://github.com/gonzalezreal/swiftui-math", - "state" : { - "revision" : "0b5c2cfaaec8d6193db206f675048eeb5ce95f71", - "version" : "0.1.0" - } - }, - { - "identity" : "textual", - "kind" : "remoteSourceControl", - "location" : "https://github.com/gonzalezreal/textual", - "state" : { - "revision" : "5b06b811c0f5313b6b84bbef98c635a630638c38", - "version" : "0.3.1" - } - } - ], - "version" : 3 -} diff --git a/Swabble/Package.swift b/Swabble/Package.swift deleted file mode 100644 index 9f5a000361..0000000000 --- a/Swabble/Package.swift +++ /dev/null @@ -1,55 +0,0 @@ -// swift-tools-version: 6.2 -import PackageDescription - -let package = Package( - name: "swabble", - platforms: [ - .macOS(.v15), - .iOS(.v17), - ], - products: [ - .library(name: "Swabble", targets: ["Swabble"]), - .library(name: "SwabbleKit", targets: ["SwabbleKit"]), - .executable(name: "swabble", targets: ["SwabbleCLI"]), - ], - dependencies: [ - .package(url: "https://github.com/steipete/Commander.git", exact: "0.2.1"), - .package(url: "https://github.com/apple/swift-testing", from: "0.99.0"), - ], - targets: [ - .target( - name: "Swabble", - path: "Sources/SwabbleCore", - swiftSettings: []), - .target( - name: "SwabbleKit", - path: "Sources/SwabbleKit", - swiftSettings: [ - .enableUpcomingFeature("StrictConcurrency"), - ]), - .executableTarget( - name: "SwabbleCLI", - dependencies: [ - "Swabble", - "SwabbleKit", - .product(name: "Commander", package: "Commander"), - ], - path: "Sources/swabble"), - .testTarget( - name: "SwabbleKitTests", - dependencies: [ - "SwabbleKit", - .product(name: "Testing", package: "swift-testing"), - ], - swiftSettings: [ - .enableUpcomingFeature("StrictConcurrency"), - .enableExperimentalFeature("SwiftTesting"), - ]), - .testTarget( - name: "swabbleTests", - dependencies: [ - "Swabble", - .product(name: "Testing", package: "swift-testing"), - ]), - ], - swiftLanguageModes: [.v6]) diff --git a/Swabble/README.md b/Swabble/README.md deleted file mode 100644 index bf6dc3dc8b..0000000000 --- a/Swabble/README.md +++ /dev/null @@ -1,111 +0,0 @@ -# 🎙️ swabble — Speech.framework wake-word hook daemon (macOS 26) - -swabble is a Swift 6.2 wake-word hook daemon. The CLI targets macOS 26 (SpeechAnalyzer + SpeechTranscriber). The shared `SwabbleKit` target is multi-platform and exposes wake-word gating utilities for iOS/macOS apps. - -- **Local-only**: Speech.framework on-device models; zero network usage. -- **Wake word**: Default `clawd` (aliases `claude`), optional `--no-wake` bypass. -- **SwabbleKit**: Shared wake gate utilities (gap-based gating when you provide speech segments). -- **Hooks**: Run any command with prefix/env, cooldown, min_chars, timeout. -- **Services**: launchd helper stubs for start/stop/install. -- **File transcribe**: TXT or SRT with time ranges (using AttributedString splits). - -## Quick start -```bash -# Install deps -brew install swiftformat swiftlint - -# Build -swift build - -# Write default config (~/.config/swabble/config.json) -swift run swabble setup - -# Run foreground daemon -swift run swabble serve - -# Test your hook -swift run swabble test-hook "hello world" - -# Transcribe a file to SRT -swift run swabble transcribe /path/to/audio.m4a --format srt --output out.srt -``` - -## Use as a library -Add swabble as a SwiftPM dependency and import the `Swabble` or `SwabbleKit` product: - -```swift -// Package.swift -dependencies: [ - .package(url: "https://github.com/steipete/swabble.git", branch: "main"), -], -targets: [ - .target(name: "MyApp", dependencies: [ - .product(name: "Swabble", package: "swabble"), // Speech pipeline (macOS 26+ / iOS 26+) - .product(name: "SwabbleKit", package: "swabble"), // Wake-word gate utilities (iOS 17+ / macOS 15+) - ]), -] -``` - -## CLI -- `serve` — foreground loop (mic → wake → hook) -- `transcribe ` — offline transcription (txt|srt) -- `test-hook "text"` — invoke configured hook -- `mic list|set ` — enumerate/select input device -- `setup` — write default config JSON -- `doctor` — check Speech auth & device availability -- `health` — prints `ok` -- `tail-log` — last 10 transcripts -- `status` — show wake state + recent transcripts -- `service install|uninstall|status` — user launchd plist (stub: prints launchctl commands) -- `start|stop|restart` — placeholders until full launchd wiring - -All commands accept Commander runtime flags (`-v/--verbose`, `--json-output`, `--log-level`), plus `--config` where applicable. - -## Config -`~/.config/swabble/config.json` (auto-created by `setup`): -```json -{ - "audio": {"deviceName": "", "deviceIndex": -1, "sampleRate": 16000, "channels": 1}, - "wake": {"enabled": true, "word": "clawd", "aliases": ["claude"]}, - "hook": { - "command": "", - "args": [], - "prefix": "Voice swabble from ${hostname}: ", - "cooldownSeconds": 1, - "minCharacters": 24, - "timeoutSeconds": 5, - "env": {} - }, - "logging": {"level": "info", "format": "text"}, - "transcripts": {"enabled": true, "maxEntries": 50}, - "speech": {"localeIdentifier": "en_US", "etiquetteReplacements": false} -} -``` - -- Config path override: `--config /path/to/config.json` on relevant commands. -- Transcripts persist to `~/Library/Application Support/swabble/transcripts.log`. - -## Hook protocol -When a wake-gated transcript passes min_chars & cooldown, swabble runs: -``` - "" -``` -Environment variables: -- `SWABBLE_TEXT` — stripped transcript (wake word removed) -- `SWABBLE_PREFIX` — rendered prefix (hostname substituted) -- plus any `hook.env` key/values - -## Speech pipeline -- `AVAudioEngine` tap → `BufferConverter` → `AnalyzerInput` → `SpeechAnalyzer` with a `SpeechTranscriber` module. -- Requests volatile + final results; the CLI uses text-only wake gating today. -- Authorization requested at first start; requires macOS 26 + new Speech.framework APIs. - -## Development -- Format: `./scripts/format.sh` (uses local `.swiftformat`) -- Lint: `./scripts/lint.sh` (uses local `.swiftlint.yml`) -- Tests: `swift test` (uses swift-testing package) - -## Roadmap -- launchd control (load/bootout, PID + status socket) -- JSON logging + PII redaction toggle -- Stronger wake-word detection and control socket status/health diff --git a/Swabble/Sources/SwabbleCore/Config/Config.swift b/Swabble/Sources/SwabbleCore/Config/Config.swift deleted file mode 100644 index 4dc9d4668c..0000000000 --- a/Swabble/Sources/SwabbleCore/Config/Config.swift +++ /dev/null @@ -1,77 +0,0 @@ -import Foundation - -public struct SwabbleConfig: Codable, Sendable { - public struct Audio: Codable, Sendable { - public var deviceName: String = "" - public var deviceIndex: Int = -1 - public var sampleRate: Double = 16000 - public var channels: Int = 1 - } - - public struct Wake: Codable, Sendable { - public var enabled: Bool = true - public var word: String = "clawd" - public var aliases: [String] = ["claude"] - } - - public struct Hook: Codable, Sendable { - public var command: String = "" - public var args: [String] = [] - public var prefix: String = "Voice swabble from ${hostname}: " - public var cooldownSeconds: Double = 1 - public var minCharacters: Int = 24 - public var timeoutSeconds: Double = 5 - public var env: [String: String] = [:] - } - - public struct Logging: Codable, Sendable { - public var level: String = "info" - public var format: String = "text" // text|json placeholder - } - - public struct Transcripts: Codable, Sendable { - public var enabled: Bool = true - public var maxEntries: Int = 50 - } - - public struct Speech: Codable, Sendable { - public var localeIdentifier: String = Locale.current.identifier - public var etiquetteReplacements: Bool = false - } - - public var audio = Audio() - public var wake = Wake() - public var hook = Hook() - public var logging = Logging() - public var transcripts = Transcripts() - public var speech = Speech() - - public static let defaultPath = FileManager.default - .homeDirectoryForCurrentUser - .appendingPathComponent(".config/swabble/config.json") - - public init() {} -} - -public enum ConfigError: Error { - case missingConfig -} - -public enum ConfigLoader { - public static func load(at path: URL?) throws -> SwabbleConfig { - let url = path ?? SwabbleConfig.defaultPath - if !FileManager.default.fileExists(atPath: url.path) { - throw ConfigError.missingConfig - } - let data = try Data(contentsOf: url) - return try JSONDecoder().decode(SwabbleConfig.self, from: data) - } - - public static func save(_ config: SwabbleConfig, at path: URL?) throws { - let url = path ?? SwabbleConfig.defaultPath - let dir = url.deletingLastPathComponent() - try FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true) - let data = try JSONEncoder().encode(config) - try data.write(to: url) - } -} diff --git a/Swabble/Sources/SwabbleCore/Hooks/HookExecutor.swift b/Swabble/Sources/SwabbleCore/Hooks/HookExecutor.swift deleted file mode 100644 index dd59c43bb5..0000000000 --- a/Swabble/Sources/SwabbleCore/Hooks/HookExecutor.swift +++ /dev/null @@ -1,75 +0,0 @@ -import Foundation - -public struct HookJob: Sendable { - public let text: String - public let timestamp: Date - - public init(text: String, timestamp: Date) { - self.text = text - self.timestamp = timestamp - } -} - -public actor HookExecutor { - private let config: SwabbleConfig - private var lastRun: Date? - private let hostname: String - - public init(config: SwabbleConfig) { - self.config = config - hostname = Host.current().localizedName ?? "host" - } - - public func shouldRun() -> Bool { - guard config.hook.cooldownSeconds > 0 else { return true } - if let lastRun, Date().timeIntervalSince(lastRun) < config.hook.cooldownSeconds { - return false - } - return true - } - - public func run(job: HookJob) async throws { - guard shouldRun() else { return } - guard !config.hook.command.isEmpty else { throw NSError( - domain: "Hook", - code: 1, - userInfo: [NSLocalizedDescriptionKey: "hook command not set"]) } - - let prefix = config.hook.prefix.replacingOccurrences(of: "${hostname}", with: hostname) - let payload = prefix + job.text - - let process = Process() - process.executableURL = URL(fileURLWithPath: config.hook.command) - process.arguments = config.hook.args + [payload] - - var env = ProcessInfo.processInfo.environment - env["SWABBLE_TEXT"] = job.text - env["SWABBLE_PREFIX"] = prefix - for (k, v) in config.hook.env { - env[k] = v - } - process.environment = env - - let pipe = Pipe() - process.standardOutput = pipe - process.standardError = pipe - - try process.run() - - let timeoutNanos = UInt64(max(config.hook.timeoutSeconds, 0.1) * 1_000_000_000) - try await withThrowingTaskGroup(of: Void.self) { group in - group.addTask { - process.waitUntilExit() - } - group.addTask { - try await Task.sleep(nanoseconds: timeoutNanos) - if process.isRunning { - process.terminate() - } - } - try await group.next() - group.cancelAll() - } - lastRun = Date() - } -} diff --git a/Swabble/Sources/SwabbleCore/Speech/BufferConverter.swift b/Swabble/Sources/SwabbleCore/Speech/BufferConverter.swift deleted file mode 100644 index e6d7dc993b..0000000000 --- a/Swabble/Sources/SwabbleCore/Speech/BufferConverter.swift +++ /dev/null @@ -1,50 +0,0 @@ -@preconcurrency import AVFoundation -import Foundation - -final class BufferConverter { - private final class Box: @unchecked Sendable { var value: T; init(_ value: T) { self.value = value } } - enum ConverterError: Swift.Error { - case failedToCreateConverter - case failedToCreateConversionBuffer - case conversionFailed(NSError?) - } - - private var converter: AVAudioConverter? - - func convert(_ buffer: AVAudioPCMBuffer, to format: AVAudioFormat) throws -> AVAudioPCMBuffer { - let inputFormat = buffer.format - if inputFormat == format { - return buffer - } - if converter == nil || converter?.outputFormat != format { - converter = AVAudioConverter(from: inputFormat, to: format) - converter?.primeMethod = .none - } - guard let converter else { throw ConverterError.failedToCreateConverter } - - let sampleRateRatio = converter.outputFormat.sampleRate / converter.inputFormat.sampleRate - let scaledInputFrameLength = Double(buffer.frameLength) * sampleRateRatio - let frameCapacity = AVAudioFrameCount(scaledInputFrameLength.rounded(.up)) - guard let conversionBuffer = AVAudioPCMBuffer(pcmFormat: converter.outputFormat, frameCapacity: frameCapacity) - else { - throw ConverterError.failedToCreateConversionBuffer - } - - var nsError: NSError? - let consumed = Box(false) - let inputBuffer = buffer - let status = converter.convert(to: conversionBuffer, error: &nsError) { _, statusPtr in - if consumed.value { - statusPtr.pointee = .noDataNow - return nil - } - consumed.value = true - statusPtr.pointee = .haveData - return inputBuffer - } - if status == .error { - throw ConverterError.conversionFailed(nsError) - } - return conversionBuffer - } -} diff --git a/Swabble/Sources/SwabbleCore/Speech/SpeechPipeline.swift b/Swabble/Sources/SwabbleCore/Speech/SpeechPipeline.swift deleted file mode 100644 index 014b174da7..0000000000 --- a/Swabble/Sources/SwabbleCore/Speech/SpeechPipeline.swift +++ /dev/null @@ -1,114 +0,0 @@ -import AVFoundation -import Foundation -import Speech - -@available(macOS 26.0, iOS 26.0, *) -public struct SpeechSegment: Sendable { - public let text: String - public let isFinal: Bool -} - -@available(macOS 26.0, iOS 26.0, *) -public enum SpeechPipelineError: Error { - case authorizationDenied - case analyzerFormatUnavailable - case transcriberUnavailable -} - -/// Live microphone → SpeechAnalyzer → SpeechTranscriber pipeline. -@available(macOS 26.0, iOS 26.0, *) -public actor SpeechPipeline { - private struct UnsafeBuffer: @unchecked Sendable { let buffer: AVAudioPCMBuffer } - - private var engine = AVAudioEngine() - private var transcriber: SpeechTranscriber? - private var analyzer: SpeechAnalyzer? - private var inputContinuation: AsyncStream.Continuation? - private var resultTask: Task? - private let converter = BufferConverter() - - public init() {} - - public func start(localeIdentifier: String, etiquette: Bool) async throws -> AsyncStream { - let auth = await requestAuthorizationIfNeeded() - guard auth == .authorized else { throw SpeechPipelineError.authorizationDenied } - - let transcriberModule = SpeechTranscriber( - locale: Locale(identifier: localeIdentifier), - transcriptionOptions: etiquette ? [.etiquetteReplacements] : [], - reportingOptions: [.volatileResults], - attributeOptions: []) - transcriber = transcriberModule - - guard let analyzerFormat = await SpeechAnalyzer.bestAvailableAudioFormat(compatibleWith: [transcriberModule]) - else { - throw SpeechPipelineError.analyzerFormatUnavailable - } - - analyzer = SpeechAnalyzer(modules: [transcriberModule]) - let (stream, continuation) = AsyncStream.makeStream() - inputContinuation = continuation - - let inputNode = engine.inputNode - let inputFormat = inputNode.outputFormat(forBus: 0) - inputNode.removeTap(onBus: 0) - inputNode.installTap(onBus: 0, bufferSize: 2048, format: inputFormat) { [weak self] buffer, _ in - guard let self else { return } - let boxed = UnsafeBuffer(buffer: buffer) - Task { await self.handleBuffer(boxed.buffer, targetFormat: analyzerFormat) } - } - - engine.prepare() - try engine.start() - try await analyzer?.start(inputSequence: stream) - - guard let transcriberForStream = transcriber else { - throw SpeechPipelineError.transcriberUnavailable - } - - return AsyncStream { continuation in - self.resultTask = Task { - do { - for try await result in transcriberForStream.results { - let seg = SpeechSegment(text: String(result.text.characters), isFinal: result.isFinal) - continuation.yield(seg) - } - } catch { - // swallow errors and finish - } - continuation.finish() - } - continuation.onTermination = { _ in - Task { await self.stop() } - } - } - } - - public func stop() async { - resultTask?.cancel() - inputContinuation?.finish() - engine.inputNode.removeTap(onBus: 0) - engine.stop() - try? await analyzer?.finalizeAndFinishThroughEndOfInput() - } - - private func handleBuffer(_ buffer: AVAudioPCMBuffer, targetFormat: AVAudioFormat) async { - do { - let converted = try converter.convert(buffer, to: targetFormat) - let input = AnalyzerInput(buffer: converted) - inputContinuation?.yield(input) - } catch { - // drop on conversion failure - } - } - - private func requestAuthorizationIfNeeded() async -> SFSpeechRecognizerAuthorizationStatus { - let current = SFSpeechRecognizer.authorizationStatus() - guard current == .notDetermined else { return current } - return await withCheckedContinuation { continuation in - SFSpeechRecognizer.requestAuthorization { status in - continuation.resume(returning: status) - } - } - } -} diff --git a/Swabble/Sources/SwabbleCore/Support/AttributedString+Sentences.swift b/Swabble/Sources/SwabbleCore/Support/AttributedString+Sentences.swift deleted file mode 100644 index e2de6fdfce..0000000000 --- a/Swabble/Sources/SwabbleCore/Support/AttributedString+Sentences.swift +++ /dev/null @@ -1,62 +0,0 @@ -import CoreMedia -import Foundation -import NaturalLanguage - -extension AttributedString { - public func sentences(maxLength: Int? = nil) -> [AttributedString] { - let tokenizer = NLTokenizer(unit: .sentence) - let string = String(characters) - tokenizer.string = string - let sentenceRanges = tokenizer.tokens(for: string.startIndex.. maxLength else { - return [sentenceRange] - } - - let wordTokenizer = NLTokenizer(unit: .word) - wordTokenizer.string = string - var wordRanges = wordTokenizer.tokens(for: sentenceStringRange).map { - AttributedString.Index($0.lowerBound, within: self)! - ..< - AttributedString.Index($0.upperBound, within: self)! - } - guard !wordRanges.isEmpty else { return [sentenceRange] } - wordRanges[0] = sentenceRange.lowerBound..] = [] - for wordRange in wordRanges { - if let lastRange = ranges.last, - self[lastRange].characters.count + self[wordRange].characters.count <= maxLength { - ranges[ranges.count - 1] = lastRange.lowerBound.. Bool { lhs.rank < rhs.rank } -} - -public struct Logger: Sendable { - public let level: LogLevel - - public init(level: LogLevel) { self.level = level } - - public func log(_ level: LogLevel, _ message: String) { - guard level >= self.level else { return } - let ts = ISO8601DateFormatter().string(from: Date()) - print("[\(level.rawValue.uppercased())] \(ts) | \(message)") - } - - public func trace(_ msg: String) { log(.trace, msg) } - public func debug(_ msg: String) { log(.debug, msg) } - public func info(_ msg: String) { log(.info, msg) } - public func warn(_ msg: String) { log(.warn, msg) } - public func error(_ msg: String) { log(.error, msg) } -} - -extension LogLevel { - public init?(configValue: String) { - self.init(rawValue: configValue.lowercased()) - } -} diff --git a/Swabble/Sources/SwabbleCore/Support/OutputFormat.swift b/Swabble/Sources/SwabbleCore/Support/OutputFormat.swift deleted file mode 100644 index 84047c7284..0000000000 --- a/Swabble/Sources/SwabbleCore/Support/OutputFormat.swift +++ /dev/null @@ -1,45 +0,0 @@ -import CoreMedia -import Foundation - -public enum OutputFormat: String { - case txt - case srt - - public var needsAudioTimeRange: Bool { - switch self { - case .srt: true - default: false - } - } - - public func text(for transcript: AttributedString, maxLength: Int) -> String { - switch self { - case .txt: - return String(transcript.characters) - case .srt: - func format(_ timeInterval: TimeInterval) -> String { - let ms = Int(timeInterval.truncatingRemainder(dividingBy: 1) * 1000) - let s = Int(timeInterval) % 60 - let m = (Int(timeInterval) / 60) % 60 - let h = Int(timeInterval) / 60 / 60 - return String(format: "%0.2d:%0.2d:%0.2d,%0.3d", h, m, s, ms) - } - - return transcript.sentences(maxLength: maxLength).compactMap { (sentence: AttributedString) -> ( - CMTimeRange, - String)? in - guard let timeRange = sentence.audioTimeRange else { return nil } - return (timeRange, String(sentence.characters)) - }.enumerated().map { index, run in - let (timeRange, text) = run - return """ - - \(index + 1) - \(format(timeRange.start.seconds)) --> \(format(timeRange.end.seconds)) - \(text.trimmingCharacters(in: .whitespacesAndNewlines)) - - """ - }.joined().trimmingCharacters(in: .whitespacesAndNewlines) - } - } -} diff --git a/Swabble/Sources/SwabbleCore/Support/TranscriptsStore.swift b/Swabble/Sources/SwabbleCore/Support/TranscriptsStore.swift deleted file mode 100644 index 4f91d052e6..0000000000 --- a/Swabble/Sources/SwabbleCore/Support/TranscriptsStore.swift +++ /dev/null @@ -1,45 +0,0 @@ -import Foundation - -public actor TranscriptsStore { - public static let shared = TranscriptsStore() - - private var entries: [String] = [] - private let limit = 100 - private let fileURL: URL - - public init() { - let dir = FileManager.default.homeDirectoryForCurrentUser - .appendingPathComponent("Library/Application Support/swabble", isDirectory: true) - try? FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true) - fileURL = dir.appendingPathComponent("transcripts.log") - if let data = try? Data(contentsOf: fileURL), - let text = String(data: data, encoding: .utf8) { - entries = text.split(separator: "\n").map(String.init).suffix(limit) - } - } - - public func append(text: String) { - entries.append(text) - if entries.count > limit { - entries.removeFirst(entries.count - limit) - } - let body = entries.joined(separator: "\n") - try? body.write(to: fileURL, atomically: false, encoding: .utf8) - } - - public func latest() -> [String] { entries } -} - -extension String { - private func appendLine(to url: URL) throws { - let data = (self + "\n").data(using: .utf8) ?? Data() - if FileManager.default.fileExists(atPath: url.path) { - let handle = try FileHandle(forWritingTo: url) - try handle.seekToEnd() - try handle.write(contentsOf: data) - try handle.close() - } else { - try data.write(to: url) - } - } -} diff --git a/Swabble/Sources/SwabbleKit/WakeWordGate.swift b/Swabble/Sources/SwabbleKit/WakeWordGate.swift deleted file mode 100644 index 27c952a8d1..0000000000 --- a/Swabble/Sources/SwabbleKit/WakeWordGate.swift +++ /dev/null @@ -1,197 +0,0 @@ -import Foundation - -public struct WakeWordSegment: Sendable, Equatable { - public let text: String - public let start: TimeInterval - public let duration: TimeInterval - public let range: Range? - - public init(text: String, start: TimeInterval, duration: TimeInterval, range: Range? = nil) { - self.text = text - self.start = start - self.duration = duration - self.range = range - } - - public var end: TimeInterval { start + duration } -} - -public struct WakeWordGateConfig: Sendable, Equatable { - public var triggers: [String] - public var minPostTriggerGap: TimeInterval - public var minCommandLength: Int - - public init( - triggers: [String], - minPostTriggerGap: TimeInterval = 0.45, - minCommandLength: Int = 1) { - self.triggers = triggers - self.minPostTriggerGap = minPostTriggerGap - self.minCommandLength = minCommandLength - } -} - -public struct WakeWordGateMatch: Sendable, Equatable { - public let triggerEndTime: TimeInterval - public let postGap: TimeInterval - public let command: String - - public init(triggerEndTime: TimeInterval, postGap: TimeInterval, command: String) { - self.triggerEndTime = triggerEndTime - self.postGap = postGap - self.command = command - } -} - -public enum WakeWordGate { - private struct Token { - let normalized: String - let start: TimeInterval - let end: TimeInterval - let range: Range? - let text: String - } - - private struct TriggerTokens { - let tokens: [String] - } - - private struct MatchCandidate { - let index: Int - let triggerEnd: TimeInterval - let gap: TimeInterval - } - - public static func match( - transcript: String, - segments: [WakeWordSegment], - config: WakeWordGateConfig) - -> WakeWordGateMatch? { - let triggerTokens = normalizeTriggers(config.triggers) - guard !triggerTokens.isEmpty else { return nil } - - let tokens = normalizeSegments(segments) - guard !tokens.isEmpty else { return nil } - - var best: MatchCandidate? - - for trigger in triggerTokens { - let count = trigger.tokens.count - guard count > 0, tokens.count > count else { continue } - for i in 0...(tokens.count - count - 1) { - let matched = (0..= config.minCommandLength else { return nil } - return WakeWordGateMatch(triggerEndTime: best.triggerEnd, postGap: best.gap, command: command) - } - - public static func commandText( - transcript: String, - segments: [WakeWordSegment], - triggerEndTime: TimeInterval) - -> String { - let threshold = triggerEndTime + 0.001 - for segment in segments where segment.start >= threshold { - if normalizeToken(segment.text).isEmpty { continue } - if let range = segment.range { - let slice = transcript[range.lowerBound...] - return String(slice).trimmingCharacters(in: Self.whitespaceAndPunctuation) - } - break - } - - let text = segments - .filter { $0.start >= threshold && !normalizeToken($0.text).isEmpty } - .map(\.text) - .joined(separator: " ") - return text.trimmingCharacters(in: Self.whitespaceAndPunctuation) - } - - public static func matchesTextOnly(text: String, triggers: [String]) -> Bool { - guard !text.isEmpty else { return false } - let normalized = text.lowercased() - for trigger in triggers { - let token = trigger.trimmingCharacters(in: whitespaceAndPunctuation).lowercased() - if token.isEmpty { continue } - if normalized.contains(token) { return true } - } - return false - } - - public static func stripWake(text: String, triggers: [String]) -> String { - var out = text - for trigger in triggers { - let token = trigger.trimmingCharacters(in: whitespaceAndPunctuation) - guard !token.isEmpty else { continue } - out = out.replacingOccurrences(of: token, with: "", options: [.caseInsensitive]) - } - return out.trimmingCharacters(in: whitespaceAndPunctuation) - } - - private static func normalizeTriggers(_ triggers: [String]) -> [TriggerTokens] { - var output: [TriggerTokens] = [] - for trigger in triggers { - let tokens = trigger - .split(whereSeparator: { $0.isWhitespace }) - .map { normalizeToken(String($0)) } - .filter { !$0.isEmpty } - if tokens.isEmpty { continue } - output.append(TriggerTokens(tokens: tokens)) - } - return output - } - - private static func normalizeSegments(_ segments: [WakeWordSegment]) -> [Token] { - segments.compactMap { segment in - let normalized = normalizeToken(segment.text) - guard !normalized.isEmpty else { return nil } - return Token( - normalized: normalized, - start: segment.start, - end: segment.end, - range: segment.range, - text: segment.text) - } - } - - private static func normalizeToken(_ token: String) -> String { - token - .trimmingCharacters(in: whitespaceAndPunctuation) - .lowercased() - } - - private static let whitespaceAndPunctuation = CharacterSet.whitespacesAndNewlines - .union(.punctuationCharacters) -} - -#if canImport(Speech) -import Speech - -public enum WakeWordSpeechSegments { - public static func from(transcription: SFTranscription, transcript: String) -> [WakeWordSegment] { - transcription.segments.map { segment in - let range = Range(segment.substringRange, in: transcript) - return WakeWordSegment( - text: segment.substring, - start: segment.timestamp, - duration: segment.duration, - range: range) - } - } -} -#endif diff --git a/Swabble/Sources/swabble/CLI/CLIRegistry.swift b/Swabble/Sources/swabble/CLI/CLIRegistry.swift deleted file mode 100644 index c47a9864f9..0000000000 --- a/Swabble/Sources/swabble/CLI/CLIRegistry.swift +++ /dev/null @@ -1,71 +0,0 @@ -import Commander -import Foundation - -@available(macOS 26.0, *) -@MainActor -enum CLIRegistry { - static var descriptors: [CommandDescriptor] { - let serveDesc = descriptor(for: ServeCommand.self) - let transcribeDesc = descriptor(for: TranscribeCommand.self) - let testHookDesc = descriptor(for: TestHookCommand.self) - let micList = descriptor(for: MicList.self) - let micSet = descriptor(for: MicSet.self) - let micRoot = CommandDescriptor( - name: "mic", - abstract: "Microphone management", - discussion: nil, - signature: CommandSignature(), - subcommands: [micList, micSet]) - let serviceRoot = CommandDescriptor( - name: "service", - abstract: "launchd helper", - discussion: nil, - signature: CommandSignature(), - subcommands: [ - descriptor(for: ServiceInstall.self), - descriptor(for: ServiceUninstall.self), - descriptor(for: ServiceStatus.self) - ]) - let doctorDesc = descriptor(for: DoctorCommand.self) - let setupDesc = descriptor(for: SetupCommand.self) - let healthDesc = descriptor(for: HealthCommand.self) - let tailLogDesc = descriptor(for: TailLogCommand.self) - let startDesc = descriptor(for: StartCommand.self) - let stopDesc = descriptor(for: StopCommand.self) - let restartDesc = descriptor(for: RestartCommand.self) - let statusDesc = descriptor(for: StatusCommand.self) - - let rootSignature = CommandSignature().withStandardRuntimeFlags() - let root = CommandDescriptor( - name: "swabble", - abstract: "Speech hook daemon", - discussion: "Local wake-word → SpeechTranscriber → hook", - signature: rootSignature, - subcommands: [ - serveDesc, - transcribeDesc, - testHookDesc, - micRoot, - serviceRoot, - doctorDesc, - setupDesc, - healthDesc, - tailLogDesc, - startDesc, - stopDesc, - restartDesc, - statusDesc - ]) - return [root] - } - - private static func descriptor(for type: any ParsableCommand.Type) -> CommandDescriptor { - let sig = CommandSignature.describe(type.init()).withStandardRuntimeFlags() - return CommandDescriptor( - name: type.commandDescription.commandName ?? "", - abstract: type.commandDescription.abstract, - discussion: type.commandDescription.discussion, - signature: sig, - subcommands: []) - } -} diff --git a/Swabble/Sources/swabble/Commands/DoctorCommand.swift b/Swabble/Sources/swabble/Commands/DoctorCommand.swift deleted file mode 100644 index ec6c84ad44..0000000000 --- a/Swabble/Sources/swabble/Commands/DoctorCommand.swift +++ /dev/null @@ -1,37 +0,0 @@ -import Commander -import Foundation -import Speech -import Swabble - -@MainActor -struct DoctorCommand: ParsableCommand { - static var commandDescription: CommandDescription { - CommandDescription(commandName: "doctor", abstract: "Check Speech permission and config") - } - - @Option(name: .long("config"), help: "Path to config JSON") var configPath: String? - - init() {} - init(parsed: ParsedValues) { - self.init() - if let cfg = parsed.options["config"]?.last { configPath = cfg } - } - - mutating func run() async throws { - let auth = await SFSpeechRecognizer.authorizationStatus() - print("Speech auth: \(auth)") - do { - _ = try ConfigLoader.load(at: configURL) - print("Config: OK") - } catch { - print("Config missing or invalid; run setup") - } - let session = AVCaptureDevice.DiscoverySession( - deviceTypes: [.microphone, .external], - mediaType: .audio, - position: .unspecified) - print("Mics found: \(session.devices.count)") - } - - private var configURL: URL? { configPath.map { URL(fileURLWithPath: $0) } } -} diff --git a/Swabble/Sources/swabble/Commands/HealthCommand.swift b/Swabble/Sources/swabble/Commands/HealthCommand.swift deleted file mode 100644 index b3db452868..0000000000 --- a/Swabble/Sources/swabble/Commands/HealthCommand.swift +++ /dev/null @@ -1,16 +0,0 @@ -import Commander -import Foundation - -@MainActor -struct HealthCommand: ParsableCommand { - static var commandDescription: CommandDescription { - CommandDescription(commandName: "health", abstract: "Health probe") - } - - init() {} - init(parsed: ParsedValues) {} - - mutating func run() async throws { - print("ok") - } -} diff --git a/Swabble/Sources/swabble/Commands/MicCommands.swift b/Swabble/Sources/swabble/Commands/MicCommands.swift deleted file mode 100644 index 6430c86d52..0000000000 --- a/Swabble/Sources/swabble/Commands/MicCommands.swift +++ /dev/null @@ -1,62 +0,0 @@ -import AVFoundation -import Commander -import Foundation -import Swabble - -@MainActor -struct MicCommand: ParsableCommand { - static var commandDescription: CommandDescription { - CommandDescription( - commandName: "mic", - abstract: "Microphone management", - subcommands: [MicList.self, MicSet.self]) - } -} - -@MainActor -struct MicList: ParsableCommand { - static var commandDescription: CommandDescription { - CommandDescription(commandName: "list", abstract: "List input devices") - } - - init() {} - init(parsed: ParsedValues) {} - - mutating func run() async throws { - let session = AVCaptureDevice.DiscoverySession( - deviceTypes: [.microphone, .external], - mediaType: .audio, - position: .unspecified) - let devices = session.devices - if devices.isEmpty { print("no audio inputs found"); return } - for (idx, device) in devices.enumerated() { - print("[\(idx)] \(device.localizedName)") - } - } -} - -@MainActor -struct MicSet: ParsableCommand { - @Argument(help: "Device index from list") var index: Int = 0 - @Option(name: .long("config"), help: "Path to config JSON") var configPath: String? - - static var commandDescription: CommandDescription { - CommandDescription(commandName: "set", abstract: "Set default input device index") - } - - init() {} - init(parsed: ParsedValues) { - self.init() - if let value = parsed.positional.first, let intVal = Int(value) { index = intVal } - if let cfg = parsed.options["config"]?.last { configPath = cfg } - } - - mutating func run() async throws { - var cfg = try ConfigLoader.load(at: configURL) - cfg.audio.deviceIndex = index - try ConfigLoader.save(cfg, at: configURL) - print("saved device index \(index)") - } - - private var configURL: URL? { configPath.map { URL(fileURLWithPath: $0) } } -} diff --git a/Swabble/Sources/swabble/Commands/ServeCommand.swift b/Swabble/Sources/swabble/Commands/ServeCommand.swift deleted file mode 100644 index 705ecf41a6..0000000000 --- a/Swabble/Sources/swabble/Commands/ServeCommand.swift +++ /dev/null @@ -1,81 +0,0 @@ -import Commander -import Foundation -import Swabble -import SwabbleKit - -@available(macOS 26.0, *) -@MainActor -struct ServeCommand: ParsableCommand { - @Option(name: .long("config"), help: "Path to config JSON") var configPath: String? - @Flag(name: .long("no-wake"), help: "Disable wake word") var noWake: Bool = false - - static var commandDescription: CommandDescription { - CommandDescription( - commandName: "serve", - abstract: "Run swabble in the foreground") - } - - init() {} - - init(parsed: ParsedValues) { - self.init() - if parsed.flags.contains("noWake") { noWake = true } - if let cfg = parsed.options["config"]?.last { configPath = cfg } - } - - mutating func run() async throws { - var cfg: SwabbleConfig - do { - cfg = try ConfigLoader.load(at: configURL) - } catch { - cfg = SwabbleConfig() - try ConfigLoader.save(cfg, at: configURL) - } - if noWake { - cfg.wake.enabled = false - } - - let logger = Logger(level: LogLevel(configValue: cfg.logging.level) ?? .info) - logger.info("swabble serve starting (wake: \(cfg.wake.enabled ? cfg.wake.word : "disabled"))") - let pipeline = SpeechPipeline() - do { - let stream = try await pipeline.start( - localeIdentifier: cfg.speech.localeIdentifier, - etiquette: cfg.speech.etiquetteReplacements) - for await seg in stream { - if cfg.wake.enabled { - guard Self.matchesWake(text: seg.text, cfg: cfg) else { continue } - } - let stripped = Self.stripWake(text: seg.text, cfg: cfg) - let job = HookJob(text: stripped, timestamp: Date()) - let executor = HookExecutor(config: cfg) - try await executor.run(job: job) - if cfg.transcripts.enabled { - await TranscriptsStore.shared.append(text: stripped) - } - if seg.isFinal { - logger.info("final: \(stripped)") - } else { - logger.debug("partial: \(stripped)") - } - } - } catch { - logger.error("serve error: \(error)") - throw error - } - } - - private var configURL: URL? { - configPath.map { URL(fileURLWithPath: $0) } - } - - private static func matchesWake(text: String, cfg: SwabbleConfig) -> Bool { - let triggers = [cfg.wake.word] + cfg.wake.aliases - return WakeWordGate.matchesTextOnly(text: text, triggers: triggers) - } - - private static func stripWake(text: String, cfg: SwabbleConfig) -> String { - let triggers = [cfg.wake.word] + cfg.wake.aliases - return WakeWordGate.stripWake(text: text, triggers: triggers) - } -} diff --git a/Swabble/Sources/swabble/Commands/ServiceCommands.swift b/Swabble/Sources/swabble/Commands/ServiceCommands.swift deleted file mode 100644 index 8690e95628..0000000000 --- a/Swabble/Sources/swabble/Commands/ServiceCommands.swift +++ /dev/null @@ -1,77 +0,0 @@ -import Commander -import Foundation - -@MainActor -struct ServiceRootCommand: ParsableCommand { - static var commandDescription: CommandDescription { - CommandDescription( - commandName: "service", - abstract: "Manage launchd agent", - subcommands: [ServiceInstall.self, ServiceUninstall.self, ServiceStatus.self]) - } -} - -private enum LaunchdHelper { - static let label = "com.swabble.agent" - - static var plistURL: URL { - FileManager.default - .homeDirectoryForCurrentUser - .appendingPathComponent("Library/LaunchAgents/\(label).plist") - } - - static func writePlist(executable: String) throws { - let plist: [String: Any] = [ - "Label": label, - "ProgramArguments": [executable, "serve"], - "RunAtLoad": true, - "KeepAlive": true - ] - let data = try PropertyListSerialization.data(fromPropertyList: plist, format: .xml, options: 0) - try data.write(to: plistURL) - } - - static func removePlist() throws { - try? FileManager.default.removeItem(at: plistURL) - } -} - -@MainActor -struct ServiceInstall: ParsableCommand { - static var commandDescription: CommandDescription { - CommandDescription(commandName: "install", abstract: "Install user launch agent") - } - - mutating func run() async throws { - let exe = CommandLine.arguments.first ?? "/usr/local/bin/swabble" - try LaunchdHelper.writePlist(executable: exe) - print("launchctl load -w \(LaunchdHelper.plistURL.path)") - } -} - -@MainActor -struct ServiceUninstall: ParsableCommand { - static var commandDescription: CommandDescription { - CommandDescription(commandName: "uninstall", abstract: "Remove launch agent") - } - - mutating func run() async throws { - try LaunchdHelper.removePlist() - print("launchctl bootout gui/$(id -u)/\(LaunchdHelper.label)") - } -} - -@MainActor -struct ServiceStatus: ParsableCommand { - static var commandDescription: CommandDescription { - CommandDescription(commandName: "status", abstract: "Show launch agent status") - } - - mutating func run() async throws { - if FileManager.default.fileExists(atPath: LaunchdHelper.plistURL.path) { - print("plist present at \(LaunchdHelper.plistURL.path)") - } else { - print("launchd plist not installed") - } - } -} diff --git a/Swabble/Sources/swabble/Commands/SetupCommand.swift b/Swabble/Sources/swabble/Commands/SetupCommand.swift deleted file mode 100644 index 469de233d1..0000000000 --- a/Swabble/Sources/swabble/Commands/SetupCommand.swift +++ /dev/null @@ -1,26 +0,0 @@ -import Commander -import Foundation -import Swabble - -@MainActor -struct SetupCommand: ParsableCommand { - static var commandDescription: CommandDescription { - CommandDescription(commandName: "setup", abstract: "Write default config") - } - - @Option(name: .long("config"), help: "Path to config JSON") var configPath: String? - - init() {} - init(parsed: ParsedValues) { - self.init() - if let cfg = parsed.options["config"]?.last { configPath = cfg } - } - - mutating func run() async throws { - let cfg = SwabbleConfig() - try ConfigLoader.save(cfg, at: configURL) - print("wrote config to \(configURL?.path ?? SwabbleConfig.defaultPath.path)") - } - - private var configURL: URL? { configPath.map { URL(fileURLWithPath: $0) } } -} diff --git a/Swabble/Sources/swabble/Commands/StartStopCommands.swift b/Swabble/Sources/swabble/Commands/StartStopCommands.swift deleted file mode 100644 index 641cd923a0..0000000000 --- a/Swabble/Sources/swabble/Commands/StartStopCommands.swift +++ /dev/null @@ -1,35 +0,0 @@ -import Commander -import Foundation - -@MainActor -struct StartCommand: ParsableCommand { - static var commandDescription: CommandDescription { - CommandDescription(commandName: "start", abstract: "Start swabble (foreground placeholder)") - } - - mutating func run() async throws { - print("start: launchd helper not implemented; run 'swabble serve' instead") - } -} - -@MainActor -struct StopCommand: ParsableCommand { - static var commandDescription: CommandDescription { - CommandDescription(commandName: "stop", abstract: "Stop swabble (placeholder)") - } - - mutating func run() async throws { - print("stop: launchd helper not implemented yet") - } -} - -@MainActor -struct RestartCommand: ParsableCommand { - static var commandDescription: CommandDescription { - CommandDescription(commandName: "restart", abstract: "Restart swabble (placeholder)") - } - - mutating func run() async throws { - print("restart: launchd helper not implemented yet") - } -} diff --git a/Swabble/Sources/swabble/Commands/StatusCommand.swift b/Swabble/Sources/swabble/Commands/StatusCommand.swift deleted file mode 100644 index 19db16117a..0000000000 --- a/Swabble/Sources/swabble/Commands/StatusCommand.swift +++ /dev/null @@ -1,34 +0,0 @@ -import Commander -import Foundation -import Swabble - -@MainActor -struct StatusCommand: ParsableCommand { - static var commandDescription: CommandDescription { - CommandDescription(commandName: "status", abstract: "Show daemon state") - } - - @Option(name: .long("config"), help: "Path to config JSON") var configPath: String? - - init() {} - init(parsed: ParsedValues) { - self.init() - if let cfg = parsed.options["config"]?.last { configPath = cfg } - } - - mutating func run() async throws { - let cfg = try? ConfigLoader.load(at: configURL) - let wake = cfg?.wake.word ?? "clawd" - let wakeEnabled = cfg?.wake.enabled ?? false - let latest = await TranscriptsStore.shared.latest().suffix(3) - print("wake: \(wakeEnabled ? wake : "disabled")") - if latest.isEmpty { - print("transcripts: (none yet)") - } else { - print("last transcripts:") - latest.forEach { print("- \($0)") } - } - } - - private var configURL: URL? { configPath.map { URL(fileURLWithPath: $0) } } -} diff --git a/Swabble/Sources/swabble/Commands/TailLogCommand.swift b/Swabble/Sources/swabble/Commands/TailLogCommand.swift deleted file mode 100644 index 451ed37de4..0000000000 --- a/Swabble/Sources/swabble/Commands/TailLogCommand.swift +++ /dev/null @@ -1,20 +0,0 @@ -import Commander -import Foundation -import Swabble - -@MainActor -struct TailLogCommand: ParsableCommand { - static var commandDescription: CommandDescription { - CommandDescription(commandName: "tail-log", abstract: "Tail recent transcripts") - } - - init() {} - init(parsed: ParsedValues) {} - - mutating func run() async throws { - let latest = await TranscriptsStore.shared.latest() - for line in latest.suffix(10) { - print(line) - } - } -} diff --git a/Swabble/Sources/swabble/Commands/TestHookCommand.swift b/Swabble/Sources/swabble/Commands/TestHookCommand.swift deleted file mode 100644 index 226776ceb8..0000000000 --- a/Swabble/Sources/swabble/Commands/TestHookCommand.swift +++ /dev/null @@ -1,30 +0,0 @@ -import Commander -import Foundation -import Swabble - -@MainActor -struct TestHookCommand: ParsableCommand { - @Argument(help: "Text to send to hook") var text: String - @Option(name: .long("config"), help: "Path to config JSON") var configPath: String? - - static var commandDescription: CommandDescription { - CommandDescription(commandName: "test-hook", abstract: "Invoke the configured hook with text") - } - - init() {} - - init(parsed: ParsedValues) { - self.init() - if let positional = parsed.positional.first { text = positional } - if let cfg = parsed.options["config"]?.last { configPath = cfg } - } - - mutating func run() async throws { - let cfg = try ConfigLoader.load(at: configURL) - let executor = HookExecutor(config: cfg) - try await executor.run(job: HookJob(text: text, timestamp: Date())) - print("hook invoked") - } - - private var configURL: URL? { configPath.map { URL(fileURLWithPath: $0) } } -} diff --git a/Swabble/Sources/swabble/Commands/TranscribeCommand.swift b/Swabble/Sources/swabble/Commands/TranscribeCommand.swift deleted file mode 100644 index 1bedca3fc0..0000000000 --- a/Swabble/Sources/swabble/Commands/TranscribeCommand.swift +++ /dev/null @@ -1,61 +0,0 @@ -import AVFoundation -import Commander -import Foundation -import Speech -import Swabble - -@MainActor -struct TranscribeCommand: ParsableCommand { - @Argument(help: "Path to audio/video file") var inputFile: String = "" - @Option(name: .long("locale"), help: "Locale identifier", parsing: .singleValue) var locale: String = Locale.current - .identifier - @Flag(help: "Censor etiquette-sensitive content") var censor: Bool = false - @Option(name: .long("output"), help: "Output file path") var outputFile: String? - @Option(name: .long("format"), help: "Output format txt|srt") var format: String = "txt" - @Option(name: .long("max-length"), help: "Max sentence length for srt") var maxLength: Int = 40 - - static var commandDescription: CommandDescription { - CommandDescription( - commandName: "transcribe", - abstract: "Transcribe a media file locally") - } - - init() {} - - init(parsed: ParsedValues) { - self.init() - if let positional = parsed.positional.first { inputFile = positional } - if let loc = parsed.options["locale"]?.last { locale = loc } - if parsed.flags.contains("censor") { censor = true } - if let out = parsed.options["output"]?.last { outputFile = out } - if let fmt = parsed.options["format"]?.last { format = fmt } - if let len = parsed.options["maxLength"]?.last, let intVal = Int(len) { maxLength = intVal } - } - - mutating func run() async throws { - let fileURL = URL(fileURLWithPath: inputFile) - let audioFile = try AVAudioFile(forReading: fileURL) - - let outputFormat = OutputFormat(rawValue: format) ?? .txt - - let transcriber = SpeechTranscriber( - locale: Locale(identifier: locale), - transcriptionOptions: censor ? [.etiquetteReplacements] : [], - reportingOptions: [], - attributeOptions: outputFormat.needsAudioTimeRange ? [.audioTimeRange] : []) - let analyzer = SpeechAnalyzer(modules: [transcriber]) - try await analyzer.start(inputAudioFile: audioFile, finishAfterFile: true) - - var transcript: AttributedString = "" - for try await result in transcriber.results { - transcript += result.text - } - - let output = outputFormat.text(for: transcript, maxLength: maxLength) - if let path = outputFile { - try output.write(to: URL(fileURLWithPath: path), atomically: false, encoding: .utf8) - } else { - print(output) - } - } -} diff --git a/Swabble/Sources/swabble/main.swift b/Swabble/Sources/swabble/main.swift deleted file mode 100644 index a534c68d96..0000000000 --- a/Swabble/Sources/swabble/main.swift +++ /dev/null @@ -1,151 +0,0 @@ -import Commander -import Foundation - -@available(macOS 26.0, *) -@MainActor -private func runCLI() async -> Int32 { - do { - let descriptors = CLIRegistry.descriptors - let program = Program(descriptors: descriptors) - let invocation = try program.resolve(argv: CommandLine.arguments) - try await dispatch(invocation: invocation) - return 0 - } catch { - fputs("error: \(error)\n", stderr) - return 1 - } -} - -@available(macOS 26.0, *) -@MainActor -private func dispatch(invocation: CommandInvocation) async throws { - let parsed = invocation.parsedValues - let path = invocation.path - guard let first = path.first else { throw CommanderProgramError.missingCommand } - - switch first { - case "swabble": - try await dispatchSwabble(parsed: parsed, path: path) - default: - throw CommanderProgramError.unknownCommand(first) - } -} - -@available(macOS 26.0, *) -@MainActor -private func dispatchSwabble(parsed: ParsedValues, path: [String]) async throws { - let sub = try subcommand(path, index: 1, command: "swabble") - switch sub { - case "mic": - try await dispatchMic(parsed: parsed, path: path) - case "service": - try await dispatchService(path: path) - default: - let handlers = swabbleHandlers(parsed: parsed) - guard let handler = handlers[sub] else { - throw CommanderProgramError.unknownSubcommand(command: "swabble", name: sub) - } - try await handler() - } -} - -@available(macOS 26.0, *) -@MainActor -private func swabbleHandlers(parsed: ParsedValues) -> [String: () async throws -> Void] { - [ - "serve": { - var cmd = ServeCommand(parsed: parsed) - try await cmd.run() - }, - "transcribe": { - var cmd = TranscribeCommand(parsed: parsed) - try await cmd.run() - }, - "test-hook": { - var cmd = TestHookCommand(parsed: parsed) - try await cmd.run() - }, - "doctor": { - var cmd = DoctorCommand(parsed: parsed) - try await cmd.run() - }, - "setup": { - var cmd = SetupCommand(parsed: parsed) - try await cmd.run() - }, - "health": { - var cmd = HealthCommand(parsed: parsed) - try await cmd.run() - }, - "tail-log": { - var cmd = TailLogCommand(parsed: parsed) - try await cmd.run() - }, - "start": { - var cmd = StartCommand() - try await cmd.run() - }, - "stop": { - var cmd = StopCommand() - try await cmd.run() - }, - "restart": { - var cmd = RestartCommand() - try await cmd.run() - }, - "status": { - var cmd = StatusCommand() - try await cmd.run() - } - ] -} - -@available(macOS 26.0, *) -@MainActor -private func dispatchMic(parsed: ParsedValues, path: [String]) async throws { - let micSub = try subcommand(path, index: 2, command: "mic") - switch micSub { - case "list": - var cmd = MicList(parsed: parsed) - try await cmd.run() - case "set": - var cmd = MicSet(parsed: parsed) - try await cmd.run() - default: - throw CommanderProgramError.unknownSubcommand(command: "mic", name: micSub) - } -} - -@available(macOS 26.0, *) -@MainActor -private func dispatchService(path: [String]) async throws { - let svcSub = try subcommand(path, index: 2, command: "service") - switch svcSub { - case "install": - var cmd = ServiceInstall() - try await cmd.run() - case "uninstall": - var cmd = ServiceUninstall() - try await cmd.run() - case "status": - var cmd = ServiceStatus() - try await cmd.run() - default: - throw CommanderProgramError.unknownSubcommand(command: "service", name: svcSub) - } -} - -private func subcommand(_ path: [String], index: Int, command: String) throws -> String { - guard path.count > index else { - throw CommanderProgramError.missingSubcommand(command: command) - } - return path[index] -} - -if #available(macOS 26.0, *) { - let exitCode = await runCLI() - exit(exitCode) -} else { - fputs("error: swabble requires macOS 26 or newer\n", stderr) - exit(1) -} diff --git a/Swabble/Tests/SwabbleKitTests/WakeWordGateTests.swift b/Swabble/Tests/SwabbleKitTests/WakeWordGateTests.swift deleted file mode 100644 index 5cc283c35a..0000000000 --- a/Swabble/Tests/SwabbleKitTests/WakeWordGateTests.swift +++ /dev/null @@ -1,63 +0,0 @@ -import Foundation -import SwabbleKit -import Testing - -@Suite struct WakeWordGateTests { - @Test func matchRequiresGapAfterTrigger() { - let transcript = "hey clawd do thing" - let segments = makeSegments( - transcript: transcript, - words: [ - ("hey", 0.0, 0.1), - ("clawd", 0.2, 0.1), - ("do", 0.35, 0.1), - ("thing", 0.5, 0.1), - ]) - let config = WakeWordGateConfig(triggers: ["clawd"], minPostTriggerGap: 0.3) - #expect(WakeWordGate.match(transcript: transcript, segments: segments, config: config) == nil) - } - - @Test func matchAllowsGapAndExtractsCommand() { - let transcript = "hey clawd do thing" - let segments = makeSegments( - transcript: transcript, - words: [ - ("hey", 0.0, 0.1), - ("clawd", 0.2, 0.1), - ("do", 0.9, 0.1), - ("thing", 1.1, 0.1), - ]) - let config = WakeWordGateConfig(triggers: ["clawd"], minPostTriggerGap: 0.3) - let match = WakeWordGate.match(transcript: transcript, segments: segments, config: config) - #expect(match?.command == "do thing") - } - - @Test func matchHandlesMultiWordTriggers() { - let transcript = "hey clawd do it" - let segments = makeSegments( - transcript: transcript, - words: [ - ("hey", 0.0, 0.1), - ("clawd", 0.2, 0.1), - ("do", 0.8, 0.1), - ("it", 1.0, 0.1), - ]) - let config = WakeWordGateConfig(triggers: ["hey clawd"], minPostTriggerGap: 0.3) - let match = WakeWordGate.match(transcript: transcript, segments: segments, config: config) - #expect(match?.command == "do it") - } -} - -private func makeSegments( - transcript: String, - words: [(String, TimeInterval, TimeInterval)]) --> [WakeWordSegment] { - var searchStart = transcript.startIndex - var output: [WakeWordSegment] = [] - for (word, start, duration) in words { - let range = transcript.range(of: word, range: searchStart../dev/null; then - echo "swiftlint not installed" >&2 - exit 1 -fi -swiftlint --config "$CONFIG" diff --git a/TEST_STEPS.md b/TEST_STEPS.md new file mode 100644 index 0000000000..1f0eb7e4d9 --- /dev/null +++ b/TEST_STEPS.md @@ -0,0 +1,354 @@ +# 测试步骤(完整版) + +## 🎯 配置步骤 + +### 步骤 1:编译 + +**目的**:编译 TypeScript 代码为可执行的 JavaScript + +```bash +npm install +npm run build +``` + +**验证**: +```bash +ls dist/index.mjs +# 应该看到编译后的文件 +``` + +**注意**:如果修改了源代码,需要重新编译 + +--- + +### 步骤 2:打开浏览器调试 + +**目的**:提供浏览器环境(端口 9222) + +```bash +./start-chrome-debug.sh +``` + +**验证**: +```bash +ps aux | grep "chrome.*9222" | grep -v grep +# 应该看到 Chrome 进程 +``` + +--- + +### 步骤 3:登录各大网站(不含 DeepSeek) + +**目的**:在 Chrome 调试浏览器中建立登录会话 + +**重要**:必须在 `start-chrome-debug` 启动的 Chrome 中登录(不是普通浏览器)。**DeepSeek 在第 5 步单独处理** + +在 Chrome 中打开并登录以下平台: + +1. **千问国际版 (Qwen International)**: https://chat.qwen.ai +2. **千问国内版 (Qwen CN)**: https://www.qianwen.com +3. **Kimi**: https://kimi.moonshot.cn +4. **Claude**: https://claude.ai +5. **Doubao**: https://www.doubao.com/chat/ +6. **ChatGPT**: https://chatgpt.com +7. **Gemini**: https://gemini.google.com/app +8. **Grok**: https://grok.com +9. **GLM Web (智谱清言)**: https://chatglm.cn +10. **GLM 国际版**: https://chat.z.ai + +**注意**:Manus 使用 API Key 方式认证,不需要浏览器登录。API Key 获取地址:https://open.manus.im + +--- + +### 步骤 4:配置 onboard + +**目的**:为各平台配置认证信息 + +```bash +./onboard.sh +``` + +**操作**:选择平台(如 `deepseek-web`),按提示完成认证 + +--- + +### 步骤 5:登录 DeepSeek + +**目的**:在 Chrome 中登录 DeepSeek,并通过 onboard 捕获认证 + +1. 在 Chrome 中访问 https://chat.deepseek.com 并登录 +2. 运行 `./onboard.sh`,选择 **deepseek-web** 完成凭证捕获 + +--- + +### 步骤 6:启动 server + +**目的**:启动 Web UI 服务(端口 3001) + +```bash +./server.sh start +``` + +**验证**: +```bash +./server.sh status +# 应该显示:Gateway 服务运行中 +``` + +--- + +### 访问 Web UI + +**访问地址**: +``` +http://127.0.0.1:3001/#token=62b791625fa441be036acd3c206b7e14e2bb13c803355823 +``` + +浏览器应该会自动打开,如果没有,手动访问上面的地址。 + +--- + +### 步骤 7:查看所有模型 + +**关键规则(请务必注意)**: +- `/models` 里显示的是**已完成 onboard 配置**的平台模型集合。 +- 只有你在 `./onboard.sh` 中实际选择并完成认证的平台,才会写入 `openclaw.json` 并出现在最终模型列表中。 +- 仅在浏览器里登录、但没有走完 onboard 的平台,**不会**出现在 `/models`。 + +在 Web UI 的聊天框中输入: +``` +/models +``` + +**预期结果**:应该看到以下模型 + +``` +claude-web/claude-sonnet-4-6 +claude-web/claude-opus-4-6 +claude-web/claude-haiku-4-6 +doubao-web/doubao-seed-2.0 +doubao-web/doubao-pro +chatgpt-web/gpt-4 +chatgpt-web/gpt-4-turbo +chatgpt-web/gpt-3.5-turbo +qwen-web/qwen-max +qwen-web/qwen-plus +qwen-web/qwen-turbo +kimi-web/moonshot-v1-8k +kimi-web/moonshot-v1-32k +kimi-web/moonshot-v1-128k +gemini-web/gemini-pro +gemini-web/gemini-ultra +grok-web/grok-2 +grok-web/grok-1 +glm-web/glm-4-plus (GLM) +glm-web/glm-4-think (GLM) +manus-api/manus-1.6 +manus-api/manus-1.6-lite +``` + +--- + +### 步骤 8:测试对话 + +**操作**: +1. 在 Web UI 中选择一个模型(如 `claude-web/claude-sonnet-4-6`) +2. 发送测试消息:"你好,请介绍一下你自己" +3. 检查是否能正常收到回复 + +**对每个平台重复测试**: +- ✅ claude-web +- ✅ doubao-web +- ✅ chatgpt-web +- ✅ qwen-web +- ✅ kimi-web +- ✅ gemini-web +- ✅ grok-web +- ✅ deepseek-web +- ✅ glm-web (GLM) +- ✅ manus-api (需要 API Key) + +--- + +## 📊 配置流程图 + +``` +┌─────────────────────────────────────┐ +│ 1. 编译 │ +│ npm install && npm run build │ +└──────────────┬──────────────────────┘ + ↓ +┌─────────────────────────────────────┐ +│ 2. 打开浏览器调试 │ +│ ./start-chrome-debug.sh │ +└──────────────┬──────────────────────┘ + ↓ +┌─────────────────────────────────────┐ +│ 3. 登录各大网站(不含 DeepSeek) │ +│ (千问、Kimi 等,DeepSeek 在第 5 步)│ +└──────────────┬──────────────────────┘ + ↓ +┌─────────────────────────────────────┐ +│ 4. 配置 onboard │ +│ ./onboard.sh │ +└──────────────┬──────────────────────┘ + ↓ +┌─────────────────────────────────────┐ +│ 5. 登录 DeepSeek │ +│ (Chrome 登录 + onboard 捕获) │ +└──────────────┬──────────────────────┘ + ↓ +┌─────────────────────────────────────┐ +│ 6. 启动 server │ +│ ./server.sh start │ +└──────────────┬──────────────────────┘ + ↓ +┌─────────────────────────────────────┐ +│ 打开 Web UI → http://127.0.0.1:3001 │ +│ 输入 /models → 测试对话 │ +└─────────────────────────────────────┘ +``` + +--- + +## 🔧 故障排查 + +### 问题 1:端口冲突 + +**症状**:Gateway 启动失败,提示端口被占用 + +**解决**: +```bash +# 查找占用 3001 端口的进程 +lsof -i :3001 + +# 关闭进程 +kill + +# 或者强制关闭 +./server.sh stop +``` + +### 问题 2:Chrome 调试浏览器未启动 + +**症状**:onboard 提示无法连接浏览器 + +**解决**: +```bash +# 检查 Chrome 是否运行 +ps aux | grep "chrome.*9222" + +# 重新启动 +./start-chrome-debug.sh +``` + +### 问题 3:认证失败 + +**症状**:测试对话时提示认证错误 + +**解决**: +1. 确保在 Chrome 调试浏览器中已登录 +2. 重新运行 `./onboard.sh` 配置认证 +3. 检查 cookie 是否正确 + +### 问题 4:模型列表为空 + +**症状**:`/models` 命令没有显示模型 + +**解决**: +```bash +# 重启 Gateway +./server.sh restart + +# 检查配置文件 +cat .openclaw-zero-state/openclaw.json | jq '.models.providers | keys' + +# 查看日志 +tail -f /tmp/openclaw-zero-gateway.log +``` + +### 问题 5:glm-intl-web 认证或 API 错误 + +**症状**:`glm-intl-web` 返回 `Authentication expired`、`API 500/401` 等错误。 + +**说明**: +- 国际版 `https://chat.z.ai/` 的请求链路与 `glm-web(chatglm.cn)` 不同,接口可能随前端版本变化。 +- 当前实现已切换为优先复用浏览器页面(UI 驱动)以提高稳定性。 + +**排查建议**: +```bash +# 1) 确保调试浏览器与登录状态 +./start-chrome-debug.sh + +# 2) 重新授权 glm-intl-web +./onboard.sh + +# 3) 使用抓包脚本分析真实请求(脚本已迁移到 test/) +node test/fix-glm-intl-api.js +``` + +--- + +## 📝 快速命令参考 + +```bash +# 首次使用:安装依赖并编译 +npm install +npm run build + +# 关闭系统 Gateway +openclaw gateway stop + +# 启动 Chrome 调试 +./start-chrome-debug.sh + +# 配置认证 +./onboard.sh + +# 启动本地 Gateway +./server.sh start + +# 查看状态 +./server.sh status + +# 重启 Gateway +./server.sh restart + +# 停止 Gateway +./server.sh stop + +# 查看日志 +tail -f /tmp/openclaw-zero-gateway.log + +# 检查配置 +cat .openclaw-zero-state/openclaw.json | jq '.models.providers | keys' + +# 检查认证 +cat .openclaw-zero-state/agents/main/agent/auth-profiles.json | jq '.profiles | keys' +``` + +--- + +## 🧪 调试脚本位置 + +根目录下的 GLM 调试脚本已统一迁移到 `test/`: + +- `test/fix-glm-intl-api.js`:自动发送测试消息并抓取请求/响应 +- `test/debug-glm-intl-api.js`:持续监听 intl API 请求 +- `test/debug-glm-requests.js`:拦截并打印 POST 请求 +- `test/capture-glm-api.js`:CDP/Fetch 级抓包 +- `test/quick-debug-glm.js`:快速连通性调试 +- `test/direct-capture.js`:WebSocket 直连抓包 + +--- + +## ✅ 测试完成标志 + +- ✅ 所有 10 个平台都能在 `/models` 中看到 +- ✅ 每个平台都能成功发送消息并收到回复 +- ✅ 流式响应正常工作(逐字显示) +- ✅ 没有认证错误或 API 错误 + +--- + +祝测试顺利!🚀 diff --git a/VISION.md b/VISION.md deleted file mode 100644 index 4ff70189ab..0000000000 --- a/VISION.md +++ /dev/null @@ -1,110 +0,0 @@ -## OpenClaw Vision - -OpenClaw is the AI that actually does things. -It runs on your devices, in your channels, with your rules. - -This document explains the current state and direction of the project. -We are still early, so iteration is fast. -Project overview and developer docs: [`README.md`](README.md) -Contribution guide: [`CONTRIBUTING.md`](CONTRIBUTING.md) - -OpenClaw started as a personal playground to learn AI and build something genuinely useful: -an assistant that can run real tasks on a real computer. -It evolved through several names and shells: Warelay -> Clawdbot -> Moltbot -> OpenClaw. - -The goal: a personal assistant that is easy to use, supports a wide range of platforms, and respects privacy and security. - -The current focus is: - -Priority: - -- Security and safe defaults -- Bug fixes and stability -- Setup reliability and first-run UX - -Next priorities: - -- Supporting all major model providers -- Improving support for major messaging channels (and adding a few high-demand ones) -- Performance and test infrastructure -- Better computer-use and agent harness capabilities -- Ergonomics across CLI and web frontend -- Companion apps on macOS, iOS, Android, Windows, and Linux - -Contribution rules: - -- One PR = one issue/topic. Do not bundle multiple unrelated fixes/features. -- PRs over ~5,000 changed lines are reviewed only in exceptional circumstances. -- Do not open large batches of tiny PRs at once; each PR has review cost. -- For very small related fixes, grouping into one focused PR is encouraged. - -## Security - -Security in OpenClaw is a deliberate tradeoff: strong defaults without killing capability. -The goal is to stay powerful for real work while making risky paths explicit and operator-controlled. - -Canonical security policy and reporting: - -- [`SECURITY.md`](SECURITY.md) - -We prioritize secure defaults, but also expose clear knobs for trusted high-power workflows. - -## Plugins & Memory - -OpenClaw has an extensive plugin API. -Core stays lean; optional capability should usually ship as plugins. - -Preferred plugin path is npm package distribution plus local extension loading for development. -If you build a plugin, host and maintain it in your own repository. -The bar for adding optional plugins to core is intentionally high. -Plugin docs: [`docs/tools/plugin.md`](docs/tools/plugin.md) -Community plugin listing + PR bar: https://docs.openclaw.ai/plugins/community - -Memory is a special plugin slot where only one memory plugin can be active at a time. -Today we ship multiple memory options; over time we plan to converge on one recommended default path. - -### Skills - -We still ship some bundled skills for baseline UX. -New skills should be published to ClawHub first (`clawhub.ai`), not added to core by default. -Core skill additions should be rare and require a strong product or security reason. - -### MCP Support - -OpenClaw supports MCP through `mcporter`: https://github.com/steipete/mcporter - -This keeps MCP integration flexible and decoupled from core runtime: - -- add or change MCP servers without restarting the gateway -- keep core tool/context surface lean -- reduce MCP churn impact on core stability and security - -For now, we prefer this bridge model over building first-class MCP runtime into core. -If there is an MCP server or feature `mcporter` does not support yet, please open an issue there. - -### Setup - -OpenClaw is currently terminal-first by design. -This keeps setup explicit: users see docs, auth, permissions, and security posture up front. - -Long term, we want easier onboarding flows as hardening matures. -We do not want convenience wrappers that hide critical security decisions from users. - -### Why TypeScript? - -OpenClaw is primarily an orchestration system: prompts, tools, protocols, and integrations. -TypeScript was chosen to keep OpenClaw hackable by default. -It is widely known, fast to iterate in, and easy to read, modify, and extend. - -## What We Will Not Merge (For Now) - -- New core skills when they can live on ClawHub -- Full-doc translation sets for all docs (deferred; we plan AI-generated translations later) -- Commercial service integrations that do not clearly fit the model-provider category -- Wrapper channels around already supported channels without a clear capability or security gap -- First-class MCP runtime in core when `mcporter` already provides the integration path -- Agent-hierarchy frameworks (manager-of-managers / nested planner trees) as a default architecture -- Heavy orchestration layers that duplicate existing agent and tool infrastructure - -This list is a roadmap guardrail, not a law of physics. -Strong user demand and strong technical rationale can change it. diff --git a/appcast.xml b/appcast.xml deleted file mode 100644 index 3318fbaf86..0000000000 --- a/appcast.xml +++ /dev/null @@ -1,313 +0,0 @@ - - - - OpenClaw - - 2026.2.14 - Sun, 15 Feb 2026 04:24:34 +0100 - https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml - 202602140 - 2026.2.14 - 15.0 - OpenClaw 2026.2.14 -

Changes

-
    -
  • Telegram: add poll sending via openclaw message poll (duration seconds, silent delivery, anonymity controls). (#16209) Thanks @robbyczgw-cla.
  • -
  • Slack/Discord: add dmPolicy + allowFrom config aliases for DM access control; legacy dm.policy + dm.allowFrom keys remain supported and openclaw doctor --fix can migrate them.
  • -
  • Discord: allow exec approval prompts to target channels or both DM+channel via channels.discord.execApprovals.target. (#16051) Thanks @leonnardo.
  • -
  • Sandbox: add sandbox.browser.binds to configure browser-container bind mounts separately from exec containers. (#16230) Thanks @seheepeak.
  • -
  • Discord: add debug logging for message routing decisions to improve --debug tracing. (#16202) Thanks @jayleekr.
  • -
-

Fixes

-
    -
  • CLI/Plugins: ensure openclaw message send exits after successful delivery across plugin-backed channels so one-shot sends do not hang. (#16491) Thanks @yinghaosang.
  • -
  • CLI/Plugins: run registered plugin gateway_stop hooks before openclaw message exits (success and failure paths), so plugin-backed channels can clean up one-shot CLI resources. (#16580) Thanks @gumadeiras.
  • -
  • WhatsApp: honor per-account dmPolicy overrides (account-level settings now take precedence over channel defaults for inbound DMs). (#10082) Thanks @mcaxtr.
  • -
  • Telegram: when channels.telegram.commands.native is false, exclude plugin commands from setMyCommands menu registration while keeping plugin slash handlers callable. (#15132) Thanks @Glucksberg.
  • -
  • LINE: return 200 OK for Developers Console "Verify" requests ({"events":[]}) without X-Line-Signature, while still requiring signatures for real deliveries. (#16582) Thanks @arosstale.
  • -
  • Cron: deliver text-only output directly when delivery.to is set so cron recipients get full output instead of summaries. (#16360) Thanks @thewilloftheshadow.
  • -
  • Cron/Slack: preserve agent identity (name and icon) when cron jobs deliver outbound messages. (#16242) Thanks @robbyczgw-cla.
  • -
  • Media: accept MEDIA:-prefixed paths (lenient whitespace) when loading outbound media to prevent ENOENT for tool-returned local media paths. (#13107) Thanks @mcaxtr.
  • -
  • Agents: deliver tool result media (screenshots, images, audio) to channels regardless of verbose level. (#11735) Thanks @strelov1.
  • -
  • Agents/Image tool: allow workspace-local image paths by including the active workspace directory in local media allowlists, and trust sandbox-validated paths in image loaders to prevent false "not under an allowed directory" rejections. (#15541)
  • -
  • Agents/Image tool: propagate the effective workspace root into tool wiring so workspace-local image paths are accepted by default when running without an explicit workspaceDir. (#16722)
  • -
  • BlueBubbles: include sender identity in group chat envelopes and pass clean message text to the agent prompt, aligning with iMessage/Signal formatting. (#16210) Thanks @zerone0x.
  • -
  • CLI: fix lazy core command registration so top-level maintenance commands (doctor, dashboard, reset, uninstall) resolve correctly instead of exposing a non-functional maintenance placeholder command.
  • -
  • CLI/Dashboard: when gateway.bind=lan, generate localhost dashboard URLs to satisfy browser secure-context requirements while preserving non-LAN bind behavior. (#16434) Thanks @BinHPdev.
  • -
  • TUI/Gateway: resolve local gateway target URL from gateway.bind mode (tailnet/lan) instead of hardcoded localhost so openclaw tui connects when gateway is non-loopback. (#16299) Thanks @cortexuvula.
  • -
  • TUI: honor explicit --session in openclaw tui even when session.scope is global, so named sessions no longer collapse into shared global history. (#16575) Thanks @cinqu.
  • -
  • TUI: use available terminal width for session name display in searchable select lists. (#16238) Thanks @robbyczgw-cla.
  • -
  • TUI: refactor searchable select list description layout and add regression coverage for ANSI-highlight width bounds.
  • -
  • TUI: preserve in-flight streaming replies when a different run finalizes concurrently (avoid clearing active run or reloading history mid-stream). (#10704) Thanks @axschr73.
  • -
  • TUI: keep pre-tool streamed text visible when later tool-boundary deltas temporarily omit earlier text blocks. (#6958) Thanks @KrisKind75.
  • -
  • TUI: sanitize ANSI/control-heavy history text, redact binary-like lines, and split pathological long unbroken tokens before rendering to prevent startup crashes on binary attachment history. (#13007) Thanks @wilkinspoe.
  • -
  • TUI: harden render-time sanitizer for narrow terminals by chunking moderately long unbroken tokens and adding fast-path sanitization guards to reduce overhead on normal text. (#5355) Thanks @tingxueren.
  • -
  • TUI: render assistant body text in terminal default foreground (instead of fixed light ANSI color) so contrast remains readable on light themes such as Solarized Light. (#16750) Thanks @paymog.
  • -
  • TUI/Hooks: pass explicit reset reason (new vs reset) through sessions.reset and emit internal command hooks for gateway-triggered resets so /new hook workflows fire in TUI/webchat.
  • -
  • Cron: prevent cron list/cron status from silently skipping past-due recurring jobs by using maintenance recompute semantics. (#16156) Thanks @zerone0x.
  • -
  • Cron: repair missing/corrupt nextRunAtMs for the updated job without globally recomputing unrelated due jobs during cron update. (#15750)
  • -
  • Cron: skip missed-job replay on startup for jobs interrupted mid-run (stale runningAtMs markers), preventing restart loops for self-restarting jobs such as update tasks. (#16694) Thanks @sbmilburn.
  • -
  • Discord: prefer gateway guild id when logging inbound messages so cached-miss guilds do not appear as guild=dm. Thanks @thewilloftheshadow.
  • -
  • Discord: treat empty per-guild channels: {} config maps as no channel allowlist (not deny-all), so groupPolicy: "open" guilds without explicit channel entries continue to receive messages. (#16714) Thanks @xqliu.
  • -
  • Models/CLI: guard models status string trimming paths to prevent crashes from malformed non-string config values. (#16395) Thanks @BinHPdev.
  • -
  • Gateway/Subagents: preserve queued announce items and summary state on delivery errors, retry failed announce drains, and avoid dropping unsent announcements on timeout/failure. (#16729) Thanks @Clawdette-Workspace.
  • -
  • Gateway/Sessions: abort active embedded runs and clear queued session work before sessions.reset, returning unavailable if the run does not stop in time. (#16576) Thanks @Grynn.
  • -
  • Sessions/Agents: harden transcript path resolution for mismatched agent context by preserving explicit store roots and adding safe absolute-path fallback to the correct agent sessions directory. (#16288) Thanks @robbyczgw-cla.
  • -
  • Agents: add a safety timeout around embedded session.compact() to ensure stalled compaction runs settle and release blocked session lanes. (#16331) Thanks @BinHPdev.
  • -
  • Agents: keep unresolved mutating tool failures visible until the same action retry succeeds, scope mutation-error surfacing to mutating calls (including session_status model changes), and dedupe duplicate failure warnings in outbound replies. (#16131) Thanks @Swader.
  • -
  • Agents/Process/Bootstrap: preserve unbounded process log offset-only pagination (default tail applies only when both offset and limit are omitted) and enforce strict bootstrapTotalMaxChars budgeting across injected bootstrap content (including markers), skipping additional injection when remaining budget is too small. (#16539) Thanks @CharlieGreenman.
  • -
  • Agents/Workspace: persist bootstrap onboarding state so partially initialized workspaces recover missing BOOTSTRAP.md once, while completed onboarding keeps BOOTSTRAP deleted even if runtime files are later recreated. Thanks @gumadeiras.
  • -
  • Agents/Workspace: create BOOTSTRAP.md when core workspace files are seeded in partially initialized workspaces, while keeping BOOTSTRAP one-shot after onboarding deletion. (#16457) Thanks @robbyczgw-cla.
  • -
  • Agents: classify external timeout aborts during compaction the same as internal timeouts, preventing unnecessary auth-profile rotation and preserving compaction-timeout snapshot fallback behavior. (#9855) Thanks @mverrilli.
  • -
  • Agents: treat empty-stream provider failures (request ended without sending any chunks) as timeout-class failover signals, enabling auth-profile rotation/fallback and showing a friendly timeout message instead of raw provider errors. (#10210) Thanks @zenchantlive.
  • -
  • Agents: treat read tool file_path arguments as valid in tool-start diagnostics to avoid false “read tool called without path” warnings when alias parameters are used. (#16717) Thanks @Stache73.
  • -
  • Ollama/Agents: avoid forcing tag enforcement for Ollama models, which could suppress all output as (no output). (#16191) Thanks @Glucksberg.
  • -
  • Plugins: suppress false duplicate plugin id warnings when the same extension is discovered via multiple paths (config/workspace/global vs bundled), while still warning on genuine duplicates. (#16222) Thanks @shadril238.
  • -
  • Skills: watch SKILL.md only when refreshing skills snapshot to avoid file-descriptor exhaustion in large data trees. (#11325) Thanks @household-bard.
  • -
  • Memory/QMD: make memory status read-only by skipping QMD boot update/embed side effects for status-only manager checks.
  • -
  • Memory/QMD: keep original QMD failures when builtin fallback initialization fails (for example missing embedding API keys), instead of replacing them with fallback init errors.
  • -
  • Memory/Builtin: keep memory status dirty reporting stable across invocations by deriving status-only manager dirty state from persisted index metadata instead of process-start defaults. (#10863) Thanks @BarryYangi.
  • -
  • Memory/QMD: cap QMD command output buffering to prevent memory exhaustion from pathological qmd command output.
  • -
  • Memory/QMD: parse qmd scope keys once per request to avoid repeated parsing in scope checks.
  • -
  • Memory/QMD: query QMD index using exact docid matches before falling back to prefix lookup for better recall correctness and index efficiency.
  • -
  • Memory/QMD: pass result limits to search/vsearch commands so QMD can cap results earlier.
  • -
  • Memory/QMD: avoid reading full markdown files when a from/lines window is requested in QMD reads.
  • -
  • Memory/QMD: skip rewriting unchanged session export markdown files during sync to reduce disk churn.
  • -
  • Memory/QMD: make QMD result JSON parsing resilient to noisy command output by extracting the first JSON array from noisy stdout.
  • -
  • Memory/QMD: treat prefixed no results found marker output as an empty result set in qmd JSON parsing. (#11302) Thanks @blazerui.
  • -
  • Memory/QMD: avoid multi-collection query ranking corruption by running one qmd query -c per managed collection and merging by best score (also used for search/vsearch fallback-to-query). (#16740) Thanks @volarian-vai.
  • -
  • Memory/QMD: detect null-byte ENOTDIR update failures, rebuild managed collections once, and retry update to self-heal corrupted collection metadata. (#12919) Thanks @jorgejhms.
  • -
  • Memory/QMD/Security: add rawKeyPrefix support for QMD scope rules and preserve legacy keyPrefix: "agent:..." matching, preventing scoped deny bypass when operators match agent-prefixed session keys.
  • -
  • Memory/Builtin: narrow memory watcher targets to markdown globs and ignore dependency/venv directories to reduce file-descriptor pressure during memory sync startup. (#11721) Thanks @rex05ai.
  • -
  • Security/Memory-LanceDB: treat recalled memories as untrusted context (escape injected memory text + explicit non-instruction framing), skip likely prompt-injection payloads during auto-capture, and restrict auto-capture to user messages to reduce memory-poisoning risk. (#12524) Thanks @davidschmid24.
  • -
  • Security/Memory-LanceDB: require explicit autoCapture: true opt-in (default is now disabled) to prevent automatic PII capture unless operators intentionally enable it. (#12552) Thanks @fr33d3m0n.
  • -
  • Diagnostics/Memory: prune stale diagnostic session state entries and cap tracked session states to prevent unbounded in-memory growth on long-running gateways. (#5136) Thanks @coygeek and @vignesh07.
  • -
  • Gateway/Memory: clean up agentRunSeq tracking on run completion/abort and enforce maintenance-time cap pruning to prevent unbounded sequence-map growth over long uptimes. (#6036) Thanks @coygeek and @vignesh07.
  • -
  • Auto-reply/Memory: bound ABORT_MEMORY growth by evicting oldest entries and deleting reset (false) flags so abort state tracking cannot grow unbounded over long uptimes. (#6629) Thanks @coygeek and @vignesh07.
  • -
  • Slack/Memory: bound thread-starter cache growth with TTL + max-size pruning to prevent long-running Slack gateways from accumulating unbounded thread cache state. (#5258) Thanks @coygeek and @vignesh07.
  • -
  • Outbound/Memory: bound directory cache growth with max-size eviction and proactive TTL pruning to prevent long-running gateways from accumulating unbounded directory entries. (#5140) Thanks @coygeek and @vignesh07.
  • -
  • Skills/Memory: remove disconnected nodes from remote-skills cache to prevent stale node metadata from accumulating over long uptimes. (#6760) Thanks @coygeek.
  • -
  • Sandbox/Tools: make sandbox file tools bind-mount aware (including absolute container paths) and enforce read-only bind semantics for writes. (#16379) Thanks @tasaankaeris.
  • -
  • Media/Security: allow local media reads from OpenClaw state workspace/ and sandboxes/ roots by default so generated workspace media can be delivered without unsafe global path bypasses. (#15541) Thanks @lanceji.
  • -
  • Media/Security: harden local media allowlist bypasses by requiring an explicit readFile override when callers mark paths as validated, and reject filesystem-root localRoots entries. (#16739)
  • -
  • Discord/Security: harden voice message media loading (SSRF + allowed-local-root checks) so tool-supplied paths/URLs cannot be used to probe internal URLs or read arbitrary local files.
  • -
  • Security/BlueBubbles: require explicit mediaLocalRoots allowlists for local outbound media path reads to prevent local file disclosure. (#16322) Thanks @mbelinky.
  • -
  • Security/BlueBubbles: reject ambiguous shared-path webhook routing when multiple webhook targets match the same guid/password.
  • -
  • Security/BlueBubbles: harden BlueBubbles webhook auth behind reverse proxies by only accepting passwordless webhooks for direct localhost loopback requests (forwarded/proxied requests now require a password). Thanks @simecek.
  • -
  • Feishu/Security: harden media URL fetching against SSRF and local file disclosure. (#16285) Thanks @mbelinky.
  • -
  • Security/Zalo: reject ambiguous shared-path webhook routing when multiple webhook targets match the same secret.
  • -
  • Security/Nostr: require loopback source and block cross-origin profile mutation/import attempts. Thanks @vincentkoc.
  • -
  • Security/Signal: harden signal-cli archive extraction during install to prevent path traversal outside the install root.
  • -
  • Security/Hooks: restrict hook transform modules to ~/.openclaw/hooks/transforms (prevents path traversal/escape module loads via config). Config note: hooks.transformsDir must now be within that directory. Thanks @akhmittra.
  • -
  • Security/Hooks: ignore hook package manifest entries that point outside the package directory (prevents out-of-tree handler loads during hook discovery).
  • -
  • Security/Archive: enforce archive extraction entry/size limits to prevent resource exhaustion from high-expansion ZIP/TAR archives. Thanks @vincentkoc.
  • -
  • Security/Media: reject oversized base64-backed input media before decoding to avoid large allocations. Thanks @vincentkoc.
  • -
  • Security/Media: stream and bound URL-backed input media fetches to prevent memory exhaustion from oversized responses. Thanks @vincentkoc.
  • -
  • Security/Skills: harden archive extraction for download-installed skills to prevent path traversal outside the target directory. Thanks @markmusson.
  • -
  • Security/Slack: compute command authorization for DM slash commands even when dmPolicy=open, preventing unauthorized users from running privileged commands via DM. Thanks @christos-eth.
  • -
  • Security/iMessage: keep DM pairing-store identities out of group allowlist authorization (prevents cross-context command authorization). Thanks @vincentkoc.
  • -
  • Security/Google Chat: deprecate users/ allowlists (treat users/... as immutable user id only); keep raw email allowlists for usability. Thanks @vincentkoc.
  • -
  • Security/Google Chat: reject ambiguous shared-path webhook routing when multiple webhook targets verify successfully (prevents cross-account policy-context misrouting). Thanks @vincentkoc.
  • -
  • Telegram/Security: require numeric Telegram sender IDs for allowlist authorization (reject @username principals), auto-resolve @username to IDs in openclaw doctor --fix (when possible), and warn in openclaw security audit when legacy configs contain usernames. Thanks @vincentkoc.
  • -
  • Telegram/Security: reject Telegram webhook startup when webhookSecret is missing or empty (prevents unauthenticated webhook request forgery). Thanks @yueyueL.
  • -
  • Security/Windows: avoid shell invocation when spawning child processes to prevent cmd.exe metacharacter injection via untrusted CLI arguments (e.g. agent prompt text).
  • -
  • Telegram: set webhook callback timeout handling to onTimeout: "return" (10s) so long-running update processing no longer emits webhook 500s and retry storms. (#16763) Thanks @chansearrington.
  • -
  • Signal: preserve case-sensitive group: target IDs during normalization so mixed-case group IDs no longer fail with Group not found. (#16748) Thanks @repfigit.
  • -
  • Feishu/Security: harden media URL fetching against SSRF and local file disclosure. (#16285) Thanks @mbelinky.
  • -
  • Security/Agents: scope CLI process cleanup to owned child PIDs to avoid killing unrelated processes on shared hosts. Thanks @aether-ai-agent.
  • -
  • Security/Agents: enforce workspace-root path bounds for apply_patch in non-sandbox mode to block traversal and symlink escape writes. Thanks @p80n-sec.
  • -
  • Security/Agents: enforce symlink-escape checks for apply_patch delete hunks under workspaceOnly, while still allowing deleting the symlink itself. Thanks @p80n-sec.
  • -
  • Security/Agents (macOS): prevent shell injection when writing Claude CLI keychain credentials. (#15924) Thanks @aether-ai-agent.
  • -
  • macOS: hard-limit unkeyed openclaw://agent deep links and ignore deliver / to / channel unless a valid unattended key is provided. Thanks @Cillian-Collins.
  • -
  • Scripts/Security: validate GitHub logins and avoid shell invocation in scripts/update-clawtributors.ts to prevent command injection via malicious commit records. Thanks @scanleale.
  • -
  • Security: fix Chutes manual OAuth login state validation by requiring the full redirect URL (reject code-only pastes) (thanks @aether-ai-agent).
  • -
  • Security/Gateway: harden tool-supplied gatewayUrl overrides by restricting them to loopback or the configured gateway.remote.url. Thanks @p80n-sec.
  • -
  • Security/Gateway: block system.execApprovals.* via node.invoke (use exec.approvals.node.* instead). Thanks @christos-eth.
  • -
  • Security/Gateway: reject oversized base64 chat attachments before decoding to avoid large allocations. Thanks @vincentkoc.
  • -
  • Security/Gateway: stop returning raw resolved config values in skills.status requirement checks (prevents operator.read clients from reading secrets). Thanks @simecek.
  • -
  • Security/Net: fix SSRF guard bypass via full-form IPv4-mapped IPv6 literals (blocks loopback/private/metadata access). Thanks @yueyueL.
  • -
  • Security/Browser: harden browser control file upload + download helpers to prevent path traversal / local file disclosure. Thanks @1seal.
  • -
  • Security/Browser: block cross-origin mutating requests to loopback browser control routes (CSRF hardening). Thanks @vincentkoc.
  • -
  • Security/Node Host: enforce system.run rawCommand/argv consistency to prevent allowlist/approval bypass. Thanks @christos-eth.
  • -
  • Security/Exec approvals: prevent safeBins allowlist bypass via shell expansion (host exec allowlist mode only; not enabled by default). Thanks @christos-eth.
  • -
  • Security/Exec: harden PATH handling by disabling project-local node_modules/.bin bootstrapping by default, disallowing node-host PATH overrides, and spawning ACP servers via the current executable by default. Thanks @akhmittra.
  • -
  • Security/Tlon: harden Urbit URL fetching against SSRF by blocking private/internal hosts by default (opt-in: channels.tlon.allowPrivateNetwork). Thanks @p80n-sec.
  • -
  • Security/Voice Call (Telnyx): require webhook signature verification when receiving inbound events; configs without telnyx.publicKey are now rejected unless skipSignatureVerification is enabled. Thanks @p80n-sec.
  • -
  • Security/Voice Call: require valid Twilio webhook signatures even when ngrok free tier loopback compatibility mode is enabled. Thanks @p80n-sec.
  • -
  • Security/Discovery: stop treating Bonjour TXT records as authoritative routing (prefer resolved service endpoints) and prevent discovery from overriding stored TLS pins; autoconnect now requires a previously trusted gateway. Thanks @simecek.
  • -
-

View full changelog

-]]>
- -
- - 2026.2.15 - Mon, 16 Feb 2026 05:04:34 +0100 - https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml - 202602150 - 2026.2.15 - 15.0 - OpenClaw 2026.2.15 -

Changes

-
    -
  • Discord: unlock rich interactive agent prompts with Components v2 (buttons, selects, modals, and attachment-backed file blocks) so for native interaction through Discord. Thanks @thewilloftheshadow.
  • -
  • Discord: components v2 UI + embeds passthrough + exec approval UX refinements (CV2 containers, button layout, Discord-forwarding skip). Thanks @thewilloftheshadow.
  • -
  • Plugins: expose llm_input and llm_output hook payloads so extensions can observe prompt/input context and model output usage details. (#16724) Thanks @SecondThread.
  • -
  • Subagents: nested sub-agents (sub-sub-agents) with configurable depth. Set agents.defaults.subagents.maxSpawnDepth: 2 to allow sub-agents to spawn their own children. Includes maxChildrenPerAgent limit (default 5), depth-aware tool policy, and proper announce chain routing. (#14447) Thanks @tyler6204.
  • -
  • Slack/Discord/Telegram: add per-channel ack reaction overrides (account/channel-level) to support platform-specific emoji formats. (#17092) Thanks @zerone0x.
  • -
  • Cron/Gateway: add finished-run webhook delivery toggle (notify) and dedicated webhook auth token support (cron.webhookToken) for outbound cron webhook posts. (#14535) Thanks @advaitpaliwal.
  • -
  • Channels: deduplicate probe/token resolution base types across core + extensions while preserving per-channel error typing. (#16986) Thanks @iyoda and @thewilloftheshadow.
  • -
-

Fixes

-
    -
  • Security: replace deprecated SHA-1 sandbox configuration hashing with SHA-256 for deterministic sandbox cache identity and recreation checks. Thanks @kexinoh.
  • -
  • Security/Logging: redact Telegram bot tokens from error messages and uncaught stack traces to prevent accidental secret leakage into logs. Thanks @aether-ai-agent.
  • -
  • Sandbox/Security: block dangerous sandbox Docker config (bind mounts, host networking, unconfined seccomp/apparmor) to prevent container escape via config injection. Thanks @aether-ai-agent.
  • -
  • Sandbox: preserve array order in config hashing so order-sensitive Docker/browser settings trigger container recreation correctly. Thanks @kexinoh.
  • -
  • Gateway/Security: redact sensitive session/path details from status responses for non-admin clients; full details remain available to operator.admin. (#8590) Thanks @fr33d3m0n.
  • -
  • Gateway/Control UI: preserve requested operator scopes for Control UI bypass modes (allowInsecureAuth / dangerouslyDisableDeviceAuth) when device identity is unavailable, preventing false missing scope failures on authenticated LAN/HTTP operator sessions. (#17682) Thanks @leafbird.
  • -
  • LINE/Security: fail closed on webhook startup when channel token or channel secret is missing, and treat LINE accounts as configured only when both are present. (#17587) Thanks @davidahmann.
  • -
  • Skills/Security: restrict download installer targetDir to the per-skill tools directory to prevent arbitrary file writes. Thanks @Adam55A-code.
  • -
  • Skills/Linux: harden go installer fallback on apt-based systems by handling root/no-sudo environments safely, doing best-effort apt index refresh, and returning actionable errors instead of failing with spawn errors. (#17687) Thanks @mcrolly.
  • -
  • Web Fetch/Security: cap downloaded response body size before HTML parsing to prevent memory exhaustion from oversized or deeply nested pages. Thanks @xuemian168.
  • -
  • Config/Gateway: make sensitive-key whitelist suffix matching case-insensitive while preserving passwordFile path exemptions, preventing accidental redaction of non-secret config values like maxTokens and IRC password-file paths. (#16042) Thanks @akramcodez.
  • -
  • Dev tooling: harden git pre-commit hook against option injection from malicious filenames (for example --force), preventing accidental staging of ignored files. Thanks @mrthankyou.
  • -
  • Gateway/Agent: reject malformed agent:-prefixed session keys (for example, agent:main) in agent and agent.identity.get instead of silently resolving them to the default agent, preventing accidental cross-session routing. (#15707) Thanks @rodrigouroz.
  • -
  • Gateway/Chat: harden chat.send inbound message handling by rejecting null bytes, stripping unsafe control characters, and normalizing Unicode to NFC before dispatch. (#8593) Thanks @fr33d3m0n.
  • -
  • Gateway/Send: return an actionable error when send targets internal-only webchat, guiding callers to use chat.send or a deliverable channel. (#15703) Thanks @rodrigouroz.
  • -
  • Control UI: prevent stored XSS via assistant name/avatar by removing inline script injection, serving bootstrap config as JSON, and enforcing script-src 'self'. Thanks @Adam55A-code.
  • -
  • Agents/Security: sanitize workspace paths before embedding into LLM prompts (strip Unicode control/format chars) to prevent instruction injection via malicious directory names. Thanks @aether-ai-agent.
  • -
  • Agents/Sandbox: clarify system prompt path guidance so sandbox bash/exec uses container paths (for example /workspace) while file tools keep host-bridge mapping, avoiding first-attempt path misses from host-only absolute paths in sandbox command execution. (#17693) Thanks @app/juniordevbot.
  • -
  • Agents/Context: apply configured model contextWindow overrides after provider discovery so lookupContextTokens() honors operator config values (including discovery-failure paths). (#17404) Thanks @michaelbship and @vignesh07.
  • -
  • Agents/Context: derive lookupContextTokens() from auth-available model metadata and keep the smallest discovered context window for duplicate model ids, preventing cross-provider cache collisions from overestimating session context limits. (#17586) Thanks @githabideri and @vignesh07.
  • -
  • Agents/OpenAI: force store=true for direct OpenAI Responses/Codex runs to preserve multi-turn server-side conversation state, while leaving proxy/non-OpenAI endpoints unchanged. (#16803) Thanks @mark9232 and @vignesh07.
  • -
  • Memory/FTS: make buildFtsQuery Unicode-aware so non-ASCII queries (including CJK) produce keyword tokens instead of falling back to vector-only search. (#17672) Thanks @KinGP5471.
  • -
  • Auto-reply/Compaction: resolve memory/YYYY-MM-DD.md placeholders with timezone-aware runtime dates and append a Current time: line to memory-flush turns, preventing wrong-year memory filenames without making the system prompt time-variant. (#17603, #17633) Thanks @nicholaspapadam-wq and @vignesh07.
  • -
  • Agents: return an explicit timeout error reply when an embedded run times out before producing any payloads, preventing silent dropped turns during slow cache-refresh transitions. (#16659) Thanks @liaosvcaf and @vignesh07.
  • -
  • Group chats: always inject group chat context (name, participants, reply guidance) into the system prompt on every turn, not just the first. Prevents the model from losing awareness of which group it's in and incorrectly using the message tool to send to the same group. (#14447) Thanks @tyler6204.
  • -
  • Browser/Agents: when browser control service is unavailable, return explicit non-retry guidance (instead of "try again") so models do not loop on repeated browser tool calls until timeout. (#17673) Thanks @austenstone.
  • -
  • Subagents: use child-run-based deterministic announce idempotency keys across direct and queued delivery paths (with legacy queued-item fallback) to prevent duplicate announce retries without collapsing distinct same-millisecond announces. (#17150) Thanks @widingmarcus-cyber.
  • -
  • Subagents/Models: preserve agents.defaults.model.fallbacks when subagent sessions carry a model override, so subagent runs fail over to configured fallback models instead of retrying only the overridden primary model.
  • -
  • Telegram: omit message_thread_id for DM sends/draft previews and keep forum-topic handling (id=1 general omitted, non-general kept), preventing DM failures with 400 Bad Request: message thread not found. (#10942) Thanks @garnetlyx.
  • -
  • Telegram: replace inbound placeholder with successful preflight voice transcript in message body context, preventing placeholder-only prompt bodies for mention-gated voice messages. (#16789) Thanks @Limitless2023.
  • -
  • Telegram: retry inbound media getFile calls (3 attempts with backoff) and gracefully fall back to placeholder-only processing when retries fail, preventing dropped voice/media messages on transient Telegram network errors. (#16154) Thanks @yinghaosang.
  • -
  • Telegram: finalize streaming preview replies in place instead of sending a second final message, preventing duplicate Telegram assistant outputs at stream completion. (#17218) Thanks @obviyus.
  • -
  • Discord: preserve channel session continuity when runtime payloads omit message.channelId by falling back to event/raw channel_id values for routing/session keys, so same-channel messages keep history across turns/restarts. Also align diagnostics so active Discord runs no longer appear as sessionKey=unknown. (#17622) Thanks @shakkernerd.
  • -
  • Discord: dedupe native skill commands by skill name in multi-agent setups to prevent duplicated slash commands with _2 suffixes. (#17365) Thanks @seewhyme.
  • -
  • Discord: ensure role allowlist matching uses raw role IDs for message routing authorization. Thanks @xinhuagu.
  • -
  • Web UI/Agents: hide BOOTSTRAP.md in the Agents Files list after onboarding is completed, avoiding confusing missing-file warnings for completed workspaces. (#17491) Thanks @gumadeiras.
  • -
  • Auto-reply/WhatsApp/TUI/Web: when a final assistant message is NO_REPLY and a messaging tool send succeeded, mirror the delivered messaging-tool text into session-visible assistant output so TUI/Web no longer show NO_REPLY placeholders. (#7010) Thanks @Morrowind-Xie.
  • -
  • Cron: infer payload.kind="agentTurn" for model-only cron.update payload patches, so partial agent-turn updates do not fail validation when kind is omitted. (#15664) Thanks @rodrigouroz.
  • -
  • TUI: make searchable-select filtering and highlight rendering ANSI-aware so queries ignore hidden escape codes and no longer corrupt ANSI styling sequences during match highlighting. (#4519) Thanks @bee4come.
  • -
  • TUI/Windows: coalesce rapid single-line submit bursts in Git Bash into one multiline message as a fallback when bracketed paste is unavailable, preventing pasted multiline text from being split into multiple sends. (#4986) Thanks @adamkane.
  • -
  • TUI: suppress false (no output) placeholders for non-local empty final events during concurrent runs, preventing external-channel replies from showing empty assistant bubbles while a local run is still streaming. (#5782) Thanks @LagWizard and @vignesh07.
  • -
  • TUI: preserve copy-sensitive long tokens (URLs/paths/file-like identifiers) during wrapping and overflow sanitization so wrapped output no longer inserts spaces that corrupt copy/paste values. (#17515, #17466, #17505) Thanks @abe238, @trevorpan, and @JasonCry.
  • -
  • CLI/Build: make legacy daemon CLI compatibility shim generation tolerant of minimal tsdown daemon export sets, while preserving restart/register compatibility aliases and surfacing explicit errors for unavailable legacy daemon commands. Thanks @vignesh07.
  • -
-

View full changelog

-]]>
- -
- - 2026.2.13 - Sat, 14 Feb 2026 04:30:23 +0100 - https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml - 9846 - 2026.2.13 - 15.0 - OpenClaw 2026.2.13 -

Changes

-
    -
  • Discord: send voice messages with waveform previews from local audio files (including silent delivery). (#7253) Thanks @nyanjou.
  • -
  • Discord: add configurable presence status/activity/type/url (custom status defaults to activity text). (#10855) Thanks @h0tp-ftw.
  • -
  • Slack/Plugins: add thread-ownership outbound gating via message_sending hooks, including @-mention bypass tracking and Slack outbound hook wiring for cancel/modify behavior. (#15775) Thanks @DarlingtonDeveloper.
  • -
  • Agents: add synthetic catalog support for hf:zai-org/GLM-5. (#15867) Thanks @battman21.
  • -
  • Skills: remove duplicate local-places Google Places skill/proxy and keep goplaces as the single supported Google Places path.
  • -
  • Agents: add pre-prompt context diagnostics (messages, systemPromptChars, promptChars, provider/model, session file) before embedded runner prompt calls to improve overflow debugging. (#8930) Thanks @Glucksberg.
  • -
-

Fixes

-
    -
  • Outbound: add a write-ahead delivery queue with crash-recovery retries to prevent lost outbound messages after gateway restarts. (#15636) Thanks @nabbilkhan, @thewilloftheshadow.
  • -
  • Auto-reply/Threading: auto-inject implicit reply threading so replyToMode works without requiring model-emitted [[reply_to_current]], while preserving replyToMode: "off" behavior for implicit Slack replies and keeping block-streaming chunk coalescing stable under replyToMode: "first". (#14976) Thanks @Diaspar4u.
  • -
  • Outbound/Threading: pass replyTo and threadId from message send tool actions through the core outbound send path to channel adapters, preserving thread/reply routing. (#14948) Thanks @mcaxtr.
  • -
  • Auto-reply/Media: allow image-only inbound messages (no caption) to reach the agent instead of short-circuiting as empty text, and preserve thread context in queued/followup prompt bodies for media-only runs. (#11916) Thanks @arosstale.
  • -
  • Discord: route autoThread replies to existing threads instead of the root channel. (#8302) Thanks @gavinbmoore, @thewilloftheshadow.
  • -
  • Web UI: add img to DOMPurify allowed tags and src/alt to allowed attributes so markdown images render in webchat instead of being stripped. (#15437) Thanks @lailoo.
  • -
  • Telegram/Matrix: treat MP3 and M4A (including audio/mp4) as voice-compatible for asVoice routing, and keep WAV/AAC falling back to regular audio sends. (#15438) Thanks @azade-c.
  • -
  • WhatsApp: preserve outbound document filenames for web-session document sends instead of always sending "file". (#15594) Thanks @TsekaLuk.
  • -
  • Telegram: cap bot menu registration to Telegram's 100-command limit with an overflow warning while keeping typed hidden commands available. (#15844) Thanks @battman21.
  • -
  • Telegram: scope skill commands to the resolved agent for default accounts so setMyCommands no longer triggers BOT_COMMANDS_TOO_MUCH when multiple agents are configured. (#15599)
  • -
  • Discord: avoid misrouting numeric guild allowlist entries to /channels/ by prefixing guild-only inputs with guild: during resolution. (#12326) Thanks @headswim.
  • -
  • MS Teams: preserve parsed mention entities/text when appending OneDrive fallback file links, and accept broader real-world Teams mention ID formats (29:..., 8:orgid:...) while still rejecting placeholder patterns. (#15436) Thanks @hyojin.
  • -
  • Media: classify text/* MIME types as documents in media-kind routing so text attachments are no longer treated as unknown. (#12237) Thanks @arosstale.
  • -
  • Inbound/Web UI: preserve literal \n sequences when normalizing inbound text so Windows paths like C:\\Work\\nxxx\\README.md are not corrupted. (#11547) Thanks @mcaxtr.
  • -
  • TUI/Streaming: preserve richer streamed assistant text when final payload drops pre-tool-call text blocks, while keeping non-empty final payload authoritative for plain-text updates. (#15452) Thanks @TsekaLuk.
  • -
  • Providers/MiniMax: switch implicit MiniMax API-key provider from openai-completions to anthropic-messages with the correct Anthropic-compatible base URL, fixing invalid role: developer (2013) errors on MiniMax M2.5. (#15275) Thanks @lailoo.
  • -
  • Ollama/Agents: use resolved model/provider base URLs for native /api/chat streaming (including aliased providers), normalize /v1 endpoints, and forward abort + maxTokens stream options for reliable cancellation and token caps. (#11853) Thanks @BrokenFinger98.
  • -
  • OpenAI Codex/Spark: implement end-to-end gpt-5.3-codex-spark support across fallback/thinking/model resolution and models list forward-compat visibility. (#14990, #15174) Thanks @L-U-C-K-Y, @loiie45e.
  • -
  • Agents/Codex: allow gpt-5.3-codex-spark in forward-compat fallback, live model filtering, and thinking presets, and fix model-picker recognition for spark. (#14990) Thanks @L-U-C-K-Y.
  • -
  • Models/Codex: resolve configured openai-codex/gpt-5.3-codex-spark through forward-compat fallback during models list, so it is not incorrectly tagged as missing when runtime resolution succeeds. (#15174) Thanks @loiie45e.
  • -
  • OpenAI Codex/Auth: bridge OpenClaw OAuth profiles into pi auth.json so model discovery and models-list registry resolution can use Codex OAuth credentials. (#15184) Thanks @loiie45e.
  • -
  • Auth/OpenAI Codex: share OAuth login handling across onboarding and models auth login --provider openai-codex, keep onboarding alive when OAuth fails, and surface a direct OAuth help note instead of terminating the wizard. (#15406, follow-up to #14552) Thanks @zhiluo20.
  • -
  • Onboarding/Providers: add vLLM as an onboarding provider with model discovery, auth profile wiring, and non-interactive auth-choice validation. (#12577) Thanks @gejifeng.
  • -
  • Onboarding/Providers: preserve Hugging Face auth intent in auth-choice remapping (tokenProvider=huggingface with authChoice=apiKey) and skip env-override prompts when an explicit token is provided. (#13472) Thanks @Josephrp.
  • -
  • Onboarding/CLI: restore terminal state without resuming paused stdin, so onboarding exits cleanly after choosing Web UI and the installer returns instead of appearing stuck.
  • -
  • Signal/Install: auto-install signal-cli via Homebrew on non-x64 Linux architectures, avoiding x86_64 native binary Exec format error failures on arm64/arm hosts. (#15443) Thanks @jogvan-k.
  • -
  • macOS Voice Wake: fix a crash in trigger trimming for CJK/Unicode transcripts by matching and slicing on original-string ranges instead of transformed-string indices. (#11052) Thanks @Flash-LHR.
  • -
  • Mattermost (plugin): retry websocket monitor connections with exponential backoff and abort-aware teardown so transient connect failures no longer permanently stop monitoring. (#14962) Thanks @mcaxtr.
  • -
  • Discord/Agents: apply channel/group historyLimit during embedded-runner history compaction to prevent long-running channel sessions from bypassing truncation and overflowing context windows. (#11224) Thanks @shadril238.
  • -
  • Outbound targets: fail closed for WhatsApp/Twitch/Google Chat fallback paths so invalid or missing targets are dropped instead of rerouted, and align resolver hints with strict target requirements. (#13578) Thanks @mcaxtr.
  • -
  • Gateway/Restart: clear stale command-queue and heartbeat wake runtime state after SIGUSR1 in-process restarts to prevent zombie gateway behavior where queued work stops draining. (#15195) Thanks @joeykrug.
  • -
  • Heartbeat: prevent scheduler silent-death races during runner reloads, preserve retry cooldown backoff under wake bursts, and prioritize user/action wake causes over interval/retry reasons when coalescing. (#15108) Thanks @joeykrug.
  • -
  • Heartbeat: allow explicit wake (wake) and hook wake (hook:*) reasons to run even when HEARTBEAT.md is effectively empty so queued system events are processed. (#14527) Thanks @arosstale.
  • -
  • Auto-reply/Heartbeat: strip sentence-ending HEARTBEAT_OK tokens even when followed by up to 4 punctuation characters, while preserving surrounding sentence punctuation. (#15847) Thanks @Spacefish.
  • -
  • Agents/Heartbeat: stop auto-creating HEARTBEAT.md during workspace bootstrap so missing files continue to run heartbeat as documented. (#11766) Thanks @shadril238.
  • -
  • Sessions/Agents: pass agentId when resolving existing transcript paths in reply runs so non-default agents and heartbeat/chat handlers no longer fail with Session file path must be within sessions directory. (#15141) Thanks @Goldenmonstew.
  • -
  • Sessions/Agents: pass agentId through status and usage transcript-resolution paths (auto-reply, gateway usage APIs, and session cost/log loaders) so non-default agents can resolve absolute session files without path-validation failures. (#15103) Thanks @jalehman.
  • -
  • Sessions: archive previous transcript files on /new and /reset session resets (including gateway sessions.reset) so stale transcripts do not accumulate on disk. (#14869) Thanks @mcaxtr.
  • -
  • Status/Sessions: stop clamping derived totalTokens to context-window size, keep prompt-token snapshots wired through session accounting, and surface context usage as unknown when fresh snapshot data is missing to avoid false 100% reports. (#15114) Thanks @echoVic.
  • -
  • CLI/Completion: route plugin-load logs to stderr and write generated completion scripts directly to stdout to avoid source <(openclaw completion ...) corruption. (#15481) Thanks @arosstale.
  • -
  • CLI: lazily load outbound provider dependencies and remove forced success-path exits so commands terminate naturally without killing intentional long-running foreground actions. (#12906) Thanks @DrCrinkle.
  • -
  • Security/Gateway + ACP: block high-risk tools (sessions_spawn, sessions_send, gateway, whatsapp_login) from HTTP /tools/invoke by default with gateway.tools.{allow,deny} overrides, and harden ACP permission selection to fail closed when tool identity/options are ambiguous while supporting allow_always/reject_always. (#15390) Thanks @aether-ai-agent.
  • -
  • Security/Gateway: breaking default-behavior change - canvas IP-based auth fallback now only accepts machine-scoped addresses (RFC1918, link-local, ULA IPv6, CGNAT); public-source IP matches now require bearer token auth. (#14661) Thanks @sumleo.
  • -
  • Security/Link understanding: block loopback/internal host patterns and private/mapped IPv6 addresses in extracted URL handling to close SSRF bypasses in link CLI flows. (#15604) Thanks @AI-Reviewer-QS.
  • -
  • Security/Browser: constrain POST /trace/stop, POST /wait/download, and POST /download output paths to OpenClaw temp roots and reject traversal/escape paths.
  • -
  • Security/Canvas: serve A2UI assets via the shared safe-open path (openFileWithinRoot) to close traversal/TOCTOU gaps, with traversal and symlink regression coverage. (#10525) Thanks @abdelsfane.
  • -
  • Security/WhatsApp: enforce 0o600 on creds.json and creds.json.bak on save/backup/restore paths to reduce credential file exposure. (#10529) Thanks @abdelsfane.
  • -
  • Security/Gateway: sanitize and truncate untrusted WebSocket header values in pre-handshake close logs to reduce log-poisoning risk. Thanks @thewilloftheshadow.
  • -
  • Security/Audit: add misconfiguration checks for sandbox Docker config with sandbox mode off, ineffective gateway.nodes.denyCommands entries, global minimal tool-profile overrides by agent profiles, and permissive extension-plugin tool reachability.
  • -
  • Security/Audit: distinguish external webhooks (hooks.enabled) from internal hooks (hooks.internal.enabled) in attack-surface summaries to avoid false exposure signals when only internal hooks are enabled. (#13474) Thanks @mcaxtr.
  • -
  • Security/Onboarding: clarify multi-user DM isolation remediation with explicit openclaw config set session.dmScope ... commands in security audit, doctor security, and channel onboarding guidance. (#13129) Thanks @VintLin.
  • -
  • Agents/Nodes: harden node exec approval decision handling in the nodes tool run path by failing closed on unexpected approval decisions, and add regression coverage for approval-required retry/deny/timeout flows. (#4726) Thanks @rmorse.
  • -
  • Android/Nodes: harden app.update by requiring HTTPS and gateway-host URL matching plus SHA-256 verification, stream URL camera downloads to disk with size guards to avoid memory spikes, and stop signing release builds with debug keys. (#13541) Thanks @smartprogrammer93.
  • -
  • Routing: enforce strict binding-scope matching across peer/guild/team/roles so peer-scoped Discord/Slack bindings no longer match unrelated guild/team contexts or fallback tiers. (#15274) Thanks @lailoo.
  • -
  • Exec/Allowlist: allow multiline heredoc bodies (<<, <<-) while keeping multiline non-heredoc shell commands blocked, so exec approval parsing permits heredoc input safely without allowing general newline command chaining. (#13811) Thanks @mcaxtr.
  • -
  • Config: preserve ${VAR} env references when writing config files so openclaw config set/apply/patch does not persist secrets to disk. Thanks @thewilloftheshadow.
  • -
  • Config: remove a cross-request env-snapshot race in config writes by carrying read-time env context into write calls per request, preserving ${VAR} refs safely under concurrent gateway config mutations. (#11560) Thanks @akoscz.
  • -
  • Config: log overwrite audit entries (path, backup target, and hash transition) whenever an existing config file is replaced, improving traceability for unexpected config clobbers.
  • -
  • Config: keep legacy audio transcription migration strict by rejecting non-string/unsafe command tokens while still migrating valid custom script executables. (#5042) Thanks @shayan919293.
  • -
  • Config: accept $schema key in config file so JSON Schema editor tooling works without validation errors. (#14998)
  • -
  • Gateway/Tools Invoke: sanitize /tools/invoke execution failures while preserving 400 for tool input errors and returning 500 for unexpected runtime failures, with regression coverage and docs updates. (#13185) Thanks @davidrudduck.
  • -
  • Gateway/Hooks: preserve 408 for hook request-body timeout responses while keeping bounded auth-failure cache eviction behavior, with timeout-status regression coverage. (#15848) Thanks @AI-Reviewer-QS.
  • -
  • Plugins/Hooks: fire before_tool_call hook exactly once per tool invocation in embedded runs by removing duplicate dispatch paths while preserving parameter mutation semantics. (#15635) Thanks @lailoo.
  • -
  • Agents/Transcript policy: sanitize OpenAI/Codex tool-call ids during transcript policy normalization to prevent invalid tool-call identifiers from propagating into session history. (#15279) Thanks @divisonofficer.
  • -
  • Agents/Image tool: cap image-analysis completion maxTokens by model capability (min(4096, model.maxTokens)) to avoid over-limit provider failures while still preventing truncation. (#11770) Thanks @detecti1.
  • -
  • Agents/Compaction: centralize exec default resolution in the shared tool factory so per-agent tools.exec overrides (host/security/ask/node and related defaults) persist across compaction retries. (#15833) Thanks @napetrov.
  • -
  • Gateway/Agents: stop injecting a phantom main agent into gateway agent listings when agents.list explicitly excludes it. (#11450) Thanks @arosstale.
  • -
  • Process/Exec: avoid shell execution for .exe commands on Windows so env overrides work reliably in runCommandWithTimeout. Thanks @thewilloftheshadow.
  • -
  • Daemon/Windows: preserve literal backslashes in gateway.cmd command parsing so drive and UNC paths are not corrupted in runtime checks and doctor entrypoint comparisons. (#15642) Thanks @arosstale.
  • -
  • Sandbox: pass configured sandbox.docker.env variables to sandbox containers at docker create time. (#15138) Thanks @stevebot-alive.
  • -
  • Voice Call: route webhook runtime event handling through shared manager event logic so rejected inbound hangups are idempotent in production, with regression tests for duplicate reject events and provider-call-ID remapping parity. (#15892) Thanks @dcantu96.
  • -
  • Cron: add regression coverage for announce-mode isolated jobs so runs that already report delivered: true do not enqueue duplicate main-session relays, including delivery configs where mode is omitted and defaults to announce. (#15737) Thanks @brandonwise.
  • -
  • Cron: honor deleteAfterRun in isolated announce delivery by mapping it to subagent announce cleanup mode, so cron run sessions configured for deletion are removed after completion. (#15368) Thanks @arosstale.
  • -
  • Web tools/web_fetch: prefer text/markdown responses for Cloudflare Markdown for Agents, add cf-markdown extraction for markdown bodies, and redact fetched URLs in x-markdown-tokens debug logs to avoid leaking raw paths/query params. (#15376) Thanks @Yaxuan42.
  • -
  • Clawdock: avoid Zsh readonly variable collisions in helper scripts. (#15501) Thanks @nkelner.
  • -
  • Memory: switch default local embedding model to the QAT embeddinggemma-300m-qat-Q8_0 variant for better quality at the same footprint. (#15429) Thanks @azade-c.
  • -
  • Docs/Mermaid: remove hardcoded Mermaid init theme blocks from four docs diagrams so dark mode inherits readable theme defaults. (#15157) Thanks @heytulsiprasad.
  • -
-

View full changelog

-]]>
- -
-
-
\ No newline at end of file diff --git a/askonce.png b/askonce.png new file mode 100644 index 0000000000..3799a62728 Binary files /dev/null and b/askonce.png differ diff --git a/assets/avatar-placeholder.svg b/assets/avatar-placeholder.svg deleted file mode 100644 index d0a6999abf..0000000000 --- a/assets/avatar-placeholder.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/assets/chrome-extension/README.md b/assets/chrome-extension/README.md deleted file mode 100644 index 4ee072c1f2..0000000000 --- a/assets/chrome-extension/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# OpenClaw Chrome Extension (Browser Relay) - -Purpose: attach OpenClaw to an existing Chrome tab so the Gateway can automate it (via the local CDP relay server). - -## Dev / load unpacked - -1. Build/run OpenClaw Gateway with browser control enabled. -2. Ensure the relay server is reachable at `http://127.0.0.1:18792/` (default). -3. Install the extension to a stable path: - - ```bash - openclaw browser extension install - openclaw browser extension path - ``` - -4. Chrome → `chrome://extensions` → enable “Developer mode”. -5. “Load unpacked” → select the path printed above. -6. Pin the extension. Click the icon on a tab to attach/detach. - -## Options - -- `Relay port`: defaults to `18792`. -- `Gateway token`: required. Set this to `gateway.auth.token` (or `OPENCLAW_GATEWAY_TOKEN`). diff --git a/assets/chrome-extension/background.js b/assets/chrome-extension/background.js deleted file mode 100644 index 7a1754e06c..0000000000 --- a/assets/chrome-extension/background.js +++ /dev/null @@ -1,453 +0,0 @@ -const DEFAULT_PORT = 18792 - -const BADGE = { - on: { text: 'ON', color: '#FF5A36' }, - off: { text: '', color: '#000000' }, - connecting: { text: '…', color: '#F59E0B' }, - error: { text: '!', color: '#B91C1C' }, -} - -/** @type {WebSocket|null} */ -let relayWs = null -/** @type {Promise|null} */ -let relayConnectPromise = null - -let debuggerListenersInstalled = false - -let nextSession = 1 - -/** @type {Map} */ -const tabs = new Map() -/** @type {Map} */ -const tabBySession = new Map() -/** @type {Map} */ -const childSessionToTab = new Map() - -/** @type {Mapvoid, reject:(e:Error)=>void}>} */ -const pending = new Map() - -function nowStack() { - try { - return new Error().stack || '' - } catch { - return '' - } -} - -async function getRelayPort() { - const stored = await chrome.storage.local.get(['relayPort']) - const raw = stored.relayPort - const n = Number.parseInt(String(raw || ''), 10) - if (!Number.isFinite(n) || n <= 0 || n > 65535) return DEFAULT_PORT - return n -} - -async function getGatewayToken() { - const stored = await chrome.storage.local.get(['gatewayToken']) - const token = String(stored.gatewayToken || '').trim() - return token || '' -} - -function setBadge(tabId, kind) { - const cfg = BADGE[kind] - void chrome.action.setBadgeText({ tabId, text: cfg.text }) - void chrome.action.setBadgeBackgroundColor({ tabId, color: cfg.color }) - void chrome.action.setBadgeTextColor({ tabId, color: '#FFFFFF' }).catch(() => {}) -} - -async function ensureRelayConnection() { - if (relayWs && relayWs.readyState === WebSocket.OPEN) return - if (relayConnectPromise) return await relayConnectPromise - - relayConnectPromise = (async () => { - const port = await getRelayPort() - const gatewayToken = await getGatewayToken() - const httpBase = `http://127.0.0.1:${port}` - const wsUrl = gatewayToken - ? `ws://127.0.0.1:${port}/extension?token=${encodeURIComponent(gatewayToken)}` - : `ws://127.0.0.1:${port}/extension` - - // Fast preflight: is the relay server up? - try { - await fetch(`${httpBase}/`, { method: 'HEAD', signal: AbortSignal.timeout(2000) }) - } catch (err) { - throw new Error(`Relay server not reachable at ${httpBase} (${String(err)})`) - } - - if (!gatewayToken) { - throw new Error( - 'Missing gatewayToken in extension settings (chrome.storage.local.gatewayToken)', - ) - } - - const ws = new WebSocket(wsUrl) - relayWs = ws - - await new Promise((resolve, reject) => { - const t = setTimeout(() => reject(new Error('WebSocket connect timeout')), 5000) - ws.onopen = () => { - clearTimeout(t) - resolve() - } - ws.onerror = () => { - clearTimeout(t) - reject(new Error('WebSocket connect failed')) - } - ws.onclose = (ev) => { - clearTimeout(t) - reject(new Error(`WebSocket closed (${ev.code} ${ev.reason || 'no reason'})`)) - } - }) - - ws.onmessage = (event) => void onRelayMessage(String(event.data || '')) - ws.onclose = () => onRelayClosed('closed') - ws.onerror = () => onRelayClosed('error') - - if (!debuggerListenersInstalled) { - debuggerListenersInstalled = true - chrome.debugger.onEvent.addListener(onDebuggerEvent) - chrome.debugger.onDetach.addListener(onDebuggerDetach) - } - })() - - try { - await relayConnectPromise - } finally { - relayConnectPromise = null - } -} - -function onRelayClosed(reason) { - relayWs = null - for (const [id, p] of pending.entries()) { - pending.delete(id) - p.reject(new Error(`Relay disconnected (${reason})`)) - } - - for (const tabId of tabs.keys()) { - void chrome.debugger.detach({ tabId }).catch(() => {}) - setBadge(tabId, 'connecting') - void chrome.action.setTitle({ - tabId, - title: 'OpenClaw Browser Relay: disconnected (click to re-attach)', - }) - } - tabs.clear() - tabBySession.clear() - childSessionToTab.clear() -} - -function sendToRelay(payload) { - const ws = relayWs - if (!ws || ws.readyState !== WebSocket.OPEN) { - throw new Error('Relay not connected') - } - ws.send(JSON.stringify(payload)) -} - -async function maybeOpenHelpOnce() { - try { - const stored = await chrome.storage.local.get(['helpOnErrorShown']) - if (stored.helpOnErrorShown === true) return - await chrome.storage.local.set({ helpOnErrorShown: true }) - await chrome.runtime.openOptionsPage() - } catch { - // ignore - } -} - -function requestFromRelay(command) { - const id = command.id - return new Promise((resolve, reject) => { - pending.set(id, { resolve, reject }) - try { - sendToRelay(command) - } catch (err) { - pending.delete(id) - reject(err instanceof Error ? err : new Error(String(err))) - } - }) -} - -async function onRelayMessage(text) { - /** @type {any} */ - let msg - try { - msg = JSON.parse(text) - } catch { - return - } - - if (msg && msg.method === 'ping') { - try { - sendToRelay({ method: 'pong' }) - } catch { - // ignore - } - return - } - - if (msg && typeof msg.id === 'number' && (msg.result !== undefined || msg.error !== undefined)) { - const p = pending.get(msg.id) - if (!p) return - pending.delete(msg.id) - if (msg.error) p.reject(new Error(String(msg.error))) - else p.resolve(msg.result) - return - } - - if (msg && typeof msg.id === 'number' && msg.method === 'forwardCDPCommand') { - try { - const result = await handleForwardCdpCommand(msg) - sendToRelay({ id: msg.id, result }) - } catch (err) { - sendToRelay({ id: msg.id, error: err instanceof Error ? err.message : String(err) }) - } - } -} - -function getTabBySessionId(sessionId) { - const direct = tabBySession.get(sessionId) - if (direct) return { tabId: direct, kind: 'main' } - const child = childSessionToTab.get(sessionId) - if (child) return { tabId: child, kind: 'child' } - return null -} - -function getTabByTargetId(targetId) { - for (const [tabId, tab] of tabs.entries()) { - if (tab.targetId === targetId) return tabId - } - return null -} - -async function attachTab(tabId, opts = {}) { - const debuggee = { tabId } - await chrome.debugger.attach(debuggee, '1.3') - await chrome.debugger.sendCommand(debuggee, 'Page.enable').catch(() => {}) - - const info = /** @type {any} */ (await chrome.debugger.sendCommand(debuggee, 'Target.getTargetInfo')) - const targetInfo = info?.targetInfo - const targetId = String(targetInfo?.targetId || '').trim() - if (!targetId) { - throw new Error('Target.getTargetInfo returned no targetId') - } - - const sessionId = `cb-tab-${nextSession++}` - const attachOrder = nextSession - - tabs.set(tabId, { state: 'connected', sessionId, targetId, attachOrder }) - tabBySession.set(sessionId, tabId) - void chrome.action.setTitle({ - tabId, - title: 'OpenClaw Browser Relay: attached (click to detach)', - }) - - if (!opts.skipAttachedEvent) { - sendToRelay({ - method: 'forwardCDPEvent', - params: { - method: 'Target.attachedToTarget', - params: { - sessionId, - targetInfo: { ...targetInfo, attached: true }, - waitingForDebugger: false, - }, - }, - }) - } - - setBadge(tabId, 'on') - return { sessionId, targetId } -} - -async function detachTab(tabId, reason) { - const tab = tabs.get(tabId) - if (tab?.sessionId && tab?.targetId) { - try { - sendToRelay({ - method: 'forwardCDPEvent', - params: { - method: 'Target.detachedFromTarget', - params: { sessionId: tab.sessionId, targetId: tab.targetId, reason }, - }, - }) - } catch { - // ignore - } - } - - if (tab?.sessionId) tabBySession.delete(tab.sessionId) - tabs.delete(tabId) - - for (const [childSessionId, parentTabId] of childSessionToTab.entries()) { - if (parentTabId === tabId) childSessionToTab.delete(childSessionId) - } - - try { - await chrome.debugger.detach({ tabId }) - } catch { - // ignore - } - - setBadge(tabId, 'off') - void chrome.action.setTitle({ - tabId, - title: 'OpenClaw Browser Relay (click to attach/detach)', - }) -} - -async function connectOrToggleForActiveTab() { - const [active] = await chrome.tabs.query({ active: true, currentWindow: true }) - const tabId = active?.id - if (!tabId) return - - const existing = tabs.get(tabId) - if (existing?.state === 'connected') { - await detachTab(tabId, 'toggle') - return - } - - tabs.set(tabId, { state: 'connecting' }) - setBadge(tabId, 'connecting') - void chrome.action.setTitle({ - tabId, - title: 'OpenClaw Browser Relay: connecting to local relay…', - }) - - try { - await ensureRelayConnection() - await attachTab(tabId) - } catch (err) { - tabs.delete(tabId) - setBadge(tabId, 'error') - void chrome.action.setTitle({ - tabId, - title: 'OpenClaw Browser Relay: relay not running (open options for setup)', - }) - void maybeOpenHelpOnce() - // Extra breadcrumbs in chrome://extensions service worker logs. - const message = err instanceof Error ? err.message : String(err) - console.warn('attach failed', message, nowStack()) - } -} - -async function handleForwardCdpCommand(msg) { - const method = String(msg?.params?.method || '').trim() - const params = msg?.params?.params || undefined - const sessionId = typeof msg?.params?.sessionId === 'string' ? msg.params.sessionId : undefined - - // Map command to tab - const bySession = sessionId ? getTabBySessionId(sessionId) : null - const targetId = typeof params?.targetId === 'string' ? params.targetId : undefined - const tabId = - bySession?.tabId || - (targetId ? getTabByTargetId(targetId) : null) || - (() => { - // No sessionId: pick the first connected tab (stable-ish). - for (const [id, tab] of tabs.entries()) { - if (tab.state === 'connected') return id - } - return null - })() - - if (!tabId) throw new Error(`No attached tab for method ${method}`) - - /** @type {chrome.debugger.DebuggerSession} */ - const debuggee = { tabId } - - if (method === 'Runtime.enable') { - try { - await chrome.debugger.sendCommand(debuggee, 'Runtime.disable') - await new Promise((r) => setTimeout(r, 50)) - } catch { - // ignore - } - return await chrome.debugger.sendCommand(debuggee, 'Runtime.enable', params) - } - - if (method === 'Target.createTarget') { - const url = typeof params?.url === 'string' ? params.url : 'about:blank' - const tab = await chrome.tabs.create({ url, active: false }) - if (!tab.id) throw new Error('Failed to create tab') - await new Promise((r) => setTimeout(r, 100)) - const attached = await attachTab(tab.id) - return { targetId: attached.targetId } - } - - if (method === 'Target.closeTarget') { - const target = typeof params?.targetId === 'string' ? params.targetId : '' - const toClose = target ? getTabByTargetId(target) : tabId - if (!toClose) return { success: false } - try { - await chrome.tabs.remove(toClose) - } catch { - return { success: false } - } - return { success: true } - } - - if (method === 'Target.activateTarget') { - const target = typeof params?.targetId === 'string' ? params.targetId : '' - const toActivate = target ? getTabByTargetId(target) : tabId - if (!toActivate) return {} - const tab = await chrome.tabs.get(toActivate).catch(() => null) - if (!tab) return {} - if (tab.windowId) { - await chrome.windows.update(tab.windowId, { focused: true }).catch(() => {}) - } - await chrome.tabs.update(toActivate, { active: true }).catch(() => {}) - return {} - } - - const tabState = tabs.get(tabId) - const mainSessionId = tabState?.sessionId - const debuggerSession = - sessionId && mainSessionId && sessionId !== mainSessionId - ? { ...debuggee, sessionId } - : debuggee - - return await chrome.debugger.sendCommand(debuggerSession, method, params) -} - -function onDebuggerEvent(source, method, params) { - const tabId = source.tabId - if (!tabId) return - const tab = tabs.get(tabId) - if (!tab?.sessionId) return - - if (method === 'Target.attachedToTarget' && params?.sessionId) { - childSessionToTab.set(String(params.sessionId), tabId) - } - - if (method === 'Target.detachedFromTarget' && params?.sessionId) { - childSessionToTab.delete(String(params.sessionId)) - } - - try { - sendToRelay({ - method: 'forwardCDPEvent', - params: { - sessionId: source.sessionId || tab.sessionId, - method, - params, - }, - }) - } catch { - // ignore - } -} - -function onDebuggerDetach(source, reason) { - const tabId = source.tabId - if (!tabId) return - if (!tabs.has(tabId)) return - void detachTab(tabId, reason) -} - -chrome.action.onClicked.addListener(() => void connectOrToggleForActiveTab()) - -chrome.runtime.onInstalled.addListener(() => { - // Useful: first-time instructions. - void chrome.runtime.openOptionsPage() -}) diff --git a/assets/chrome-extension/icons/icon128.png b/assets/chrome-extension/icons/icon128.png deleted file mode 100644 index 533cc812de..0000000000 Binary files a/assets/chrome-extension/icons/icon128.png and /dev/null differ diff --git a/assets/chrome-extension/icons/icon16.png b/assets/chrome-extension/icons/icon16.png deleted file mode 100644 index 1be23ae89b..0000000000 Binary files a/assets/chrome-extension/icons/icon16.png and /dev/null differ diff --git a/assets/chrome-extension/icons/icon32.png b/assets/chrome-extension/icons/icon32.png deleted file mode 100644 index f4c1be8a6a..0000000000 Binary files a/assets/chrome-extension/icons/icon32.png and /dev/null differ diff --git a/assets/chrome-extension/icons/icon48.png b/assets/chrome-extension/icons/icon48.png deleted file mode 100644 index d2a278af59..0000000000 Binary files a/assets/chrome-extension/icons/icon48.png and /dev/null differ diff --git a/assets/chrome-extension/manifest.json b/assets/chrome-extension/manifest.json deleted file mode 100644 index d6b593990d..0000000000 --- a/assets/chrome-extension/manifest.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "manifest_version": 3, - "name": "OpenClaw Browser Relay", - "version": "0.1.0", - "description": "Attach OpenClaw to your existing Chrome tab via a local CDP relay server.", - "icons": { - "16": "icons/icon16.png", - "32": "icons/icon32.png", - "48": "icons/icon48.png", - "128": "icons/icon128.png" - }, - "permissions": ["debugger", "tabs", "activeTab", "storage"], - "host_permissions": ["http://127.0.0.1/*", "http://localhost/*"], - "background": { "service_worker": "background.js", "type": "module" }, - "action": { - "default_title": "OpenClaw Browser Relay (click to attach/detach)", - "default_icon": { - "16": "icons/icon16.png", - "32": "icons/icon32.png", - "48": "icons/icon48.png", - "128": "icons/icon128.png" - } - }, - "options_ui": { "page": "options.html", "open_in_tab": true } -} diff --git a/assets/chrome-extension/options.html b/assets/chrome-extension/options.html deleted file mode 100644 index 17fc6a79ee..0000000000 --- a/assets/chrome-extension/options.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - OpenClaw Browser Relay - - - -
-
- -
-

OpenClaw Browser Relay

-

Click the toolbar button on a tab to attach / detach.

-
-
- -
-
-

Getting started

-

- If you see a red ! badge on the extension icon, the relay server is not reachable. - Start OpenClaw’s browser relay on this machine (Gateway or node host), then click the toolbar button again. -

-

- Full guide (install, remote Gateway, security): docs.openclaw.ai/tools/chrome-extension -

-
- -
-

Relay connection

- -
- -
- -
- - -
-
- Default port: 18792. Extension connects to: http://127.0.0.1:<port>/. - Gateway token must match gateway.auth.token (or OPENCLAW_GATEWAY_TOKEN). -
-
-
-
- - -
- - diff --git a/assets/chrome-extension/options.js b/assets/chrome-extension/options.js deleted file mode 100644 index e4252ccae4..0000000000 --- a/assets/chrome-extension/options.js +++ /dev/null @@ -1,83 +0,0 @@ -const DEFAULT_PORT = 18792 - -function clampPort(value) { - const n = Number.parseInt(String(value || ''), 10) - if (!Number.isFinite(n)) return DEFAULT_PORT - if (n <= 0 || n > 65535) return DEFAULT_PORT - return n -} - -function updateRelayUrl(port) { - const el = document.getElementById('relay-url') - if (!el) return - el.textContent = `http://127.0.0.1:${port}/` -} - -function relayHeaders(token) { - const t = String(token || '').trim() - if (!t) return {} - return { 'x-openclaw-relay-token': t } -} - -function setStatus(kind, message) { - const status = document.getElementById('status') - if (!status) return - status.dataset.kind = kind || '' - status.textContent = message || '' -} - -async function checkRelayReachable(port, token) { - const url = `http://127.0.0.1:${port}/json/version` - const trimmedToken = String(token || '').trim() - if (!trimmedToken) { - setStatus('error', 'Gateway token required. Save your gateway token to connect.') - return - } - const ctrl = new AbortController() - const t = setTimeout(() => ctrl.abort(), 1200) - try { - const res = await fetch(url, { - method: 'GET', - headers: relayHeaders(trimmedToken), - signal: ctrl.signal, - }) - if (res.status === 401) { - setStatus('error', 'Gateway token rejected. Check token and save again.') - return - } - if (!res.ok) throw new Error(`HTTP ${res.status}`) - setStatus('ok', `Relay reachable and authenticated at http://127.0.0.1:${port}/`) - } catch { - setStatus( - 'error', - `Relay not reachable/authenticated at http://127.0.0.1:${port}/. Start OpenClaw browser relay and verify token.`, - ) - } finally { - clearTimeout(t) - } -} - -async function load() { - const stored = await chrome.storage.local.get(['relayPort', 'gatewayToken']) - const port = clampPort(stored.relayPort) - const token = String(stored.gatewayToken || '').trim() - document.getElementById('port').value = String(port) - document.getElementById('token').value = token - updateRelayUrl(port) - await checkRelayReachable(port, token) -} - -async function save() { - const portInput = document.getElementById('port') - const tokenInput = document.getElementById('token') - const port = clampPort(portInput.value) - const token = String(tokenInput.value || '').trim() - await chrome.storage.local.set({ relayPort: port, gatewayToken: token }) - portInput.value = String(port) - tokenInput.value = token - updateRelayUrl(port) - await checkRelayReachable(port, token) -} - -document.getElementById('save').addEventListener('click', () => void save()) -void load() diff --git a/assets/dmg-background-small.png b/assets/dmg-background-small.png deleted file mode 100644 index 74fc56a904..0000000000 Binary files a/assets/dmg-background-small.png and /dev/null differ diff --git a/assets/dmg-background.png b/assets/dmg-background.png deleted file mode 100644 index a3bff0382b..0000000000 Binary files a/assets/dmg-background.png and /dev/null differ diff --git a/claude.mp4 b/claude.mp4 new file mode 100644 index 0000000000..b4aca57194 Binary files /dev/null and b/claude.mp4 differ diff --git a/deepseek.mp4 b/deepseek.mp4 new file mode 100644 index 0000000000..ed028f181f Binary files /dev/null and b/deepseek.mp4 differ diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 614a1f8d53..0000000000 --- a/docker-compose.yml +++ /dev/null @@ -1,46 +0,0 @@ -services: - openclaw-gateway: - image: ${OPENCLAW_IMAGE:-openclaw:local} - environment: - HOME: /home/node - TERM: xterm-256color - OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN} - CLAUDE_AI_SESSION_KEY: ${CLAUDE_AI_SESSION_KEY} - CLAUDE_WEB_SESSION_KEY: ${CLAUDE_WEB_SESSION_KEY} - CLAUDE_WEB_COOKIE: ${CLAUDE_WEB_COOKIE} - volumes: - - ${OPENCLAW_CONFIG_DIR}:/home/node/.openclaw - - ${OPENCLAW_WORKSPACE_DIR}:/home/node/.openclaw/workspace - ports: - - "${OPENCLAW_GATEWAY_PORT:-18789}:18789" - - "${OPENCLAW_BRIDGE_PORT:-18790}:18790" - init: true - restart: unless-stopped - command: - [ - "node", - "dist/index.js", - "gateway", - "--bind", - "${OPENCLAW_GATEWAY_BIND:-lan}", - "--port", - "18789", - ] - - openclaw-cli: - image: ${OPENCLAW_IMAGE:-openclaw:local} - environment: - HOME: /home/node - TERM: xterm-256color - OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN} - BROWSER: echo - CLAUDE_AI_SESSION_KEY: ${CLAUDE_AI_SESSION_KEY} - CLAUDE_WEB_SESSION_KEY: ${CLAUDE_WEB_SESSION_KEY} - CLAUDE_WEB_COOKIE: ${CLAUDE_WEB_COOKIE} - volumes: - - ${OPENCLAW_CONFIG_DIR}:/home/node/.openclaw - - ${OPENCLAW_WORKSPACE_DIR}:/home/node/.openclaw/workspace - stdin_open: true - tty: true - init: true - entrypoint: ["node", "dist/index.js"] diff --git a/docker-setup.sh b/docker-setup.sh deleted file mode 100755 index 00c3cf1924..0000000000 --- a/docker-setup.sh +++ /dev/null @@ -1,288 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -COMPOSE_FILE="$ROOT_DIR/docker-compose.yml" -EXTRA_COMPOSE_FILE="$ROOT_DIR/docker-compose.extra.yml" -IMAGE_NAME="${OPENCLAW_IMAGE:-openclaw:local}" -EXTRA_MOUNTS="${OPENCLAW_EXTRA_MOUNTS:-}" -HOME_VOLUME_NAME="${OPENCLAW_HOME_VOLUME:-}" - -fail() { - echo "ERROR: $*" >&2 - exit 1 -} - -require_cmd() { - if ! command -v "$1" >/dev/null 2>&1; then - echo "Missing dependency: $1" >&2 - exit 1 - fi -} - -contains_disallowed_chars() { - local value="$1" - [[ "$value" == *$'\n'* || "$value" == *$'\r'* || "$value" == *$'\t'* ]] -} - -validate_mount_path_value() { - local label="$1" - local value="$2" - if [[ -z "$value" ]]; then - fail "$label cannot be empty." - fi - if contains_disallowed_chars "$value"; then - fail "$label contains unsupported control characters." - fi - if [[ "$value" =~ [[:space:]] ]]; then - fail "$label cannot contain whitespace." - fi -} - -validate_named_volume() { - local value="$1" - if [[ ! "$value" =~ ^[A-Za-z0-9][A-Za-z0-9_.-]*$ ]]; then - fail "OPENCLAW_HOME_VOLUME must match [A-Za-z0-9][A-Za-z0-9_.-]* when using a named volume." - fi -} - -validate_mount_spec() { - local mount="$1" - if contains_disallowed_chars "$mount"; then - fail "OPENCLAW_EXTRA_MOUNTS entries cannot contain control characters." - fi - # Keep mount specs strict to avoid YAML structure injection. - # Expected format: source:target[:options] - if [[ ! "$mount" =~ ^[^[:space:],:]+:[^[:space:],:]+(:[^[:space:],:]+)?$ ]]; then - fail "Invalid mount format '$mount'. Expected source:target[:options] without spaces." - fi -} - -require_cmd docker -if ! docker compose version >/dev/null 2>&1; then - echo "Docker Compose not available (try: docker compose version)" >&2 - exit 1 -fi - -OPENCLAW_CONFIG_DIR="${OPENCLAW_CONFIG_DIR:-$HOME/.openclaw}" -OPENCLAW_WORKSPACE_DIR="${OPENCLAW_WORKSPACE_DIR:-$HOME/.openclaw/workspace}" - -validate_mount_path_value "OPENCLAW_CONFIG_DIR" "$OPENCLAW_CONFIG_DIR" -validate_mount_path_value "OPENCLAW_WORKSPACE_DIR" "$OPENCLAW_WORKSPACE_DIR" -if [[ -n "$HOME_VOLUME_NAME" ]]; then - if [[ "$HOME_VOLUME_NAME" == *"/"* ]]; then - validate_mount_path_value "OPENCLAW_HOME_VOLUME" "$HOME_VOLUME_NAME" - else - validate_named_volume "$HOME_VOLUME_NAME" - fi -fi -if contains_disallowed_chars "$EXTRA_MOUNTS"; then - fail "OPENCLAW_EXTRA_MOUNTS cannot contain control characters." -fi - -mkdir -p "$OPENCLAW_CONFIG_DIR" -mkdir -p "$OPENCLAW_WORKSPACE_DIR" - -export OPENCLAW_CONFIG_DIR -export OPENCLAW_WORKSPACE_DIR -export OPENCLAW_GATEWAY_PORT="${OPENCLAW_GATEWAY_PORT:-18789}" -export OPENCLAW_BRIDGE_PORT="${OPENCLAW_BRIDGE_PORT:-18790}" -export OPENCLAW_GATEWAY_BIND="${OPENCLAW_GATEWAY_BIND:-lan}" -export OPENCLAW_IMAGE="$IMAGE_NAME" -export OPENCLAW_DOCKER_APT_PACKAGES="${OPENCLAW_DOCKER_APT_PACKAGES:-}" -export OPENCLAW_EXTRA_MOUNTS="$EXTRA_MOUNTS" -export OPENCLAW_HOME_VOLUME="$HOME_VOLUME_NAME" - -if [[ -z "${OPENCLAW_GATEWAY_TOKEN:-}" ]]; then - if command -v openssl >/dev/null 2>&1; then - OPENCLAW_GATEWAY_TOKEN="$(openssl rand -hex 32)" - else - OPENCLAW_GATEWAY_TOKEN="$(python3 - <<'PY' -import secrets -print(secrets.token_hex(32)) -PY -)" - fi -fi -export OPENCLAW_GATEWAY_TOKEN - -COMPOSE_FILES=("$COMPOSE_FILE") -COMPOSE_ARGS=() - -write_extra_compose() { - local home_volume="$1" - shift - local mount - local gateway_home_mount - local gateway_config_mount - local gateway_workspace_mount - - cat >"$EXTRA_COMPOSE_FILE" <<'YAML' -services: - openclaw-gateway: - volumes: -YAML - - if [[ -n "$home_volume" ]]; then - gateway_home_mount="${home_volume}:/home/node" - gateway_config_mount="${OPENCLAW_CONFIG_DIR}:/home/node/.openclaw" - gateway_workspace_mount="${OPENCLAW_WORKSPACE_DIR}:/home/node/.openclaw/workspace" - validate_mount_spec "$gateway_home_mount" - validate_mount_spec "$gateway_config_mount" - validate_mount_spec "$gateway_workspace_mount" - printf ' - %s\n' "$gateway_home_mount" >>"$EXTRA_COMPOSE_FILE" - printf ' - %s\n' "$gateway_config_mount" >>"$EXTRA_COMPOSE_FILE" - printf ' - %s\n' "$gateway_workspace_mount" >>"$EXTRA_COMPOSE_FILE" - fi - - for mount in "$@"; do - validate_mount_spec "$mount" - printf ' - %s\n' "$mount" >>"$EXTRA_COMPOSE_FILE" - done - - cat >>"$EXTRA_COMPOSE_FILE" <<'YAML' - openclaw-cli: - volumes: -YAML - - if [[ -n "$home_volume" ]]; then - printf ' - %s\n' "$gateway_home_mount" >>"$EXTRA_COMPOSE_FILE" - printf ' - %s\n' "$gateway_config_mount" >>"$EXTRA_COMPOSE_FILE" - printf ' - %s\n' "$gateway_workspace_mount" >>"$EXTRA_COMPOSE_FILE" - fi - - for mount in "$@"; do - validate_mount_spec "$mount" - printf ' - %s\n' "$mount" >>"$EXTRA_COMPOSE_FILE" - done - - if [[ -n "$home_volume" && "$home_volume" != *"/"* ]]; then - validate_named_volume "$home_volume" - cat >>"$EXTRA_COMPOSE_FILE" <>"$tmp" - seen="$seen$k " - replaced=true - break - fi - done - if [[ "$replaced" == false ]]; then - printf '%s\n' "$line" >>"$tmp" - fi - done <"$file" - fi - - for k in "${keys[@]}"; do - if [[ "$seen" != *" $k "* ]]; then - printf '%s=%s\n' "$k" "${!k-}" >>"$tmp" - fi - done - - mv "$tmp" "$file" -} - -upsert_env "$ENV_FILE" \ - OPENCLAW_CONFIG_DIR \ - OPENCLAW_WORKSPACE_DIR \ - OPENCLAW_GATEWAY_PORT \ - OPENCLAW_BRIDGE_PORT \ - OPENCLAW_GATEWAY_BIND \ - OPENCLAW_GATEWAY_TOKEN \ - OPENCLAW_IMAGE \ - OPENCLAW_EXTRA_MOUNTS \ - OPENCLAW_HOME_VOLUME \ - OPENCLAW_DOCKER_APT_PACKAGES - -echo "==> Building Docker image: $IMAGE_NAME" -docker build \ - --build-arg "OPENCLAW_DOCKER_APT_PACKAGES=${OPENCLAW_DOCKER_APT_PACKAGES}" \ - -t "$IMAGE_NAME" \ - -f "$ROOT_DIR/Dockerfile" \ - "$ROOT_DIR" - -echo "" -echo "==> Onboarding (interactive)" -echo "When prompted:" -echo " - Gateway bind: lan" -echo " - Gateway auth: token" -echo " - Gateway token: $OPENCLAW_GATEWAY_TOKEN" -echo " - Tailscale exposure: Off" -echo " - Install Gateway daemon: No" -echo "" -docker compose "${COMPOSE_ARGS[@]}" run --rm openclaw-cli onboard --no-install-daemon - -echo "" -echo "==> Provider setup (optional)" -echo "WhatsApp (QR):" -echo " ${COMPOSE_HINT} run --rm openclaw-cli channels login" -echo "Telegram (bot token):" -echo " ${COMPOSE_HINT} run --rm openclaw-cli channels add --channel telegram --token " -echo "Discord (bot token):" -echo " ${COMPOSE_HINT} run --rm openclaw-cli channels add --channel discord --token " -echo "Docs: https://docs.openclaw.ai/channels" - -echo "" -echo "==> Starting gateway" -docker compose "${COMPOSE_ARGS[@]}" up -d openclaw-gateway - -echo "" -echo "Gateway running with host port mapping." -echo "Access from tailnet devices via the host's tailnet IP." -echo "Config: $OPENCLAW_CONFIG_DIR" -echo "Workspace: $OPENCLAW_WORKSPACE_DIR" -echo "Token: $OPENCLAW_GATEWAY_TOKEN" -echo "" -echo "Commands:" -echo " ${COMPOSE_HINT} logs -f openclaw-gateway" -echo " ${COMPOSE_HINT} exec openclaw-gateway node dist/index.js health --token \"$OPENCLAW_GATEWAY_TOKEN\"" diff --git a/docs.acp.md b/docs.acp.md deleted file mode 100644 index cfe7349c34..0000000000 --- a/docs.acp.md +++ /dev/null @@ -1,197 +0,0 @@ -# OpenClaw ACP Bridge - -This document describes how the OpenClaw ACP (Agent Client Protocol) bridge works, -how it maps ACP sessions to Gateway sessions, and how IDEs should invoke it. - -## Overview - -`openclaw acp` exposes an ACP agent over stdio and forwards prompts to a running -OpenClaw Gateway over WebSocket. It keeps ACP session ids mapped to Gateway -session keys so IDEs can reconnect to the same agent transcript or reset it on -request. - -Key goals: - -- Minimal ACP surface area (stdio, NDJSON). -- Stable session mapping across reconnects. -- Works with existing Gateway session store (list/resolve/reset). -- Safe defaults (isolated ACP session keys by default). - -## How can I use this - -Use ACP when an IDE or tooling speaks Agent Client Protocol and you want it to -drive a OpenClaw Gateway session. - -Quick steps: - -1. Run a Gateway (local or remote). -2. Configure the Gateway target (`gateway.remote.url` + auth) or pass flags. -3. Point the IDE to run `openclaw acp` over stdio. - -Example config: - -```bash -openclaw config set gateway.remote.url wss://gateway-host:18789 -openclaw config set gateway.remote.token -``` - -Example run: - -```bash -openclaw acp --url wss://gateway-host:18789 --token -``` - -## Selecting agents - -ACP does not pick agents directly. It routes by the Gateway session key. - -Use agent-scoped session keys to target a specific agent: - -```bash -openclaw acp --session agent:main:main -openclaw acp --session agent:design:main -openclaw acp --session agent:qa:bug-123 -``` - -Each ACP session maps to a single Gateway session key. One agent can have many -sessions; ACP defaults to an isolated `acp:` session unless you override -the key or label. - -## Zed editor setup - -Add a custom ACP agent in `~/.config/zed/settings.json`: - -```json -{ - "agent_servers": { - "OpenClaw ACP": { - "type": "custom", - "command": "openclaw", - "args": ["acp"], - "env": {} - } - } -} -``` - -To target a specific Gateway or agent: - -```json -{ - "agent_servers": { - "OpenClaw ACP": { - "type": "custom", - "command": "openclaw", - "args": [ - "acp", - "--url", - "wss://gateway-host:18789", - "--token", - "", - "--session", - "agent:design:main" - ], - "env": {} - } - } -} -``` - -In Zed, open the Agent panel and select “OpenClaw ACP” to start a thread. - -## Execution Model - -- ACP client spawns `openclaw acp` and speaks ACP messages over stdio. -- The bridge connects to the Gateway using existing auth config (or CLI flags). -- ACP `prompt` translates to Gateway `chat.send`. -- Gateway streaming events are translated back into ACP streaming events. -- ACP `cancel` maps to Gateway `chat.abort` for the active run. - -## Session Mapping - -By default each ACP session is mapped to a dedicated Gateway session key: - -- `acp:` unless overridden. - -You can override or reuse sessions in two ways: - -1. CLI defaults - -```bash -openclaw acp --session agent:main:main -openclaw acp --session-label "support inbox" -openclaw acp --reset-session -``` - -2. ACP metadata per session - -```json -{ - "_meta": { - "sessionKey": "agent:main:main", - "sessionLabel": "support inbox", - "resetSession": true, - "requireExisting": false - } -} -``` - -Rules: - -- `sessionKey`: direct Gateway session key. -- `sessionLabel`: resolve an existing session by label. -- `resetSession`: mint a new transcript for the key before first use. -- `requireExisting`: fail if the key/label does not exist. - -### Session Listing - -ACP `listSessions` maps to Gateway `sessions.list` and returns a filtered -summary suitable for IDE session pickers. `_meta.limit` can cap the number of -sessions returned. - -## Prompt Translation - -ACP prompt inputs are converted into a Gateway `chat.send`: - -- `text` and `resource` blocks become prompt text. -- `resource_link` with image mime types become attachments. -- The working directory can be prefixed into the prompt (default on, can be - disabled with `--no-prefix-cwd`). - -Gateway streaming events are translated into ACP `message` and `tool_call` -updates. Terminal Gateway states map to ACP `done` with stop reasons: - -- `complete` -> `stop` -- `aborted` -> `cancel` -- `error` -> `error` - -## Auth + Gateway Discovery - -`openclaw acp` resolves the Gateway URL and auth from CLI flags or config: - -- `--url` / `--token` / `--password` take precedence. -- Otherwise use configured `gateway.remote.*` settings. - -## Operational Notes - -- ACP sessions are stored in memory for the bridge process lifetime. -- Gateway session state is persisted by the Gateway itself. -- `--verbose` logs ACP/Gateway bridge events to stderr (never stdout). -- ACP runs can be canceled and the active run id is tracked per session. - -## Compatibility - -- ACP bridge uses `@agentclientprotocol/sdk` (currently 0.13.x). -- Works with ACP clients that implement `initialize`, `newSession`, - `loadSession`, `prompt`, `cancel`, and `listSessions`. - -## Testing - -- Unit: `src/acp/session.test.ts` covers run id lifecycle. -- Full gate: `pnpm build && pnpm check && pnpm test && pnpm docs:build`. - -## Related Docs - -- CLI usage: `docs/cli/acp.md` -- Session model: `docs/concepts/session.md` -- Session management internals: `docs/reference/session-management-compaction.md` diff --git a/docs/.i18n/README.md b/docs/.i18n/README.md deleted file mode 100644 index 8e751a11ea..0000000000 --- a/docs/.i18n/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# OpenClaw docs i18n assets - -This folder stores **generated** and **config** files for documentation translations. - -## Files - -- `glossary..json` — preferred term mappings (used in prompt guidance). -- `.tm.jsonl` — translation memory (cache) keyed by workflow + model + text hash. - -## Glossary format - -`glossary..json` is an array of entries: - -```json -{ - "source": "troubleshooting", - "target": "故障排除", - "ignore_case": true, - "whole_word": false -} -``` - -Fields: - -- `source`: English (or source) phrase to prefer. -- `target`: preferred translation output. - -## Notes - -- Glossary entries are passed to the model as **prompt guidance** (no deterministic rewrites). -- The translation memory is updated by `scripts/docs-i18n`. diff --git a/docs/.i18n/glossary.ja-JP.json b/docs/.i18n/glossary.ja-JP.json deleted file mode 100644 index f7c59a187d..0000000000 --- a/docs/.i18n/glossary.ja-JP.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { "source": "OpenClaw", "target": "OpenClaw" }, - { "source": "Gateway", "target": "Gateway" }, - { "source": "Pi", "target": "Pi" }, - { "source": "Skills", "target": "Skills" }, - { "source": "local loopback", "target": "local loopback" }, - { "source": "Tailscale", "target": "Tailscale" }, - { "source": "Getting Started", "target": "はじめに" }, - { "source": "Getting started", "target": "はじめに" }, - { "source": "Quick start", "target": "クイックスタート" }, - { "source": "Quick Start", "target": "クイックスタート" }, - { "source": "Onboarding", "target": "オンボーディング" }, - { "source": "wizard", "target": "ウィザード" } -] diff --git a/docs/.i18n/glossary.zh-CN.json b/docs/.i18n/glossary.zh-CN.json deleted file mode 100644 index bde108074c..0000000000 --- a/docs/.i18n/glossary.zh-CN.json +++ /dev/null @@ -1,210 +0,0 @@ -[ - { - "source": "OpenClaw", - "target": "OpenClaw" - }, - { - "source": "Gateway", - "target": "Gateway 网关" - }, - { - "source": "Pi", - "target": "Pi" - }, - { - "source": "Skills", - "target": "Skills" - }, - { - "source": "Skills config", - "target": "Skills 配置" - }, - { - "source": "Skills Config", - "target": "Skills 配置" - }, - { - "source": "local loopback", - "target": "local loopback" - }, - { - "source": "Tailscale", - "target": "Tailscale" - }, - { - "source": "Getting Started", - "target": "入门指南" - }, - { - "source": "Getting started", - "target": "入门指南" - }, - { - "source": "Quick start", - "target": "快速开始" - }, - { - "source": "Quick Start", - "target": "快速开始" - }, - { - "source": "Docs directory", - "target": "文档目录" - }, - { - "source": "Credits", - "target": "致谢" - }, - { - "source": "Features", - "target": "功能" - }, - { - "source": "DMs", - "target": "私信" - }, - { - "source": "DM", - "target": "私信" - }, - { - "source": "sandbox", - "target": "沙箱" - }, - { - "source": "Sandbox", - "target": "沙箱" - }, - { - "source": "sandboxing", - "target": "沙箱隔离" - }, - { - "source": "Sandboxing", - "target": "沙箱隔离" - }, - { - "source": "sandboxed", - "target": "沙箱隔离" - }, - { - "source": "Sandboxed", - "target": "沙箱隔离" - }, - { - "source": "Sandboxing note", - "target": "沙箱注意事项" - }, - { - "source": "Companion apps", - "target": "配套应用" - }, - { - "source": "expected keys", - "target": "预期键名" - }, - { - "source": "block streaming", - "target": "分块流式传输" - }, - { - "source": "Block streaming", - "target": "分块流式传输" - }, - { - "source": "Discovery + transports", - "target": "设备发现 + 传输协议" - }, - { - "source": "Discovery", - "target": "设备发现" - }, - { - "source": "Network model", - "target": "网络模型" - }, - { - "source": "for full details", - "target": "了解详情" - }, - { - "source": "First 60 seconds", - "target": "最初的六十秒" - }, - { - "source": "Auth: where it lives (important)", - "target": "凭证:存储位置(重要)" - }, - { - "source": "agent", - "target": "智能体" - }, - { - "source": "channel", - "target": "渠道" - }, - { - "source": "session", - "target": "会话" - }, - { - "source": "provider", - "target": "提供商" - }, - { - "source": "model", - "target": "模型" - }, - { - "source": "tool", - "target": "工具" - }, - { - "source": "CLI", - "target": "CLI" - }, - { - "source": "install sanity", - "target": "安装完整性检查" - }, - { - "source": "get unstuck", - "target": "解决问题" - }, - { - "source": "troubleshooting", - "target": "故障排除" - }, - { - "source": "FAQ", - "target": "常见问题" - }, - { - "source": "onboarding", - "target": "新手引导" - }, - { - "source": "Onboarding", - "target": "新手引导" - }, - { - "source": "wizard", - "target": "向导" - }, - { - "source": "environment variables", - "target": "环境变量" - }, - { - "source": "environment variable", - "target": "环境变量" - }, - { - "source": "env vars", - "target": "环境变量" - }, - { - "source": "env var", - "target": "环境变量" - } -] diff --git a/docs/.i18n/zh-CN.tm.jsonl b/docs/.i18n/zh-CN.tm.jsonl deleted file mode 100644 index 24076e5a08..0000000000 --- a/docs/.i18n/zh-CN.tm.jsonl +++ /dev/null @@ -1,1329 +0,0 @@ -{"cache_key":"001616450ecb371df73ba42e487328ded133e15d365d7ddc15d47eaf467d2e6c","segment_id":"index.md:468886872909c70d","source_path":"index.md","text_hash":"468886872909c70d3bfb4836ec60a6485f4cbbd0f8a0acedbacb9b477f01a251","text":"Workspace templates","translated":"工作区模板","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:17Z"} -{"cache_key":"0090cc37997fe8660527538473feb7d0e0535dfb0015e52d13f2e7ad09bbe185","segment_id":"start/getting-started.md:edeb36e62e1bf30e","source_path":"start/getting-started.md","text_hash":"edeb36e62e1bf30e192bc1951ed9c3f6c65f7d300f926c071c245671dfb5855c","text":"If you’re hacking on OpenClaw itself, run from source:","translated":"如果您正在开发 OpenClaw 本身,请从源码运行:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:45Z"} -{"cache_key":"00ee1ece05b05ab7b12cfe673000c037bb2037fe93a069a71ec2368184e83944","segment_id":"index.md:45e6d69dbe995a36","source_path":"index.md","text_hash":"45e6d69dbe995a36f7bc20755eff4eb4d2afaaedbcac4668ab62540c57219f32","text":"macOS app","translated":"macOS 应用","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:05:06Z"} -{"cache_key":"00eeb87b1774979860c4b016d48e416ab9157539c41f5f3f0c58c1deb8f075c9","segment_id":"environment.md:frontmatter:read_when:2","source_path":"environment.md:frontmatter:read_when:2","text_hash":"822b3d74ce16c1be19059fad4ca5bf7ae9327f58fa1ff4e75e78d5afa75c038f","text":"You are documenting provider auth or deployment environments","translated":"你正在记录提供商认证或部署环境的相关文档","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:51Z"} -{"cache_key":"01063749652c55481b7da485911a80de3049ded0257874b376efbc55a14293a7","segment_id":"start/wizard.md:037b8f564390e097","source_path":"start/wizard.md","text_hash":"037b8f564390e09742421c621a1f785d2ee5338d0c680c76f7a9b991518e909d","text":" and optional ","translated":" 和可选的 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:48:48Z"} -{"cache_key":"01814fd9d09399c075081056c6fa2befa388c67ba4f8745122804fd044fd82d6","segment_id":"start/getting-started.md:d1564fd156e28160","source_path":"start/getting-started.md","text_hash":"d1564fd156e28160c83922ad7a18428ce2c966e790f477e740d1d9f6cadd51e9","text":"WhatsApp (QR login)","translated":"WhatsApp(二维码登录)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:08Z"} -{"cache_key":"01b87576d7ade6b91ca28935f65c167c2f4fb5d1b6bfd1189fd416b229500af4","segment_id":"start/getting-started.md:7421b911bc203f6f","source_path":"start/getting-started.md","text_hash":"7421b911bc203f6fe3c677d752379f23dc314719d39d18179406da675f58d039","text":"Scan via WhatsApp → Settings → Linked Devices.","translated":"通过 WhatsApp → 设置 → 已关联设备 进行扫描。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:10Z"} -{"cache_key":"01d8d8ec84ad8f4c74e29e254e56c02f7d75005160c27d99e9ce183767e16c55","segment_id":"index.md:6b8ebac7903757ce","source_path":"index.md","text_hash":"6b8ebac7903757ce7399cc729651a27e459903c24c64aa94827b20d8a2a411d2","text":"For Tailnet access, run ","translated":"如需 Tailnet 访问,请运行 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:08Z"} -{"cache_key":"024efbb5ac15e07c191effa78c0b23bf173c8af6725e988743ea055e9a4e8c3b","segment_id":"index.md:f9b8279bc46e847b","source_path":"index.md","text_hash":"f9b8279bc46e847bfcc47b8701fd5c5dc27baa304d5add8278a7f97925c3ec13","text":"Mattermost (plugin)","translated":"Mattermost(插件)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:40Z"} -{"cache_key":"02d1e10492e8721462f16e39467b94ad3197e4eb76f6d671a09b4246d5b4d27b","segment_id":"start/getting-started.md:7ac362063b9f2046","source_path":"start/getting-started.md","text_hash":"7ac362063b9f204602f38f9f1ec9cf047f03e0d7b83896571c9df6d31ad41e9c","text":"Nodes","translated":"节点","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:28Z"} -{"cache_key":"02f39c075115bee6bdb015a49436f2b2a56365b87558fdd7aff7b17cb83bff6c","segment_id":"environment.md:frontmatter:summary","source_path":"environment.md:frontmatter:summary","text_hash":"78351223e7068721146d2de022fdf440c2866b2ee02fbbb50bf64369b999820b","text":"Where OpenClaw loads environment variables and the precedence order","translated":"OpenClaw 加载环境变量的位置及优先级顺序","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:19:12Z"} -{"cache_key":"02f4067265058ed8929f3772d87e1c5dc0af8422b8e7b513b7db155108a422c3","segment_id":"start/wizard.md:961eb43699731759","source_path":"start/wizard.md","text_hash":"961eb43699731759fd0d04f177bb24f09971bddd41426702276e761269d0a5b9","text":" does ","translated":" 会 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:48Z"} -{"cache_key":"034b5fd57fbe77f6aabf0b737f4d387868eef9ac32fcc372692191887cb16759","segment_id":"environment.md:ab5aec4424cf678d","source_path":"environment.md","text_hash":"ab5aec4424cf678dcfb1ad3d2c2929c1e0b2b1ff61b82b961ada48ad033367b4","text":" (dotenv default; does not override).","translated":" (dotenv 默认行为;不覆盖已有值)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:07Z"} -{"cache_key":"0361ba41cec2736ce451f58e657735b2d4811f0c3af53356ee56277f825899a3","segment_id":"index.md:7e2735e5df8f4e9f","source_path":"index.md","text_hash":"7e2735e5df8f4e9f006d10e079fe8045612aa662b02a9d1948081d1173798dec","text":"MIT — Free as a lobster in the ocean 🦞","translated":"MIT —— 像海洋中的龙虾一样自由 🦞","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:55:01Z"} -{"cache_key":"039c1b4477a6425d1ad785665fa3ad0b9236c514cd807422215eeb4dc76d4378","segment_id":"start/getting-started.md:e3209251e20896ec","source_path":"start/getting-started.md","text_hash":"e3209251e20896ecc60fa4da2817639f317fbb576288a9fc52d11e5030ecc44a","text":"Windows (WSL2)","translated":"Windows (WSL2)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:44Z"} -{"cache_key":"0457a19cd3a82171f6cdb92d82d5a0f6358da4c1220d42d5b0575bde871e7f91","segment_id":"environment.md:e234227b0e001687","source_path":"environment.md","text_hash":"e234227b0e001687821541fac3af38fc6be293ec6e13910c6826b9afc8ca33be","text":" syntax:","translated":" 语法:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:13:00Z"} -{"cache_key":"045fb6f3989827561e347dfa56a164069bf8b7afaa50d2d02c20ad264495d351","segment_id":"index.md:e9f63c8876aec738","source_path":"index.md","text_hash":"e9f63c8876aec7381ffb5a68efb39f50525f9fc4e732857488561516d47f5654","text":" — Uses Baileys for WhatsApp Web protocol","translated":" — 使用 Baileys 实现 WhatsApp Web 协议","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:31Z"} -{"cache_key":"046c83b658b7dd8bce829f07bd09dcee3413753ab72cf95d638925aa163d3486","segment_id":"start/getting-started.md:f4117324994aaad1","source_path":"start/getting-started.md","text_hash":"f4117324994aaad1d3413064ade8f2037e43ab2fac0b385d731ff154925ec3b3","text":"Windows (PowerShell):","translated":"Windows (PowerShell):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:51Z"} -{"cache_key":"04d48cfdb6b444cb4691ea55a5deb23df20694659ae1bc5e082e242e749f5e3c","segment_id":"help/index.md:bfc5930cc2660330","source_path":"help/index.md","text_hash":"bfc5930cc2660330260afd407e98d86adaec0af48dd72b88dc33ef8e9066e2c9","text":"Install sanity (Node/npm/PATH):","translated":"安装完整性检查(Node/npm/PATH):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:39:38Z"} -{"cache_key":"05405710e256b2e1031234be855a7c11cf1505c627df14884d655fa42a1568a7","segment_id":"index.md:f0a7f9d068cb7a14","source_path":"index.md","text_hash":"f0a7f9d068cb7a146d0bb89b3703688d690ed0b92734b78bcdb909aace617dbf","text":"WhatsApp group messages","translated":"WhatsApp 群组消息","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:45Z"} -{"cache_key":"064dcdb5051313b748c0b775ec69683149e1861d84fa47a74c68ddd8086bdebc","segment_id":"index.md:81a1c0449ea684aa","source_path":"index.md","text_hash":"81a1c0449ea684aadad54a7f8575061ddc5bfa713b6ca3eb8a0228843d2a3ea1","text":"Nodes (iOS/Android)","translated":"节点(iOS/Android)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:57Z"} -{"cache_key":"0687549a28e71ec1e17b261001a9e818e27784ce3286b7d21e856e37c07915a6","segment_id":"start/getting-started.md:bad5d156dc5e0cd3","source_path":"start/getting-started.md","text_hash":"bad5d156dc5e0cd39db3a90645cd150e846743103f3acfa5182ad5a003a172dc","text":"0) Prereqs","translated":"0)前提条件","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:23Z"} -{"cache_key":"06c13f0dfc6cd5fa142e329fd2cfb2538e19e33de83c4b9d366542f0d03cdf08","segment_id":"index.md:c3af076f92c5ed8d","source_path":"index.md","text_hash":"c3af076f92c5ed8dcb0d0b0d36dd120bc31b68264efea96cf8019ca19f1c13a3","text":"Troubleshooting","translated":"故障排除","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:14Z"} -{"cache_key":"06dfb5ef154c29e0961021acb7bcdb34a790d58d9f6f7a59165e7a423ef0f2df","segment_id":"start/wizard.md:0be68bd5c21e5e4d","source_path":"start/wizard.md","text_hash":"0be68bd5c21e5e4de598fc71e32c131ce8c742976a344ac4d9973ef08942eacb","text":"Workspace default (or existing workspace)","translated":"默认工作区(或现有工作区)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:47Z"} -{"cache_key":"071b444d331ae100d5b17caba7748f4d01e9e829b6951ac8b8903bfdb7c00349","segment_id":"environment.md:frontmatter:read_when:2","source_path":"environment.md:frontmatter:read_when:2","text_hash":"822b3d74ce16c1be19059fad4ca5bf7ae9327f58fa1ff4e75e78d5afa75c038f","text":"You are documenting provider auth or deployment environments","translated":"您正在记录 提供商 的认证或部署环境","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:06Z"} -{"cache_key":"074a96a2803f1b7e25df2097aa35c976d3c4bf3355dcb878991d99ceb398cae6","segment_id":"start/wizard.md:2b39d5818b91d602","source_path":"start/wizard.md","text_hash":"2b39d5818b91d602d9aeaaaf38d7de37f9e89553f3edcdf114ae2f43cc8ca399","text":"Full workspace layout + backup guide: ","translated":"完整工作区布局 + 备份指南: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:49Z"} -{"cache_key":"078dae6e59f75f6c474a6f696cdc942ab423be6fcd1bf1bd4b589a665766de76","segment_id":"index.md:310cc8cec6b20a30","source_path":"index.md","text_hash":"310cc8cec6b20a3003ffab12f5aade078a0e7a7d6a27ff166d62ab4c3a1ee23d","text":"If you ","translated":"如果您 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:52Z"} -{"cache_key":"07e0c1ac79c7958e1152f210f5fa32881aab6766711be06e94d0a324e62f4ea3","segment_id":"environment.md:e234227b0e001687","source_path":"environment.md","text_hash":"e234227b0e001687821541fac3af38fc6be293ec6e13910c6826b9afc8ca33be","text":" syntax:","translated":" 语法:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:22:34Z"} -{"cache_key":"083df0fcf5941871ec509cf41a264e951eb0dea21cf3572cde4180a766ac43c8","segment_id":"index.md:3c064c83b8d244fe","source_path":"index.md","text_hash":"3c064c83b8d244fef61e5fd8ce5f070b857a3578a71745e61eea02892788c020","text":" — Anthropic (Claude Pro/Max) + OpenAI (ChatGPT/Codex) via OAuth","translated":" — Anthropic(Claude Pro/Max)+ OpenAI(ChatGPT/Codex)通过 OAuth","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:54Z"} -{"cache_key":"086e200198761d02e2a28bec15b1df356262d9643c0fa8baded9caedae854526","segment_id":"environment.md:46ab081177a452aa","source_path":"environment.md","text_hash":"46ab081177a452aa62354b581730f4675cb03e58cde8282071da30cabe18fb2e","text":"Optional login-shell import","translated":"可选的登录 shell 导入","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:11Z"} -{"cache_key":"086eabdd4e052418c6234dccf807220465b0eaaef349b91be635a3128a71857a","segment_id":"index.md:9182ff69cf35cb47","source_path":"index.md","text_hash":"9182ff69cf35cb477c02452600d23b52a49db7bd7c9833a9a8bc1dcd90c25812","text":"Node ≥ 22","translated":"Node ≥ 22","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:10Z"} -{"cache_key":"08a071c1e71388ad18ffca39565a37edb304794146d2f7ea1e2bac93493f89d6","segment_id":"start/wizard.md:903ea1cf1f2831b3","source_path":"start/wizard.md","text_hash":"903ea1cf1f2831b3e836aff6e23c7d261a83381614361e65df16ade48e84b26c","text":" (API keys + OAuth).","translated":" (API 密钥 + OAuth)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:34Z"} -{"cache_key":"08b4ff7a8e04409d740ca4090c8d83bc3b05d7084bce4b83fa4c91b930eb7161","segment_id":"environment.md:62d66b8c36a6c9aa","source_path":"environment.md","text_hash":"62d66b8c36a6c9aa7134c8f9fe5912435cb0b3bfce3172712646a187954e7040","text":"See [Configuration: Env var substitution](/gateway/configuration#env-var-substitution-in-config) for full details.","translated":"详见 [配置:环境变量替换](/gateway/configuration#env-var-substitution-in-config)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:11:58Z"} -{"cache_key":"08f97e3d7baa10a515db441b79273f697f85c83da040cdf821f9e725243112f2","segment_id":"environment.md:f6b2ffe1d0d5f521","source_path":"environment.md","text_hash":"f6b2ffe1d0d5f521b76cabc67d6e96da2b1170eef8086d530558e9906a7f092d","text":"Models overview","translated":"模型概览","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:17:17Z"} -{"cache_key":"090f33f5db1fde14d7fc04aaa9febae674e9e6ed0d04ce8f1813dac53ccae3a2","segment_id":"start/wizard.md:ab4386608f0ebc6e","source_path":"start/wizard.md","text_hash":"ab4386608f0ebc6e151eab042c6de71d09863aab6dcb2551665e34210e4a4439","text":"What you’ll set:","translated":"您需要设置的内容:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:46:15Z"} -{"cache_key":"09824fcf1352f54ff162268163b8670ead0660d4e0a45d1f236b5b3ef938a56b","segment_id":"index.md:86e2bbbc305c31aa","source_path":"index.md","text_hash":"86e2bbbc305c31aa988751196a1e207da68801a48798c48b90485c11578443a0","text":"Providers and UX:","translated":"提供商 和用户体验:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:04:39Z"} -{"cache_key":"0a2b53b4943a0ba87fb991fef20f822df6c2fd0584f88d394de35b081daac564","segment_id":"environment.md:668e5590b5bb9990","source_path":"environment.md","text_hash":"668e5590b5bb9990eeb25bf657f7d17281a4c613ee4442036787cd4b2efd22bb","text":"If the config file is missing entirely, step 4 is skipped; shell import still runs if enabled.","translated":"如果配置文件完全缺失,则跳过第 4 步;如果已启用,shell 导入仍会运行。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:00Z"} -{"cache_key":"0a3f3c5b73fe0ebee73b07c3c4f4067a75ecf6a9ff30b8b77bf67227b125fee2","segment_id":"index.md:042c75df73389c8a","source_path":"index.md","text_hash":"042c75df73389c8a7c0871d2a451bd20431d24e908e2c192827a54022df95005","text":"Nacho Iacovino","translated":"Nacho Iacovino","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:50Z"} -{"cache_key":"0a4eb623efd2d7af50da4f933f490fa1b7addfe2619ab721d9fcd4f2a2302e6a","segment_id":"help/index.md:b79cac926e0b2e34","source_path":"help/index.md","text_hash":"b79cac926e0b2e347e72cc91d5174037c9e17ae7733fd7bdb570f71b10cd7bfc","text":"Help","translated":"帮助","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:44:29Z"} -{"cache_key":"0a4eb82ad59541cc64eceae3ce7e41ee4739d9a7c742146611fa96b11bdd272d","segment_id":"environment.md:frontmatter:read_when:2","source_path":"environment.md:frontmatter:read_when:2","text_hash":"822b3d74ce16c1be19059fad4ca5bf7ae9327f58fa1ff4e75e78d5afa75c038f","text":"You are documenting provider auth or deployment environments","translated":"你正在编写提供商认证或部署环境的文档","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:21:53Z"} -{"cache_key":"0a7b709303c429dd14ac8df8ef88c398cdf45a678f7beeacf08413bd16d2fc3d","segment_id":"index.md:e9f63c8876aec738","source_path":"index.md","text_hash":"e9f63c8876aec7381ffb5a68efb39f50525f9fc4e732857488561516d47f5654","text":" — Uses Baileys for WhatsApp Web protocol","translated":" — 使用 Baileys 实现 WhatsApp Web 协议","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:52Z"} -{"cache_key":"0aa65de003f8c68c46bc14dc4d66d04efaf025ddd6a1a3cdec1b51ecbe3ecc8a","segment_id":"start/getting-started.md:317f690133d02b19","source_path":"start/getting-started.md","text_hash":"317f690133d02b1969bfcbf6d76a7c0e6efa2b0839e8510227135359a535a5c0","text":"In a new terminal, send a test message:","translated":"在新终端中,发送一条测试消息:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:59Z"} -{"cache_key":"0aaaa653a1bad3c2f1d6bbf34819ea4ae8700ea5d6c593937aa6812051809168","segment_id":"environment.md:453c14128fbfb5f6","source_path":"environment.md","text_hash":"453c14128fbfb5f6757511557132a1dbb3bcbf243267630bfec49db8518c7780","text":"Env var substitution in config","translated":"配置中的 环境变量 替换","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:16Z"} -{"cache_key":"0b149311bd258e33ab5e06f16483d6b14bfb23bbf8137339bc4cf8d29e2d3d5c","segment_id":"environment.md:453c14128fbfb5f6","source_path":"environment.md","text_hash":"453c14128fbfb5f6757511557132a1dbb3bcbf243267630bfec49db8518c7780","text":"Env var substitution in config","translated":"配置中的环境变量替换","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:11:54Z"} -{"cache_key":"0b68a76b412628864a90e4b194a0db6bcc593e8700ee9228d04b45427a95c7af","segment_id":"environment.md:cf3f9ba035da9f09","source_path":"environment.md","text_hash":"cf3f9ba035da9f09202ba669adca3109148811ef31d484cc2efa1ff50a1621b1","text":" (what the Gateway process already has from the parent shell/daemon).","translated":" (Gateway 进程从父 shell/守护进程继承的已有环境变量)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:23Z"} -{"cache_key":"0bab5344d37eb10f7f0a1105ba4cf723e069867a7f745d016657752c1dc0c21a","segment_id":"environment.md:5105555b1be5f84b","source_path":"environment.md","text_hash":"5105555b1be5f84b47576d6ea432675cef742e63fa52f7b254ef2aa4c90e7cca","text":" (applied only if","translated":" (仅在","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:04Z"} -{"cache_key":"0bbc0779389fa7b103e39fff721c2df8f37e36a72350175e61b8334f79dd6555","segment_id":"index.md:0b7e778664921066","source_path":"index.md","text_hash":"0b7e77866492106632e98e7718a8e1e89e8cb0ee3f44c1572dfd9e54845023de","text":"/concepts/streaming","translated":"/concepts/streaming","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:06Z"} -{"cache_key":"0bda3d8fa9978471f16800fbab17622f054477505f8a680d6165e924184818eb","segment_id":"index.md:3fc5f55ea5862824","source_path":"index.md","text_hash":"3fc5f55ea5862824fc266d26cd39fb5da22cc56670c11905d5743adac10bc9ef","text":"Mattermost Bot (plugin)","translated":"Mattermost 机器人(插件)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:46Z"} -{"cache_key":"0bfc8cf7aac6d36a53bc389ddf8a828f323fa60964b005f84cb8aa00f8ab38e9","segment_id":"environment.md:aac7246f5e97142c","source_path":"environment.md","text_hash":"aac7246f5e97142c3f257b7d8b84976f10c29e1b89804bb9d3eb7c43cc03cb8e","text":"Environment variables","translated":"环境变量","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:19Z"} -{"cache_key":"0c1c52efad88743449d31ff51deb8a6275b8c13b9ceea60011208ad696fc3e8e","segment_id":"environment.md:61115f6649792387","source_path":"environment.md","text_hash":"61115f664979238731a390e84433a818965b7eaf1d38fa5b4b1507c33ef28c91","text":"Precedence (highest → lowest)","translated":"优先级(从高到低)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:57Z"} -{"cache_key":"0c828040f85df6effef7a39f7d06d9158493bcfd8c0981f5d6d2c5002f06181e","segment_id":"index.md:3c8aa7ad1cfe03c1","source_path":"index.md","text_hash":"3c8aa7ad1cfe03c1cb68d48f0c155903ca49f14c9b5626059d279bffc98a8f4e","text":": connect to the Gateway WebSocket (LAN/tailnet/SSH as needed); legacy TCP bridge is deprecated/removed.","translated":":通过 WebSocket 连接到 Gateway(根据需要使用局域网/Tailnet/SSH);旧版 TCP 桥接已弃用/移除。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:04Z"} -{"cache_key":"0cbb0b48efe1edd1ee9cf73b486ba3c4ecd0b316ed8355432c734a6ae2ff9828","segment_id":"index.md:a42f01be614f75f1","source_path":"index.md","text_hash":"a42f01be614f75f16278b390094dc43923f0b1b7d8e3209b3f43e356f42ed982","text":"), a single long-running process that owns channel connections and the WebSocket control plane.","translated":"进行,它是一个长期运行的单进程,负责管理渠道连接和 WebSocket 控制面。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:37Z"} -{"cache_key":"0cbb380393c622f57aedb33e0d64521926af5db0134afe3dbd8a1b24aaa3eac1","segment_id":"help/index.md:8ddb7fc8a87904de","source_path":"help/index.md","text_hash":"8ddb7fc8a87904dedc2afc16400fbe4e78582b302e01c30b1319c8a465d04684","text":"Troubleshooting:","translated":"故障排除:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:24:36Z"} -{"cache_key":"0cc5aed5ba117c3d267480c23a673d693068648c5bfffaacfdc33f4650533f2a","segment_id":"index.md:10bf8b343a32f7dc","source_path":"index.md","text_hash":"10bf8b343a32f7dc01276fc8ae5cf8082e1b39c61c12d0de8ec9b596e115c981","text":"WebChat","translated":"网页聊天","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:32Z"} -{"cache_key":"0d1e17e509bbc4aa27b446bec9af66b9246950ea0dfb619dd35f21534c317143","segment_id":"index.md:b5ccaf9b1449291c","source_path":"index.md","text_hash":"b5ccaf9b1449291c92f855b8318aeb2880a9aa1a75272d17f55cf646071b3eae","text":"Gmail hooks (Pub/Sub)","translated":"Gmail 钩子(Pub/Sub)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:09Z"} -{"cache_key":"0dad422eb096806e226c53202949206185916bda859e38301da854b681b25963","segment_id":"environment.md:frontmatter:read_when:1","source_path":"environment.md:frontmatter:read_when:1","text_hash":"a3a2d99a99de98220c8e0296d6f4e4b2a34024916bd2379d1b3b9179c8fae46f","text":"You are debugging missing API keys in the Gateway","translated":"你正在调试 Gateway 中缺失的 API 密钥","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:10Z"} -{"cache_key":"0dae07beb7b056f37a0ca939d95614b19e7c66b60741530d3b8697cc4a7bdbb7","segment_id":"index.md:bbf8779fd9010043","source_path":"index.md","text_hash":"bbf8779fd9010043ac23a2f89ba34901f3a1f58296539c3177d51a9040ea209d","text":") — Blogwatcher skill","translated":")— Blogwatcher 技能","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:53Z"} -{"cache_key":"0df8549623b0d7f6737342296a4696b34206e074d5a552cb6f37d6c439e85b79","segment_id":"environment.md:f15f5f9f4ef4d668","source_path":"environment.md","text_hash":"f15f5f9f4ef4d6688876c894f8eba251ed1db6eaf2209084028d43c9e76a8ba1","text":" (aka ","translated":" (即 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:41Z"} -{"cache_key":"0e01c4c62bbe121aee9533c17fd055ee1538caf46007bb0938ee7d361ae5d52b","segment_id":"environment.md:45ca56d179d4788c","source_path":"environment.md","text_hash":"45ca56d179d4788c55ba9f7653b376d62e7faa738e92259e3d4f6f5c1b554f28","text":"Related","translated":"相关内容","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:41:37Z"} -{"cache_key":"0e375d889ea9a49f6c0e03a2e49ea5a681ffd031303237117f0dfdf54fb917e8","segment_id":"start/wizard.md:abf42990b17ccc52","source_path":"start/wizard.md","text_hash":"abf42990b17ccc52870da0c8026ddafa221bc57d87d755a64d74fcd408395435","text":"Full reset (also removes workspace)","translated":"完全重置(同时移除工作区)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:43Z"} -{"cache_key":"0ed1d8cb8838fead312d097caca4f56b5c69e0486833919892e2fc368b933b15","segment_id":"help/index.md:6201111b83a0cb5b","source_path":"help/index.md","text_hash":"6201111b83a0cb5b0922cb37cc442b9a40e24e3b1ce100a4bb204f4c63fd2ac0","text":" and ","translated":" 和 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:30Z"} -{"cache_key":"0ef13ceaf849a114db93b4137cdc043c8ba6ba5d2b1cf2ddea7779850d137e5c","segment_id":"index.md:81023dcc765309dd","source_path":"index.md","text_hash":"81023dcc765309dd05af7638f927fd7faa070c58abe7cad33c378aa02db9baa2","text":" (token is required for non-loopback binds).","translated":" (非回环绑定时必须提供令牌)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:55Z"} -{"cache_key":"0ef99bf8be4557b02f6fc6a43848b16ec9656f205332bd687cbcc0c8b8fce99d","segment_id":"start/getting-started.md:c4b2896a2081395e","source_path":"start/getting-started.md","text_hash":"c4b2896a2081395e282313d6683f07c81e3339ef8b9d2b5a299ea5b626a0998f","text":").","translated":")。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:57Z"} -{"cache_key":"0f0645e14c15177b60a1a2e14a18e220e0ad397f483ad8a0cad68ea3d5a3bc44","segment_id":"start/wizard.md:4a85827ad80e8635","source_path":"start/wizard.md","text_hash":"4a85827ad80e8635fb4a2b41a3fce1d0f23ba1eb27db0aa84113a7b0ca415d42","text":"Synthetic","translated":"Synthetic","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:05Z"} -{"cache_key":"0f51ea5ec00d63f74853135fc04c205c09a3b3fd519a80fb8a83bf504ed6d041","segment_id":"index.md:032f5589cfa2b449","source_path":"index.md","text_hash":"032f5589cfa2b44973fe96c42e17dcc2692281413a05b16f48ff0f958f7f7ade","text":"Discord Bot","translated":"Discord 机器人","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:41Z"} -{"cache_key":"0f5a75040351402afe8493774c6b74576b064ee93723b03a03a345c5e6dcb986","segment_id":"environment.md:b4736422e64c0a36","source_path":"environment.md","text_hash":"b4736422e64c0a369663d1b2d386f1b8f4b31b8936b588e4a54453c61a24e0fd","text":"Process environment","translated":"进程环境","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:03Z"} -{"cache_key":"0f5fbe9d6968fcf81b97b0938d0191012b2512171268e21a0252476981018364","segment_id":"index.md:fdef9f917ee2f72f","source_path":"index.md","text_hash":"fdef9f917ee2f72fbd5c08b709272d28a2ae7ad8787c7d3b973063f0ebeeff7a","text":" to update the gateway service entrypoint.","translated":" 以更新 Gateway 服务入口点。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:15Z"} -{"cache_key":"0fc566f2207136599a99330b18f7b5a871db5129d3b99079d06a612b73acf825","segment_id":"index.md:268ebcd6be28e8d8","source_path":"index.md","text_hash":"268ebcd6be28e8d853ace3a6e28f269fbda1343b53e3f0de97ea3d5bf1a0e33e","text":"Clawd","translated":"Clawd","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:42Z"} -{"cache_key":"0fe42f35cd75dae1544040ac532880db182effb28cb15f90f3e180965d450f3c","segment_id":"start/wizard.md:ba5ec51d07a4ac0e","source_path":"start/wizard.md","text_hash":"ba5ec51d07a4ac0e951608704431d59a02b21a4e951acc10505a8dc407c501ee","text":")","translated":")","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:46:20Z"} -{"cache_key":"10424bff17e00e154be3be8a5c6595baabbbdbf533eb28142124ba7d3fe2f265","segment_id":"environment.md:582967534d0f909d","source_path":"environment.md","text_hash":"582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf","text":" in ","translated":" 在 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:45Z"} -{"cache_key":"105a552d339b5cc747f8939f6c1b54d6f7d6c411a850f38980a0fb1be67195e0","segment_id":"index.md:95cae5ed127bd44d","source_path":"index.md","text_hash":"95cae5ed127bd44dcc30345a1925d77f333284b43a6f97832f149a63dc38e0e0","text":"The wizard now generates a gateway token by default (even for loopback).","translated":"向导现在默认会生成一个 Gateway 令牌(即使在回环模式下也是如此)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:52Z"} -{"cache_key":"10920f79a810b1b47492e9ed0d361ef42a495b2f73a494ec40eb09e75c35bb96","segment_id":"index.md:95cae5ed127bd44d","source_path":"index.md","text_hash":"95cae5ed127bd44dcc30345a1925d77f333284b43a6f97832f149a63dc38e0e0","text":"The wizard now generates a gateway token by default (even for loopback).","translated":"向导 现在默认会生成一个网关令牌(即使是回环连接也是如此)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:43Z"} -{"cache_key":"10a05f1dce0af95edaca2aefc99dda7d1315b6b1d57e2b3021652fe20af68eb7","segment_id":"index.md:cf9f12b2c24ada73","source_path":"index.md","text_hash":"cf9f12b2c24ada73bb0474c0251333f65e6d5d50e56e605bdb264ff32ad0a588","text":"Config lives at ","translated":"配置文件位于 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:29Z"} -{"cache_key":"10a57e9dff1afe6e19b169eebc46fb2bc623dc74996f695c059c259a5d01b11f","segment_id":"environment.md:e234227b0e001687","source_path":"environment.md","text_hash":"e234227b0e001687821541fac3af38fc6be293ec6e13910c6826b9afc8ca33be","text":" syntax:","translated":" 语法:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:26:26Z"} -{"cache_key":"10ad8d1314a510acc92dd184df9be180aea8c032323637e317be12bff654aefa","segment_id":"start/wizard.md:7398946ba352a7c8","source_path":"start/wizard.md","text_hash":"7398946ba352a7c8b21e60b2474d1ba7190707d9a04a6904103217e177f67482","text":"Summary + next steps, including iOS/Android/macOS apps for extra features.","translated":"摘要 + 后续步骤,包括 iOS/Android/macOS 应用以获取额外功能。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:46:01Z"} -{"cache_key":"111e143c2961901491d16f639ad9d9bf0203700f41ad61862f0c0e09548d85ca","segment_id":"index.md:42bb365211decccb","source_path":"index.md","text_hash":"42bb365211decccb3509f3bf8c4dfcb5ae05fe36dfdedb000cbf44e59e420dc9","text":" — Local imsg CLI integration (macOS)","translated":" — 本地 imsg CLI 集成(macOS)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:53Z"} -{"cache_key":"11951539669d912b24dac16f9ed27e1de0a950a3baa481474a65de0ca85fbe7b","segment_id":"start/wizard.md:ec2d0a7d20f3b660","source_path":"start/wizard.md","text_hash":"ec2d0a7d20f3b6602a6593e0abef2337e84ba728ca8f6fef2534dc1e9dbfe06b","text":"Remote mode configures a local client to connect to a Gateway elsewhere.","translated":"远程模式配置本地客户端以连接到其他位置的 Gateway。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:46:13Z"} -{"cache_key":"11a42ddb57b9c1ba4022984efe25b463da52e7b9c5d7ec3a925d7a6d0e5a6c39","segment_id":"index.md:cdb4ee2aea69cc6a","source_path":"index.md","text_hash":"cdb4ee2aea69cc6a83331bbe96dc2caa9a299d21329efb0336fc02a82e1839a8","text":".","translated":".","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:19Z"} -{"cache_key":"11a6809809867ab84f2a66da213f7894876530602a0743b37fc93e614c7ccbfe","segment_id":"help/index.md:71095a6d42f5d9c2","source_path":"help/index.md","text_hash":"71095a6d42f5d9c2464a8e3f231fc53636d4ce0f9356b645d245874162ec07e2","text":"Gateway troubleshooting","translated":"Gateway 故障排除","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:39:44Z"} -{"cache_key":"1226fe0b47712f49a01581113142855bc5ae36e3289353b5d592ece5191b0159","segment_id":"start/wizard.md:c90e6f2be18d7e02","source_path":"start/wizard.md","text_hash":"c90e6f2be18d7e02413e18d4174fe7d855c9753005652614556204123b37c96e","text":": browser flow; paste the ","translated":":浏览器流程;粘贴 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:18Z"} -{"cache_key":"1249a5c279b0761418bca0826571d62b0526075a0c91018c35002331e3c6d6b5","segment_id":"environment.md:aac7246f5e97142c","source_path":"environment.md","text_hash":"aac7246f5e97142c3f257b7d8b84976f10c29e1b89804bb9d3eb7c43cc03cb8e","text":"Environment variables","translated":"环境变量","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:14Z"} -{"cache_key":"124e4ad52161941e1842f43e4f5d0c12d573babaf3f319ec7d5db46ba8ee7e84","segment_id":"index.md:0b60fe04b3c5c3c7","source_path":"index.md","text_hash":"0b60fe04b3c5c3c76371b6eca8b19c8e09a0e54c9010711ff87e782d87d2190b","text":"Android app","translated":"Android 应用","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:57Z"} -{"cache_key":"135f65a9b168054bcbe82dd61f4309c2dda482ef1e442ec7eec710c8f597b97c","segment_id":"start/getting-started.md:d2da561767068503","source_path":"start/getting-started.md","text_hash":"d2da56176706850367dee94ffc2a1daf962c84f7a9cbf61aa379ddc33bcbaf95","text":"If you want the deeper reference pages, jump to: ","translated":"如果您需要更详细的参考页面,请跳转至: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:05Z"} -{"cache_key":"1370cc167f786bd13af7db472a718a3029e35e284c8a6878d5d0945490b59eec","segment_id":"start/getting-started.md:66354a1d3225edbf","source_path":"start/getting-started.md","text_hash":"66354a1d3225edbf01146504d06aaea1242dcf50424054c3001fc6fa2ddece0f","text":"Remote access","translated":"远程访问","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:31Z"} -{"cache_key":"13e78cfc5d44bb03f1de8ea274175eb17591ea86da3a5b78f04e97df1a74ff65","segment_id":"index.md:329f3c913c0a1636","source_path":"index.md","text_hash":"329f3c913c0a16363949eb8ee7eb0cda7e81137a3851108019f33e5d18b57d8f","text":"Switching between npm and git installs later is easy: install the other flavor and run ","translated":"之后在 npm 安装和 git 安装之间切换很简单:安装另一种方式并运行 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:13Z"} -{"cache_key":"147fcf3acfee0fe1de6932eed18455765effec1024bb00db4f6a2dd367cd9c23","segment_id":"index.md:1016b5bdce94a848","source_path":"index.md","text_hash":"1016b5bdce94a8484312c123416c1a18c29fab915ba2512155df3a82ee097f8f","text":"If the Gateway is running on the same computer, that link opens the browser Control UI\nimmediately. If it fails, start the Gateway first: ","translated":"如果 Gateway 运行在同一台计算机上,该链接会立即打开浏览器控制界面。如果打开失败,请先启动 Gateway: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:25Z"} -{"cache_key":"1490f7c2fc1c4e0b651ef5d269a8acd623cb90b51d6b9814688a95ee8fed4772","segment_id":"index.md:9bd86b0bbc71de88","source_path":"index.md","text_hash":"9bd86b0bbc71de88337aa8ca00f0365c1333c43613b77aaa46394c431cb9afd8","text":"Maxim Vovshin","translated":"Maxim Vovshin","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:06:14Z"} -{"cache_key":"14f523713d1f9204bc80126a5fa7111149e72734cc1c958f6faf344ea347304b","segment_id":"index.md:c6e91f3b51641b1c","source_path":"index.md","text_hash":"c6e91f3b51641b1c43d297281ee782b40d9b3a0bdd7afc144ba86ba329d5f95f","text":"OpenClaw = CLAW + TARDIS","translated":"OpenClaw = CLAW + TARDIS","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:05:38Z"} -{"cache_key":"152ce96ff0d29caf9f3ce55d6a7aca272b4e335f580058a7790cc56b2470233c","segment_id":"index.md:a7a19d4f14d001a5","source_path":"index.md","text_hash":"a7a19d4f14d001a56c27f68a13ff267859a407c7a9ab457c0945693c9067dd1c","text":"Configuration (optional)","translated":"配置(可选)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:48Z"} -{"cache_key":"15ffd6a61896c7467d982847033889cbf92f11c42fa93b5f9a46b754780c41e4","segment_id":"start/wizard.md:c18a76f788d27ead","source_path":"start/wizard.md","text_hash":"c18a76f788d27eade089c5e57a4d8d0e64b0e69278ff24b71eb267d915d23646","text":"Model/auth (OpenAI Code (Codex) subscription OAuth, Anthropic API key (recommended) or setup-token (paste), plus MiniMax/GLM/Moonshot/AI Gateway options)","translated":"模型/认证(OpenAI Code (Codex) 订阅 OAuth、Anthropic API 密钥(推荐)或 setup-token(粘贴),以及 MiniMax/GLM/Moonshot/AI Gateway 选项)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:18Z"} -{"cache_key":"1609cb1df4c75a8648918d074322a56d17486584efc5dece6e10c3cbd4e37b7e","segment_id":"environment.md:d4a67341570f4656","source_path":"environment.md","text_hash":"d4a67341570f4656784c5f8fe1bfb48a738ace57b52544977431d50e2b718099","text":"FAQ: env vars and .env loading","translated":"常见问题:环境变量和 `.env` 加载","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:17:14Z"} -{"cache_key":"161305a0fe253398ae3cff640449ed26bc7a2f3c52cb3ae71ea8d861cbcce0a0","segment_id":"start/wizard.md:bb1460932d15b59c","source_path":"start/wizard.md","text_hash":"bb1460932d15b59cba3f47b5c93a8d1768a6ba842cd4aa3eba8d2e2540fc0f19","text":"Channel allowlists (Slack/Discord/Matrix/Microsoft Teams) when you opt in during the prompts (names resolve to IDs when possible).","translated":"渠道允许名单(Slack/Discord/Matrix/Microsoft Teams),在提示期间选择启用时生效(名称会尽可能解析为 ID)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:48:42Z"} -{"cache_key":"163bd5cf4e32a3b93891c0acaa17dcbec319fbab2e097d0d8785997528586f02","segment_id":"index.md:d08cec54f66c140c","source_path":"index.md","text_hash":"d08cec54f66c140c655a1631f6d629927c7c38b9c8bfa91c875df9bd3ad3c559","text":"OpenClaw assistant setup","translated":"OpenClaw 助手设置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:39Z"} -{"cache_key":"1699b5d6dd8bd25127b31c4c1dde1c32c99d4d73e8928d3d4240cc4ca7a90948","segment_id":"index.md:872887e563e75957","source_path":"index.md","text_hash":"872887e563e75957ffc20b021332504f2ddd0a8f3964cb93070863bfaf13cdad","text":"Example:","translated":"示例:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:44Z"} -{"cache_key":"16df9d8c10cc2590ebcc2313fee468c319259a1c038fcf19a9844754a1c6d0cf","segment_id":"index.md:88d90e2eef3374ce","source_path":"index.md","text_hash":"88d90e2eef3374ce1a7b5e7fbd3b1159364b26a8ceb2493d6e546d4444b03cda","text":"Tailscale","translated":"Tailscale","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:28Z"} -{"cache_key":"170ac65dcb50a9c53c485160f6dac256ff7cd0a52f42110be2e831d8b8dfe2d8","segment_id":"index.md:6638cf2301d3109d","source_path":"index.md","text_hash":"6638cf2301d3109da66a44ee3506fbd35b29773fa4ca33ff35eb838c21609e19","text":"Features (high level)","translated":"功能(概览)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:46Z"} -{"cache_key":"177341748b72b186e14110d0c9976e378a203d89a6c13e049a92f3cdc3d750a5","segment_id":"index.md:872887e563e75957","source_path":"index.md","text_hash":"872887e563e75957ffc20b021332504f2ddd0a8f3964cb93070863bfaf13cdad","text":"Example:","translated":"示例:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:03:39Z"} -{"cache_key":"17bdf88db004d77259d1facc1c15dbb8745e59196159394aa7b079e5791cb188","segment_id":"index.md:cda454f61dfcac70","source_path":"index.md","text_hash":"cda454f61dfcac7007a9edc538f9f58cf38caa0652e253975979308162bccc53","text":"Gateway configuration","translated":"Gateway 配置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:15Z"} -{"cache_key":"17e73f0432c41ef1e25bcb39e40a7fb845787238a577b53ddf27793a5397ec20","segment_id":"start/getting-started.md:185d41cd3982a2b1","source_path":"start/getting-started.md","text_hash":"185d41cd3982a2b1d9355a331c5270ca3bf6e8467b35dea265d2e3a279d05dea","text":" to the gateway host.","translated":" 到 Gateway 主机上。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:42Z"} -{"cache_key":"180848ab1dfb40b43095571666d7e635cec82592dd7b0ea3f406819694db95bd","segment_id":"index.md:1df4f2299f0d9cc4","source_path":"index.md","text_hash":"1df4f2299f0d9cc466fa05abeb2831e76e9f89583228174ffcd9af415fd869fe","text":"Send a test message (requires a running Gateway):","translated":"发送测试消息(需要 Gateway 正在运行):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:25Z"} -{"cache_key":"1851994b49e6bccd9901d48dea770f2271a4b0adf71a11555a7d49ea7433ab55","segment_id":"index.md:0d517afa83f91ec3","source_path":"index.md","text_hash":"0d517afa83f91ec33ee74f756c400a43b11ad2824719e518f8ca791659679ef4","text":"Web surfaces (Control UI)","translated":"Web 界面(控制界面)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:04:33Z"} -{"cache_key":"185a0aac0aa7e81682f9016aa8d0e4f95f86005abb5a52840876dc9b23129893","segment_id":"help/index.md:156597e2632411d1","source_path":"help/index.md","text_hash":"156597e2632411d1d5f634db15004072607ba45072a4e17dfa51790a37b6781f","text":"Gateway issues:","translated":"Gateway 问题:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:56:26Z"} -{"cache_key":"18869b3a6b51f154fdcbb622d54f07c567e9438608cf998f54e590550797ed35","segment_id":"index.md:9f4d843a5d04e23b","source_path":"index.md","text_hash":"9f4d843a5d04e23b22eb79b3bfa0fbad70ede435ddb5d047e7d77e830efa6019","text":" — Bot token + WebSocket events","translated":" — Bot 令牌 + WebSocket 事件","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:13Z"} -{"cache_key":"18bd8d592ca11411d1c02c1a70123dc798352f581db4c9ce297c5ebb04841fa3","segment_id":"index.md:03279877bfe1de07","source_path":"index.md","text_hash":"03279877bfe1de0766393b51e69853dec7e95c287ef887d65d91c8bbe84ff9ff","text":"WebChat + macOS app","translated":"网页聊天 + macOS 应用","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:02:30Z"} -{"cache_key":"190c49164ee5535fac803e9c0f057588d634e056d2c4fc072a0ca26e01ddc391","segment_id":"index.md:7d8b3819c6a9fb72","source_path":"index.md","text_hash":"7d8b3819c6a9fb726f40c191f606079b473f6f72d4080c13bf3b99063a736187","text":"Ops and safety:","translated":"运维和安全:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:05:19Z"} -{"cache_key":"19207e4ed0ae44f965f33707377a0217c1765cf57b09c0268ee36c10fb108dd9","segment_id":"index.md:c6e91f3b51641b1c","source_path":"index.md","text_hash":"c6e91f3b51641b1c43d297281ee782b40d9b3a0bdd7afc144ba86ba329d5f95f","text":"OpenClaw = CLAW + TARDIS","translated":"OpenClaw = CLAW + TARDIS","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:18Z"} -{"cache_key":"194e63ecfe45556973c28ccafc39f814f42d2478037734ce44eee72f6fc6fc66","segment_id":"index.md:856302569e24c4d6","source_path":"index.md","text_hash":"856302569e24c4d64997e2ec5c37729f852bcccf333ba1e2f71e189c9d172e6d","text":": SSH tunnel or tailnet/VPN; see ","translated":":SSH 隧道或 Tailnet/VPN;请参阅 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:21Z"} -{"cache_key":"196942db05e9e40cbdf74a89cdd1be042430343a64ac2185009414f0d092af66","segment_id":"environment.md:cda454f61dfcac70","source_path":"environment.md","text_hash":"cda454f61dfcac7007a9edc538f9f58cf38caa0652e253975979308162bccc53","text":"Gateway configuration","translated":"Gateway 配置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:13:11Z"} -{"cache_key":"19c0ced45bb35a1d8801864910a9f7bc2c460229fdd97366f546255feeb1db0e","segment_id":"index.md:8816c52bc5877a2b","source_path":"index.md","text_hash":"8816c52bc5877a2b24e3a2f4ae7313d29cf4eba0ca568a36f2d00616cfe721d0","text":"Wizard","translated":"向导","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:12Z"} -{"cache_key":"19ca5db3b9a34663414fc437ede7163609ae09cf0a0873367e8a83c8c8dc9c1c","segment_id":"index.md:e64d6b29b9d90bba","source_path":"index.md","text_hash":"e64d6b29b9d90bba92ffe2539dc295a75c553684fed0350ee56bfd0aead01662","text":"Multiple gateways","translated":"多 Gateway 部署","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:45Z"} -{"cache_key":"19d8897086c397efdc874615a9503b47cb856584fc885631b1dac100e0bbf69e","segment_id":"start/wizard.md:c3f0c8edf2a35cb6","source_path":"start/wizard.md","text_hash":"c3f0c8edf2a35cb67c00b0fe92273695465fb1a1faa99a54b08a42c116cfc532","text":"Typical fields in ","translated":"中的典型字段 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:48:26Z"} -{"cache_key":"1ace42dd9735ec65580e321be5ec1b6956327ceb79da49867d3031743de01599","segment_id":"index.md:7ac362063b9f2046","source_path":"index.md","text_hash":"7ac362063b9f204602f38f9f1ec9cf047f03e0d7b83896571c9df6d31ad41e9c","text":"Nodes","translated":"节点","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:50Z"} -{"cache_key":"1add3ec58637e35e15f8ecce92a3064278889ebc567d4b15e12d7f73d43f829d","segment_id":"environment.md:cea23dd4b87e8b00","source_path":"environment.md","text_hash":"cea23dd4b87e8b00d19fb9ccaaef93e97353c7353e2070f3baf05aeb3995dff4","text":" expected","translated":" 预期","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:44Z"} -{"cache_key":"1aefff77e0f0e3d5d9204ec8bba8bc39215a10dc4242638faf2a000db1b7f6c4","segment_id":"index.md:032f5589cfa2b449","source_path":"index.md","text_hash":"032f5589cfa2b44973fe96c42e17dcc2692281413a05b16f48ff0f958f7f7ade","text":"Discord Bot","translated":"Discord 机器人","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:40Z"} -{"cache_key":"1b03b1a606f8d851e3a9744ceedc51773da3a8df1e44cea04e77f4cdcc482f4f","segment_id":"help/index.md:b79cac926e0b2e34","source_path":"help/index.md","text_hash":"b79cac926e0b2e347e72cc91d5174037c9e17ae7733fd7bdb570f71b10cd7bfc","text":"Help","translated":"帮助","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:07Z"} -{"cache_key":"1b0d0b676f8ad6e3cca80b5ba0962cfca425d38aba4dfdae950f4c645cc4648c","segment_id":"environment.md:c2d7247c8acb83a5","source_path":"environment.md","text_hash":"c2d7247c8acb83a5a020458fa836c2445922b51513dbdbf154ab5f7656cb04e9","text":"; does not override).","translated":";不会覆盖)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:46Z"} -{"cache_key":"1b30ed7712ade7f794a6fdc40334ac098d59fa26a77cb4dbee831ba2078a2575","segment_id":"environment.md:ab5aec4424cf678d","source_path":"environment.md","text_hash":"ab5aec4424cf678dcfb1ad3d2c2929c1e0b2b1ff61b82b961ada48ad033367b4","text":" (dotenv default; does not override).","translated":" (dotenv 默认行为;不会覆盖)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:34Z"} -{"cache_key":"1b46380759682daee5913f29666ad424b3e1b23a87ee5b8169484b9c4e4cce3f","segment_id":"index.md:7af023c43013b9a5","source_path":"index.md","text_hash":"7af023c43013b9a53fbff7dd4b5821588bba3319308878229740489152c43f6d","text":"Docs","translated":"文档","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:10Z"} -{"cache_key":"1b9c39af551716b27cb347a69279ef46cfe3c1fb503688b09287759b10390831","segment_id":"start/wizard.md:e86be3a8fc32914b","source_path":"start/wizard.md","text_hash":"e86be3a8fc32914baac6ea18f1b36fb282ea9648829cec3bba6434bdc6d78b9c","text":" before continuing.","translated":" 后再继续。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:22Z"} -{"cache_key":"1c12007db13e2183cd1fe644bbe1a01094186d612f9d4c719986819020e971df","segment_id":"start/getting-started.md:e2235b75234648f0","source_path":"start/getting-started.md","text_hash":"e2235b75234648f0959f35fae53aa627c01be06907b8596d69b01ae9187e1574","text":"Sandboxing note: ","translated":"沙箱注意事项: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:15Z"} -{"cache_key":"1c4b67e17a4caf039722cea2dd696a8a7cdef2168d6518aaf603d3aeb69b9366","segment_id":"index.md:e47cdb55779aa06a","source_path":"index.md","text_hash":"e47cdb55779aa06a74ae994c998061bd9b7327f5f171c141caf2cf9f626bfe4b","text":"Peter Steinberger","translated":"Peter Steinberger","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:17Z"} -{"cache_key":"1c540694a0b8ce10fc354bd7f41b387f1d72d1759ffecbf35976cdf744305f0e","segment_id":"index.md:cec2be6f871d276b","source_path":"index.md","text_hash":"cec2be6f871d276b45d13e3010c788f01b03ae2f1caca3264bbf759afacace46","text":"Telegram Bot","translated":"Telegram 机器人","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:34Z"} -{"cache_key":"1c7aa162de30cece8f7d315f71cdc949464409fa4af6d15a34fe9e1355c65a07","segment_id":"index.md:0b60fe04b3c5c3c7","source_path":"index.md","text_hash":"0b60fe04b3c5c3c76371b6eca8b19c8e09a0e54c9010711ff87e782d87d2190b","text":"Android app","translated":"Android 应用","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:05:11Z"} -{"cache_key":"1c913763f7d014418cc6c1099fe8225a377347cffba038df43b8b36ddefb8667","segment_id":"start/wizard.md:053bc65874ad6098","source_path":"start/wizard.md","text_hash":"053bc65874ad6098e58c41c57b378a2f36b0220e5e0b46722245e6c2f796818c","text":"Discord","translated":"Discord","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:44:32Z"} -{"cache_key":"1cb210590e688dccd03dac9806c6ca974a62f36eb66841174c22bc2a92ba246b","segment_id":"index.md:1016b5bdce94a848","source_path":"index.md","text_hash":"1016b5bdce94a8484312c123416c1a18c29fab915ba2512155df3a82ee097f8f","text":"If the Gateway is running on the same computer, that link opens the browser Control UI\nimmediately. If it fails, start the Gateway first: ","translated":"如果 Gateway 运行在同一台计算机上,该链接会立即打开浏览器控制界面。如果打开失败,请先启动 Gateway: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:00Z"} -{"cache_key":"1d79cadd479cb04568bc708432327edae80a4fd8ef388f88810aa943956e4c47","segment_id":"start/wizard.md:c8fa121316f27858","source_path":"start/wizard.md","text_hash":"c8fa121316f2785846379bef81073a1f3dd68979bd249b3953d671935e11de39","text":" on any machine, then paste the token (you can name it; blank = default).","translated":" 在任意机器上执行,然后粘贴令牌(可以命名;留空 = 默认)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:07Z"} -{"cache_key":"1db946531e000c45cc98cc20862f674ef6c61986d0ea1d47dfb1904d14218107","segment_id":"environment.md:e234227b0e001687","source_path":"environment.md","text_hash":"e234227b0e001687821541fac3af38fc6be293ec6e13910c6826b9afc8ca33be","text":" syntax:","translated":" 语法:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:20Z"} -{"cache_key":"1dec0d82356f133d86b7f5230d326009390aef97750e2e02a9f559c81af566c0","segment_id":"start/wizard.md:da4f7ea58d963b1a","source_path":"start/wizard.md","text_hash":"da4f7ea58d963b1a302b76b8fa5570190106c673b9cf2975468b8caea5e27384","text":"Notes:","translated":"注意事项:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:46:26Z"} -{"cache_key":"1e12a98dc0766a832c97dea693a841b86ec63df3e8303fb054a918e2b17ca0af","segment_id":"index.md:1df4f2299f0d9cc4","source_path":"index.md","text_hash":"1df4f2299f0d9cc466fa05abeb2831e76e9f89583228174ffcd9af415fd869fe","text":"Send a test message (requires a running Gateway):","translated":"发送测试消息(需要正在运行的 Gateway):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:45Z"} -{"cache_key":"1e12f10bc3ce3c2de7f740928fb2eb076893bf23694f69adc314d8496c436182","segment_id":"environment.md:frontmatter:summary","source_path":"environment.md:frontmatter:summary","text_hash":"78351223e7068721146d2de022fdf440c2866b2ee02fbbb50bf64369b999820b","text":"Where OpenClaw loads environment variables and the precedence order","translated":"其中 OpenClaw 加载 环境变量 及优先级顺序","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:10Z"} -{"cache_key":"1e290e5653bf89ffd9643bbb215d3b2ce8f30b26d3468a5b584482ea567fb499","segment_id":"index.md:075a4a45c3999f34","source_path":"index.md","text_hash":"075a4a45c3999f340be8487cd7c0dd2ed77ced931054d75e95e5e24d5539b45b","text":" — Pi (RPC mode) with tool streaming","translated":" — Pi(RPC 模式),支持工具流式传输","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:59Z"} -{"cache_key":"1e95353aafa09b6593d0a72b4957849c4bd481c529d0cd0c2c92a989b3be6314","segment_id":"index.md:cf9f12b2c24ada73","source_path":"index.md","text_hash":"cf9f12b2c24ada73bb0474c0251333f65e6d5d50e56e605bdb264ff32ad0a588","text":"Config lives at ","translated":"配置文件位于 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:50Z"} -{"cache_key":"1ecffd089b9e7ce60ff3c650b35056b17b3818bed3a6b56aad92c8aa31d7ef0a","segment_id":"index.md:723784fa2b6a0876","source_path":"index.md","text_hash":"723784fa2b6a0876540a92223ee1019f24603499d335d6d82afbc520ef5b5d57","text":") — Creator, lobster whisperer","translated":")— 创始人,龙虾低语者","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:05:57Z"} -{"cache_key":"1ee9e09b79b65f176e6502ee06df46982743679fd7dab8489796507a560b9061","segment_id":"start/wizard.md:dd6d876548037ec7","source_path":"start/wizard.md","text_hash":"dd6d876548037ec722252b45795206575e7040eba1ca076cf1732a4a903cadba","text":"recommended","translated":"推荐的","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:01Z"} -{"cache_key":"1f29b910c7c6522a295107b45bd56440780ea346e1080c11e5151d3ba113afca","segment_id":"environment.md:1fe7fd13379f249a","source_path":"environment.md","text_hash":"1fe7fd13379f249a1e554dc904ad7b921693805367609bcddba21f0e7777f4c6","text":" keys:","translated":" 密钥:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:46Z"} -{"cache_key":"1f36183a47c67ccafde914a43347afd754eafbb2963a3d0ad3d3942258443cdf","segment_id":"index.md:d00eca1bae674280","source_path":"index.md","text_hash":"d00eca1bae6742803906ab42a831e8b5396d15b6573ea13c139ec31631208ec1","text":"Getting Started","translated":"快速入门","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:04Z"} -{"cache_key":"1f429111895ed6cef256514a66a9adb27ec53f3d69a546a6a18c80495cacd604","segment_id":"start/getting-started.md:c65465f9a818c020","source_path":"start/getting-started.md","text_hash":"c65465f9a818c02008a391292f0086b37aa7e8fe7355aca80967b20a8b692e0b","text":"Dashboard (local loopback): ","translated":"仪表盘(本地回环): ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:53Z"} -{"cache_key":"1fb0683c4f7488278cb9251e361610c911ef766dd126666b7fc10f6f73a0c8b7","segment_id":"index.md:79a482cf546c23b0","source_path":"index.md","text_hash":"79a482cf546c23b04cd48a33d4ca8411f62e5b7dc8c3a8f30165e28e747f263a","text":"iMessage","translated":"iMessage","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:54Z"} -{"cache_key":"1ff7a3f0c5d86df89523e2dad0861b2ace45830858dd2ca1c4e778747334ffc0","segment_id":"start/wizard.md:ac12572a8df977e5","source_path":"start/wizard.md","text_hash":"ac12572a8df977e5ea70c8b1a24c2a84b1ecd1935e2ef9fe4c38c5849d4755f8","text":" if present.","translated":" (如果存在)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:59Z"} -{"cache_key":"2034fd5a1e8f055e05fbbdfae0533751d7f0d1c2c0f3d2808c9eeb4da918e89a","segment_id":"environment.md:907940a35852447a","source_path":"environment.md","text_hash":"907940a35852447aad5f21c5a180d993ff31cfd5807b1352ed0c24eabe183465","text":"never override existing values","translated":"永远不覆盖已有的值","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:56Z"} -{"cache_key":"204727bc1fb1c07814caf037d6fa475e7981c7b57ed1367943361cb5d56815bb","segment_id":"index.md:185beb968bd1a81d","source_path":"index.md","text_hash":"185beb968bd1a81d07ebcf82376642f7b29f1b5594b21fe9edee714efbdcaa44","text":"✈️ ","translated":"✈️ ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:33Z"} -{"cache_key":"20af820e30f9d07e1b6dce3866df5f8dff2be94881a44767228a1f6b9aa5d1bf","segment_id":"index.md:274162b77e02a189","source_path":"index.md","text_hash":"274162b77e02a1898044ea787db109077a2969634f007221c29b53c2e159b0cc","text":". Plugins add Mattermost (Bot API + WebSocket) and more.\nOpenClaw also powers the OpenClaw assistant.","translated":"。插件还支持 Mattermost(Bot API + WebSocket)等更多平台。\nOpenClaw 还为 OpenClaw 助手提供支持。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:47:37Z"} -{"cache_key":"20afa1e6ed4b34b77d13becaaffdcb038b92351654672578634c6f3761b82d38","segment_id":"help/index.md:6201111b83a0cb5b","source_path":"help/index.md","text_hash":"6201111b83a0cb5b0922cb37cc442b9a40e24e3b1ce100a4bb204f4c63fd2ac0","text":" and ","translated":" 和 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:44:52Z"} -{"cache_key":"2187914f759dffd9a960e25b4de5d07c68b9cf635f2d86e0497c90a80ec9fa57","segment_id":"environment.md:e234227b0e001687","source_path":"environment.md","text_hash":"e234227b0e001687821541fac3af38fc6be293ec6e13910c6826b9afc8ca33be","text":" syntax:","translated":" 语法:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:47:03Z"} -{"cache_key":"2194495894bf0f98ef0af4a8658521377e555a9fc6b7b1c7bfd99e305d7f023f","segment_id":"start/wizard.md:649cfa2f76a80b42","source_path":"start/wizard.md","text_hash":"649cfa2f76a80b42e1821c89edd348794689409dcdf619dcd10624fb577c676b","text":"not recommended","translated":"不推荐","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:45:35Z"} -{"cache_key":"21c3bf5b2b4eac5e8703e4e98cf9179524d16013e1324921b87acaa0cf085d2f","segment_id":"index.md:4b4051e77af8844f","source_path":"index.md","text_hash":"4b4051e77af8844fcf86a298214527e7840938258f99bfe97b900bbc0d8d2f4b","text":"The dashboard is the browser Control UI for chat, config, nodes, sessions, and more.\nLocal default: http://127.0.0.1:18789/\nRemote access: ","translated":"仪表板是用于聊天、配置、节点、会话 等功能的浏览器控制界面。\n本地默认地址:http://127.0.0.1:18789/\n远程访问: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:07Z"} -{"cache_key":"21d5f361e852fbe5b69697313f954689d7f44d285c1d9039ba360a8907a1b7b8","segment_id":"environment.md:453c14128fbfb5f6","source_path":"environment.md","text_hash":"453c14128fbfb5f6757511557132a1dbb3bcbf243267630bfec49db8518c7780","text":"Env var substitution in config","translated":"配置中的环境变量替换","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:22:29Z"} -{"cache_key":"21e1ac9646c9b4ec91d366e85957a04c5b7f0c41c95e653c43925dd01c080501","segment_id":"index.md:4b4051e77af8844f","source_path":"index.md","text_hash":"4b4051e77af8844fcf86a298214527e7840938258f99bfe97b900bbc0d8d2f4b","text":"The dashboard is the browser Control UI for chat, config, nodes, sessions, and more.\nLocal default: http://127.0.0.1:18789/\nRemote access: ","translated":"仪表盘是用于聊天、配置、节点、会话等功能的浏览器控制界面。\n本地默认地址:http://127.0.0.1:18789/\n远程访问: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:23Z"} -{"cache_key":"2208e96b11a53d5948e802dc055895cfdd8ee5ecbaca057c64038b30e25e1403","segment_id":"start/wizard.md:65d655d45a507243","source_path":"start/wizard.md","text_hash":"65d655d45a50724332fee040cd2c6a000778db0e122459fc48047206e699900a","text":"(or pass ","translated":"(或传入 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:15Z"} -{"cache_key":"221e7c2c0fe8b9bb39aa23d66ead440852512864ee62242cc3d9290dbd135860","segment_id":"index.md:9bd86b0bbc71de88","source_path":"index.md","text_hash":"9bd86b0bbc71de88337aa8ca00f0365c1333c43613b77aaa46394c431cb9afd8","text":"Maxim Vovshin","translated":"Maxim Vovshin","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:49Z"} -{"cache_key":"2220f5ebb94a086ce480f01165b1993d04e470d58154e2aa482056a2eecbb1f1","segment_id":"help/index.md:3c33340bd23b8db8","source_path":"help/index.md","text_hash":"3c33340bd23b8db89f18fe7d05a954738c0dd5ba9623cf6bdb7bb5d1a3729cfc","text":"FAQ (concepts)","translated":"常见问题(概念)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:24:59Z"} -{"cache_key":"2229ff2bff7c65fc1a4cd5515373b1b3319f43a26222f43787452e985cf5e4bb","segment_id":"index.md:11d28de5b79e3973","source_path":"index.md","text_hash":"11d28de5b79e3973f6a3e44d08725cdd5852e3e65e2ff188f6708ae9ce776afc","text":"Docs hubs (all pages linked)","translated":"文档中心(所有页面链接)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:49Z"} -{"cache_key":"22baac03ae69320ee9635f7e23e85e926ed40c441e97357b30b48e271e88770f","segment_id":"index.md:013e11a23ec9833f","source_path":"index.md","text_hash":"013e11a23ec9833f907b2ead492b0949015e25d10ba92461669609aee559335d","text":"Start here:","translated":"从这里开始:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:47Z"} -{"cache_key":"22bfdd3e9e4f7a5447edf31592e38d663a8907afca5f46061f314b924280a94b","segment_id":"index.md:d53b75d922286041","source_path":"index.md","text_hash":"d53b75d9222860417f783b0829023b450905d982011d35f0e71de8eed93d90fc","text":"New install from zero:","translated":"从零开始全新安装:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:47:41Z"} -{"cache_key":"22c7a06691f087acabe4321804edbb000eaf7520b16060ac2879f19252b639e3","segment_id":"index.md:31365ab9453d6a1e","source_path":"index.md","text_hash":"31365ab9453d6a1ec03731622803d3b44f345b6afad08040d7f3e97290c77913","text":"do nothing","translated":"不做任何操作","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:33Z"} -{"cache_key":"22d40e91dde10d2912781df931ab0fac2802d5b81e63fdd93bdb7856c8c43976","segment_id":"environment.md:7175517a370b5cd2","source_path":"environment.md","text_hash":"7175517a370b5cd2e664e3fd29c4ea9db5ce17058eb9772fe090a5485e49dad6","text":" or ","translated":" 或 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:26:00Z"} -{"cache_key":"23004dacbc322d02e170261429793a8b23569f398c4f21352a030b42543cdef9","segment_id":"index.md:6b65292dc52408c1","source_path":"index.md","text_hash":"6b65292dc52408c15bb07aa90735e215262df697d1a7bd2d907c9d1ff294ed5e","text":"If you don’t have a global install yet, run the onboarding step via ","translated":"如果您还没有全局安装,请通过以下方式运行 上手引导 步骤 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:37Z"} -{"cache_key":"231f5f501e89f219692ad075c657cf5933b0f1f238599ce9c071676a24e755f6","segment_id":"index.md:45e6d69dbe995a36","source_path":"index.md","text_hash":"45e6d69dbe995a36f7bc20755eff4eb4d2afaaedbcac4668ab62540c57219f32","text":"macOS app","translated":"macOS 应用","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:53Z"} -{"cache_key":"232f62d57ad6e5a82f4409553ea36a2922ef2c0d515cf24d030edd4c81c89e9f","segment_id":"help/index.md:8ddb7fc8a87904de","source_path":"help/index.md","text_hash":"8ddb7fc8a87904dedc2afc16400fbe4e78582b302e01c30b1319c8a465d04684","text":"Troubleshooting:","translated":"故障排除:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:10Z"} -{"cache_key":"2406d5725ab83e6898a33bba0fc2cd62ee455bd54fbe32831a88379d5e02d86f","segment_id":"index.md:c0aa8fcb6528510a","source_path":"index.md","text_hash":"c0aa8fcb6528510aea46361e8c871d88340063926a8dfdd4ba849b6190dec713","text":": it is the only process allowed to own the WhatsApp Web session. If you need a rescue bot or strict isolation, run multiple gateways with isolated profiles and ports; see ","translated":":它是唯一允许持有 WhatsApp Web 会话的进程。如果需要备用机器人或严格隔离,可使用独立配置文件和端口运行多个 Gateway;请参阅 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:43Z"} -{"cache_key":"241e91bd0b62e35fb2ec88322ec08e734dda812d53f7abab56928ef184075551","segment_id":"environment.md:6db0742daaf9f191","source_path":"environment.md","text_hash":"6db0742daaf9f191ab7816d2c9d317b1ea1693453a8c63b95af8b01477e0f5bb","text":" runs your login shell and imports only ","translated":" 运行你的登录 shell 并仅导入 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:39Z"} -{"cache_key":"2464c2f32b20d6e91fc9b63900ca12b81b1cb3fd185ad50d14ba4335d4e1b7a5","segment_id":"index.md:6e0f6eca4ff17d33","source_path":"index.md","text_hash":"6e0f6eca4ff17d3377c1c3e8e1f73457553ad3b9cfcd5e4f2b94cfb1028b6234","text":"iOS app","translated":"iOS 应用","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:55Z"} -{"cache_key":"24f4ed3c397e27f4a1d99dd6920c49327133c009ca1c9c5ba236d54ae50831f3","segment_id":"start/getting-started.md:8b31087991db3d3d","source_path":"start/getting-started.md","text_hash":"8b31087991db3d3d41b72b3dc31587adf140ea2bc46913b195c773810711388f","text":"and chat in the browser, or open ","translated":"然后在浏览器中聊天,或打开 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:35Z"} -{"cache_key":"24fe1d1819e7b7ad223dda1b2a6ce1ec91a1954bf95f40a7dcdbba28129b3930","segment_id":"environment.md:582967534d0f909d","source_path":"environment.md","text_hash":"582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf","text":" in ","translated":" 在 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:02Z"} -{"cache_key":"250eb34b1c8653641bb56ae814e663c3ddeaf7caa912b2b75e321788d4e7e9da","segment_id":"start/getting-started.md:053bc65874ad6098","source_path":"start/getting-started.md","text_hash":"053bc65874ad6098e58c41c57b378a2f36b0220e5e0b46722245e6c2f796818c","text":"Discord","translated":"Discord","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:26Z"} -{"cache_key":"250ebfe2db8b434d37c37a532f532102c1e6f30cfaa1c295af3c4fbe13ffc1ba","segment_id":"help/index.md:cad44fbae951d379","source_path":"help/index.md","text_hash":"cad44fbae951d3791565b0cee788c01c3bd10e0176167acb691b8dba0f7895f8","text":"Gateway logging","translated":"Gateway 日志记录","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:26Z"} -{"cache_key":"25861831dad7a8862f567594c9bc4b59c68dc56776ba50ff9d7295c536b23664","segment_id":"help/index.md:6cb77499abdccd9a","source_path":"help/index.md","text_hash":"6cb77499abdccd9a2dbb7c93a4d31eed01613dda06302933057970df9ecdeb54","text":"Logs:","translated":"日志:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:56:31Z"} -{"cache_key":"25cc8403b5816b888911443d2917b330bc530b2e338f51b2a7422b2a78b7870d","segment_id":"index.md:e64d6b29b9d90bba","source_path":"index.md","text_hash":"e64d6b29b9d90bba92ffe2539dc295a75c553684fed0350ee56bfd0aead01662","text":"Multiple gateways","translated":"多网关","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:36Z"} -{"cache_key":"25e8d037a4a0fb8c548da95825983c8a0af432d3220c14dd9908bbc344acbb2b","segment_id":"index.md:45808d75bf8911fa","source_path":"index.md","text_hash":"45808d75bf8911fa21637f9dd3f0dace1877748211976b5d61fcc5c15db594d0","text":"Webhooks","translated":"Webhooks","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:08Z"} -{"cache_key":"26087df3db46ce7741b72a3511fc552773df03f7de93d20d9d6c1aaf74ada2f0","segment_id":"environment.md:6f59001999ef7b71","source_path":"environment.md","text_hash":"6f59001999ef7b7128bab80d2034c419f3034497e05f69fbdf67f7b655cdc173","text":"Configuration: Env var substitution","translated":"配置:环境变量替换","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:22:40Z"} -{"cache_key":"2609a5fb897b0d40ef4bdfd04a26758f1b19819e28a2db1074ca89dd348c1834","segment_id":"environment.md:32ebb1abcc1c601c","source_path":"environment.md","text_hash":"32ebb1abcc1c601ceb9c4e3c4faba0caa5b85bb98c4f1e6612c40faa528a91c9","text":" (","translated":" (","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:41:00Z"} -{"cache_key":"2628c353f974405b473f8058fe5c80b4039449f51806dee3ced22ced458507c3","segment_id":"environment.md:frontmatter:read_when:0","source_path":"environment.md:frontmatter:read_when:0","text_hash":"90fc0487bff88009979cff1061c1a882df8c3b1baa9c43538331d9d5dab15479","text":"You need to know which env vars are loaded, and in what order","translated":"你需要了解加载了哪些环境变量,以及它们的加载顺序","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:07Z"} -{"cache_key":"2641fa57e655e2907092885b0b24665c212df5b58bb36fa826f14180e4ec67f3","segment_id":"index.md:99260acc29f71e4b","source_path":"index.md","text_hash":"99260acc29f71e4baeb36805a1fdbd2c17254b57c8e5a9cba29ee56518832397","text":" — Route provider accounts/peers to isolated agents (workspace + per-agent sessions)","translated":" — 将提供商账户/对等方路由到隔离的智能体(工作区 + 每智能体会话)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:12Z"} -{"cache_key":"26b05211cad1c3dae78e2e4aa1f9ed7abf9cb852044cd4f872c60d9017025c93","segment_id":"start/wizard.md:27914f11fd0ce999","source_path":"start/wizard.md","text_hash":"27914f11fd0ce99942e1903fecd5ac607d0dbc22ae97969a3819e223a32265aa","text":"Workspace location + bootstrap files","translated":"工作区位置 + 引导文件","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:21Z"} -{"cache_key":"272018c637ad26ec5622a5e164be99ef742f22f1cc1f14d3af9256471c3dbe98","segment_id":"index.md:acdd1e734125f341","source_path":"index.md","text_hash":"acdd1e734125f341604c0efbabdcc4c4b0597e8f6235d66c2445edd1812838c1","text":"Telegram","translated":"Telegram","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:53:13Z"} -{"cache_key":"2751e36b231341babf0dc82fbe5863659467382c8bf049600dd6042b26310190","segment_id":"index.md:42071940eb773f4d","source_path":"index.md","text_hash":"42071940eb773f4dcb7111f0626b4a7a823fc44098e143ff425db8a03528609d","text":" — because every space lobster needs a time-and-space machine.","translated":" — 因为每只太空龙虾都需要一台时空机器。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:05:41Z"} -{"cache_key":"278578406409f5c240b49ce02dbb5bf926ca1b0ed2c7ffaa4fe2fe66ae017223","segment_id":"start/getting-started.md:623b2b8c94dc9c42","source_path":"start/getting-started.md","text_hash":"623b2b8c94dc9c4272eef1ee15c7f60ac3a2525fa9e80235380c46f41ed38748","text":"4) Pair + connect your first chat surface","translated":"4)配对 + 连接您的第一个聊天界面","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:07Z"} -{"cache_key":"27a004245e98dcbaa5e48cc369f6f2aa4bcdcf81bb6da9f4b59f6a9c0aa4d950","segment_id":"index.md:42071940eb773f4d","source_path":"index.md","text_hash":"42071940eb773f4dcb7111f0626b4a7a823fc44098e143ff425db8a03528609d","text":" — because every space lobster needs a time-and-space machine.","translated":" —— 因为每只太空龙虾都需要一台时空机器。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:07Z"} -{"cache_key":"27a06da04c255a5ecf19b5022dd6180357807d50162a5698cd21d3eb78388ef3","segment_id":"environment.md:cda454f61dfcac70","source_path":"environment.md","text_hash":"cda454f61dfcac7007a9edc538f9f58cf38caa0652e253975979308162bccc53","text":"Gateway configuration","translated":"Gateway 配置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:41:39Z"} -{"cache_key":"27d042d7c4de0149b07caa1eef12a5a6b13bad2607338e471254e32ea17ac4fe","segment_id":"index.md:6d6577cb1c128ac1","source_path":"index.md","text_hash":"6d6577cb1c128ac18a286d3c352755d1a265b1e3a03eded8885532c3f36e32ed","text":"Mario Zechner","translated":"Mario Zechner","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:25Z"} -{"cache_key":"27e979437c543d1b0d913e200ae97874a872dbe3fb1ae1e0ea7d6eb6ebbe334e","segment_id":"index.md:98a670e2fb754896","source_path":"index.md","text_hash":"98a670e2fb7548964e8b78b90fef47f679580423427bfd15e5869aca9681d0dd","text":"\"We're all just playing with our own prompts.\"","translated":"\"我们都只是在玩弄自己的提示词。\"","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:10Z"} -{"cache_key":"28006596cdda45f4da3d43d4aca5bf66c459d4553682e2dd295c7e256c0a7dc6","segment_id":"start/wizard.md:8999c63d838a1729","source_path":"start/wizard.md","text_hash":"8999c63d838a1729c88f4334c6fd73d735c69659f7e08989bd9d4bd0cc644748","text":" Node (recommended; required for WhatsApp/Telegram). Bun is ","translated":" Node(推荐;WhatsApp/Telegram 需要)。Bun ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:45:33Z"} -{"cache_key":"2816a7fdcd6be1cbfa2991a8e2e2a7547e4d6c8c24cea4a8cd4bd797e593002b","segment_id":"help/index.md:d3ef01b4a9c99103","source_path":"help/index.md","text_hash":"d3ef01b4a9c9910364c9b26b2499c8787a0461d2d24ab80376fff736a288b34c","text":"Logging","translated":"日志记录","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:39:48Z"} -{"cache_key":"28d24c047d26e2c1e65fd0bbb5ff062aa4ac050cf6a9d74ff349d775635b6ebd","segment_id":"index.md:aaa095329e21d86e","source_path":"index.md","text_hash":"aaa095329e21d86e24e8bec91bc001f7983d73a7a04c75646c0256448dac30ef","text":" — The space lobster who demanded a better name","translated":" —— 那只要求更好名字的太空龙虾","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:36Z"} -{"cache_key":"28e8ae5018d34b717de70ce7f23982de74c146a1f056b26e5e4ae8104534414e","segment_id":"index.md:6201111b83a0cb5b","source_path":"index.md","text_hash":"6201111b83a0cb5b0922cb37cc442b9a40e24e3b1ce100a4bb204f4c63fd2ac0","text":" and ","translated":" 和 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:26Z"} -{"cache_key":"28ef1da9761f650da74d92d311e4340eb104aa4bfe79c0770be44869d3d4388b","segment_id":"help/index.md:156597e2632411d1","source_path":"help/index.md","text_hash":"156597e2632411d1d5f634db15004072607ba45072a4e17dfa51790a37b6781f","text":"Gateway issues:","translated":"Gateway 问题:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:39:41Z"} -{"cache_key":"2915e64d137473ff7b41748d6e775157eeff0e1392db33707e68c51e7d2b3e4a","segment_id":"environment.md:6f59001999ef7b71","source_path":"environment.md","text_hash":"6f59001999ef7b7128bab80d2034c419f3034497e05f69fbdf67f7b655cdc173","text":"Configuration: Env var substitution","translated":"配置:环境变量替换","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:26:30Z"} -{"cache_key":"29a2f85f24db686837fe914b9726eff6a76c743da516c02abf9e7b37b6e7a822","segment_id":"index.md:76d6f9c532961885","source_path":"index.md","text_hash":"76d6f9c5329618856f133dc695e78f085545ae05fae74228fb1135cba7009fca","text":") — Pi creator, security pen-tester","translated":")— Pi 创始人,安全渗透测试员","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:06:04Z"} -{"cache_key":"29ad5ac78c867238eeea5d895c4831ef7fd4b4da6897dbbebfa2442fe9b4a55e","segment_id":"index.md:e3209251e20896ec","source_path":"index.md","text_hash":"e3209251e20896ecc60fa4da2817639f317fbb576288a9fc52d11e5030ecc44a","text":"Windows (WSL2)","translated":"Windows (WSL2)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:59Z"} -{"cache_key":"2a0917591bc5d0651e00107b3f0240ec8ef7f815194af495b214e011d1572e63","segment_id":"environment.md:cf0923bd0c80e86a","source_path":"environment.md","text_hash":"cf0923bd0c80e86a7aa644d04aa412cbd7baa3273153c40c625ceca9e012bde8","text":" runs your login shell and imports only **missing** expected keys:","translated":" 运行你的登录 shell 并仅导入**缺失的**预期键:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:11:51Z"} -{"cache_key":"2a125978841a8b745660c2fe10733f5a7ec04f35d6edccb62a3a6099827c9f31","segment_id":"help/index.md:frontmatter:summary","source_path":"help/index.md:frontmatter:summary","text_hash":"aece82a2d540ab1a9a21c7b038127cae6e9db2149491564bb1856b6f8999f205","text":"Help hub: common fixes, install sanity, and where to look when something breaks","translated":"帮助中心:常见修复方法、安装完整性检查,以及出现问题时的排查指南","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:56:09Z"} -{"cache_key":"2a272e89ec32a98ddfab85e3261d797830491c81beea1bc76f02a2f10056444a","segment_id":"environment.md:aac7246f5e97142c","source_path":"environment.md","text_hash":"aac7246f5e97142c3f257b7d8b84976f10c29e1b89804bb9d3eb7c43cc03cb8e","text":"Environment variables","translated":"环境变量","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:19:20Z"} -{"cache_key":"2a5de10a869ddf9795eb574cdf1669853adf68de0aa9b586340f9f98b19a2c1b","segment_id":"index.md:723fad6d27da9393","source_path":"index.md","text_hash":"723fad6d27da939353c65417bbaf646b65903b316eb4456297ff4a1c20811e8d","text":": HTTP file server on ","translated":":HTTP 文件服务器运行在 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:08Z"} -{"cache_key":"2a9244cf7264d7f417232bd9f92f966b46aa99b5cace7e6461e0b2d3a79e18fc","segment_id":"start/wizard.md:4646ca09dd863969","source_path":"start/wizard.md","text_hash":"4646ca09dd86396938b77d769471ccf591fb10f1e70b87c8e119921585c68647","text":"Anthropic API key (recommended)","translated":"Anthropic API 密钥(推荐)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:46Z"} -{"cache_key":"2a9bdab2f771b41c294a531f1d6df2023e4b67ee480cca4539599f2a60055a81","segment_id":"index.md:8fdfb6437318756c","source_path":"index.md","text_hash":"8fdfb6437318756c950bf2261538f06236e36040986891fa7b43452b987fb9f3","text":" — an AI, probably high on tokens","translated":" —— 一个可能被令牌冲昏头脑的 AI","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:13Z"} -{"cache_key":"2ac5a1447db5ab39cf2aa397324373ad9f62dc6a5dc80ce471170fb19c6f63e3","segment_id":"environment.md:f15f5f9f4ef4d668","source_path":"environment.md","text_hash":"f15f5f9f4ef4d6688876c894f8eba251ed1db6eaf2209084028d43c9e76a8ba1","text":" (aka ","translated":" (又称 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:52Z"} -{"cache_key":"2b3277f22f598b1a6f7a3131d92633b96fe7b09bfc6833b4283733bbb5e47a19","segment_id":"index.md:8f6fb4eb7f42c0e2","source_path":"index.md","text_hash":"8f6fb4eb7f42c0e245e29e63f5b82cc3ba19852681d1ed9aed291f59cf75ec0e","text":"Security","translated":"安全","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:12Z"} -{"cache_key":"2b5833fa7ce9898da69d1e64fc5c3a5eba6bb67c371a2b611ff4558aecdd62ca","segment_id":"environment.md:aac7246f5e97142c","source_path":"environment.md","text_hash":"aac7246f5e97142c3f257b7d8b84976f10c29e1b89804bb9d3eb7c43cc03cb8e","text":"Environment variables","translated":"环境变量","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:08Z"} -{"cache_key":"2baecfd26ff47bc7814b55f6a2cdeeb462776c8057428fe9125b6157e0185296","segment_id":"index.md:e1b33cfa2a781bde","source_path":"index.md","text_hash":"e1b33cfa2a781bde9ef6c1d08bf95993c62f780a6664f5c5b92e3d3633e1fcf8","text":" (@nachoiacovino, ","translated":" (@nachoiacovino, ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:06:27Z"} -{"cache_key":"2c1cb1cef6155b763b2262ef37c863de566330d14bf74280615cb6e549e58049","segment_id":"environment.md:32ebb1abcc1c601c","source_path":"environment.md","text_hash":"32ebb1abcc1c601ceb9c4e3c4faba0caa5b85bb98c4f1e6612c40faa528a91c9","text":" (","translated":" (","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:52Z"} -{"cache_key":"2c3188ffa72715b1d59025704a94f302614ca289ab2320901d5025dbba20e295","segment_id":"index.md:bf084dc7b82e1e62","source_path":"index.md","text_hash":"bf084dc7b82e1e62c63727b13451d1eba2269860e27db290d2d5908d7ade0529","text":" — Pairs as a node and exposes Canvas + Chat + Camera","translated":" —— 作为节点配对并暴露 Canvas + 聊天 + 相机","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:17Z"} -{"cache_key":"2c32c166aa68ab2e4ad5a305268b0b4fa3715c00d5c8711954f57c56bce5bf2f","segment_id":"index.md:7af023c43013b9a5","source_path":"index.md","text_hash":"7af023c43013b9a53fbff7dd4b5821588bba3319308878229740489152c43f6d","text":"Docs","translated":"文档","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:03:42Z"} -{"cache_key":"2c4fad6883c7306600d4b8017b42f71a49a9ef90d3f7c903931dcc1a42d6a629","segment_id":"start/getting-started.md:130fc173d131a8a8","source_path":"start/getting-started.md","text_hash":"130fc173d131a8a8e647eff6d934160e7ffc33c8a488d296f4952e43669efece","text":"Remote access (SSH tunnel / Tailscale Serve): ","translated":"远程访问(SSH 隧道 / Tailscale Serve): ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:30Z"} -{"cache_key":"2c8498d9a65196b921db3277f57a9f7a4d54f247bf632149a7e6f6d7852e3f8a","segment_id":"index.md:80fc402133201fbe","source_path":"index.md","text_hash":"80fc402133201fbe0e4e9962a9570e741856aa8b0c033f1a20a9bcb06c68e809","text":"Discovery","translated":"发现","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:43Z"} -{"cache_key":"2ca15829b0103ac379ae5ff09f282509d35a9e1dc45bbf196c72de71b74bb544","segment_id":"start/wizard.md:1d7b0a62c6b0c807","source_path":"start/wizard.md","text_hash":"1d7b0a62c6b0c8074693534632fba1f2651e07a43d627d9b033133f7be0a1e13","text":"Moonshot example:","translated":"Moonshot 示例:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:47:28Z"} -{"cache_key":"2cd61dfffeb36096d91b4e57fb246bbcee08cc8578906f516e40f38a3f0fd07b","segment_id":"start/getting-started.md:552d8f1e99b582e6","source_path":"start/getting-started.md","text_hash":"552d8f1e99b582e60aca716254ccebd754c93d319a7c4459e4d741e23ebf5e81","text":"Gateway token","translated":"Gateway 令牌","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:23Z"} -{"cache_key":"2ce482e209f5de8ec61a9b3c7a287df2841a981d3764b77fdcf48af2a7b85703","segment_id":"help/index.md:24669ff48290c187","source_path":"help/index.md","text_hash":"24669ff48290c1875d8067bbd241e8a55444839747bffb8ab99f3a34ef248436","text":"Doctor","translated":"诊断工具","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:44:58Z"} -{"cache_key":"2d0888805bfed46ef5b60cd62356c0e806d41c0b9121d293e637f9c246793517","segment_id":"start/wizard.md:f5f5d467d48ef0f0","source_path":"start/wizard.md","text_hash":"f5f5d467d48ef0f0285b3b241da9c210af806de0b975ef0d1c8caa8e43f02aca","text":" to route inbound messages (the wizard can do this).","translated":" 以路由入站消息(向导可以执行此操作)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:47:03Z"} -{"cache_key":"2d2da52fe8692965c9fb95b555b3aa3e2a2a66b0d5dda886a051d52f1a0ef1e3","segment_id":"index.md:c4b2896a2081395e","source_path":"index.md","text_hash":"c4b2896a2081395e282313d6683f07c81e3339ef8b9d2b5a299ea5b626a0998f","text":").","translated":")。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:09Z"} -{"cache_key":"2d3da03d164952a8c60693fdd97d8be29700340d6eaee19967b24342510d499a","segment_id":"index.md:83f4fc80f6b452f7","source_path":"index.md","text_hash":"83f4fc80f6b452f7cdf426f6b87f08346d7a2d9c74a0fb62815dce2bfddacf63","text":" — A space lobster, probably","translated":" —— 大概是一只太空龙虾说的","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:47:27Z"} -{"cache_key":"2d48b01c4769947be3c3683c4a8f28dd565d2db1936464b4c5d5731a12d79c60","segment_id":"index.md:30f035b33a6c35d5","source_path":"index.md","text_hash":"30f035b33a6c35d51e09f9241c61061355c872f2fb9a82822cd2f5f443fd4ad4","text":"Group Chat Support","translated":"群聊支持","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:41Z"} -{"cache_key":"2d797dc8210ef143472d22214940192b0a9192ba2fbb7c937caed61f06927d9b","segment_id":"index.md:74f99190ef66a7d5","source_path":"index.md","text_hash":"74f99190ef66a7d513049d31bafc76e05f9703f3320bf757fb2693447a48c25b","text":"Linux app","translated":"Linux 应用","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:02Z"} -{"cache_key":"2e074e5ac1705b797a4c77f7b223adcd0ae6a9f96032a837408a8435a639baff","segment_id":"index.md:37ed7c96b16160d4","source_path":"index.md","text_hash":"37ed7c96b16160d491e44676aa09fe625301de9c018ad086e263f59398b8be8a","text":"🎤 ","translated":"🎤 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:53Z"} -{"cache_key":"2e1d0951abfbe4efbae5e5ef595f231d5292c0fcb5b3ee23005ce2b68c1d79ee","segment_id":"help/index.md:0e4ea41f62f3485d","source_path":"help/index.md","text_hash":"0e4ea41f62f3485d38cc0e63e2ccf0b40ee1e32a060b3902767d612fe0823e0e","text":" here:","translated":" 这里:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:44:32Z"} -{"cache_key":"2e3290e6bc1d3f1822509afccd756cc87e8abd242e0141e0ee64721fdb864f3f","segment_id":"start/getting-started.md:f11e33a27b5b9a1c","source_path":"start/getting-started.md","text_hash":"f11e33a27b5b9a1c3aefd4fc3e37fd3effab8e9378119a2a21d20312adb940a7","text":"CLI onboarding wizard","translated":"CLI 上手引导向导","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:48Z"} -{"cache_key":"2e45b9544e6ff8d717250c9ddcf1e30690e094f474a744dda548b3e297c59cb7","segment_id":"environment.md:8d076464a84995bc","source_path":"environment.md","text_hash":"8d076464a84995bc095e934b0aa1e4419372f27cd71d033571e4dbba201ee5d8","text":"You can reference env vars directly in config string values using ","translated":"你可以在配置的字符串值中直接使用以下方式引用环境变量 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:58Z"} -{"cache_key":"2e681efe18de20b4f07ad32002c6fec86c06e56a12cd30d9c7bdbc9534bb6882","segment_id":"environment.md:frontmatter:summary","source_path":"environment.md:frontmatter:summary","text_hash":"78351223e7068721146d2de022fdf440c2866b2ee02fbbb50bf64369b999820b","text":"Where OpenClaw loads environment variables and the precedence order","translated":"OpenClaw 加载环境变量的位置及优先级顺序","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:44Z"} -{"cache_key":"2ef70367fb9aa09677565cc6176a971e2f70631d568dfe275604a6337f5ab6ad","segment_id":"environment.md:b1d6b91b67c2afa5","source_path":"environment.md","text_hash":"b1d6b91b67c2afa5e322988d9462638d354ddf8a1ef79dba987f815c22b4baee","text":" at ","translated":" 位于 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:32Z"} -{"cache_key":"2f07feeae0f7c7fd42259f8d149e737f19de5e6a5479067a97efdec3042fdd56","segment_id":"start/wizard.md:ca7981b46ecf2c17","source_path":"start/wizard.md","text_hash":"ca7981b46ecf2c1787b6d76d81d9fd7fa0ca95842e2fcc2a452869891a9334d1","text":"Off","translated":"关闭","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:02Z"} -{"cache_key":"2f42896cbef80e422a89e75bb6eff3784602d724b92e704a145d54f389869f2c","segment_id":"start/wizard.md:be297ea5bdb13e65","source_path":"start/wizard.md","text_hash":"be297ea5bdb13e6504ca452403bae1d77358398f376fc59ee9f4e06d566bc3e9","text":" even for loopback so local WS clients must authenticate.","translated":" 即使在回环地址上也使用,以确保本地 WS 客户端必须进行认证。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:44:03Z"} -{"cache_key":"300af3259f829741d51736865d7bf9f842f81f2138585d92d271370b4fb55164","segment_id":"environment.md:1734069c13c6a5b4","source_path":"environment.md","text_hash":"1734069c13c6a5b4de554e73a650ddce6651688b5771f03df706a836393aea3c","text":" override).","translated":" 覆盖)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:45Z"} -{"cache_key":"30608165f61f3a9ef054a6c564e06dfb89be246127382e61e93c52a93fa2aa9c","segment_id":"start/wizard.md:frontmatter:summary","source_path":"start/wizard.md:frontmatter:summary","text_hash":"37d4cb914a0312f3c0272449b49ff1a5b48ae22e79defb9680df63865bc21ea3","text":"CLI onboarding wizard: guided setup for gateway, workspace, channels, and skills","translated":"CLI 上手引导向导:Gateway、工作区、渠道和技能的引导式设置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:51Z"} -{"cache_key":"30675512d7a61a650d56f0b23e4df35eee0be54824589dfe3cd69ef8055204a3","segment_id":"index.md:66d0f523a379b2de","source_path":"index.md","text_hash":"66d0f523a379b2de6f8d5fba3a817ebc395f7bcaa54cc132ca9dfa665d1e9378","text":"Skills","translated":"技能","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:04:17Z"} -{"cache_key":"307223a7ef9d756946e976426895e5f1195f544f15a205458dc725b42d4f6ee1","segment_id":"help/index.md:5c94724fa7810fa9","source_path":"help/index.md","text_hash":"5c94724fa7810fa9902e565cf66c5f5a973074f2961fcd3a40bad4ee4aeca5e0","text":"If you want a quick “get unstuck” flow, start here:","translated":"如果你想快速\"解决卡住的问题\",从这里开始:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:11:27Z"} -{"cache_key":"30a615ba735a73e7d3242363754be6841b011b06bcf0852eb50b1c2fad210ba1","segment_id":"index.md:9c870aa6e5e93270","source_path":"index.md","text_hash":"9c870aa6e5e93270170d5a81277ad3e623afe8d4efd186d3e28f3d2b646d52e6","text":"How it works","translated":"工作原理","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:18Z"} -{"cache_key":"30df5b02209abc9fe6dad8f8edb5d9e1ecc23a3dafd5c4df988491ab87667a35","segment_id":"start/wizard.md:acdd1e734125f341","source_path":"start/wizard.md","text_hash":"acdd1e734125f341604c0efbabdcc4c4b0597e8f6235d66c2445edd1812838c1","text":"Telegram","translated":"Telegram","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:44:27Z"} -{"cache_key":"314a94405174f8d50e035a204e5843da2f66b97b162a65bf2b933f01abbd59f9","segment_id":"start/wizard.md:e639687221fe4ab0","source_path":"start/wizard.md","text_hash":"e639687221fe4ab0824252705b8c5db6c8ece564b77025b0f6b6a4252abb9f86","text":"Seeds the workspace files needed for the agent bootstrap ritual.","translated":"生成智能体引导启动仪式所需的工作区文件。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:46Z"} -{"cache_key":"314dd665b6543d8aa3e07bfb4411985b9e65d96c9dd2d548df33fb32bd6a7137","segment_id":"start/getting-started.md:5ed525159ebd3715","source_path":"start/getting-started.md","text_hash":"5ed525159ebd371551c1615ae2782e61c74c0ed4149ffd117284ba9523eeda84","text":"1) Install the CLI (recommended)","translated":"1)安装 CLI(推荐)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:46Z"} -{"cache_key":"3160cff1ac3376c86eff02fa191d7effc632679f70ad9d0572805c87e0373938","segment_id":"start/wizard.md:4b57039163eb0a5c","source_path":"start/wizard.md","text_hash":"4b57039163eb0a5c8ee4015d016164636534a01cc8acf14b5ce9d191319954c3","text":" to your config.","translated":" 到您的配置中。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:48:06Z"} -{"cache_key":"31dec649c828923140b2b30d6a8b2d62591976002370e88c3d3de3ac115cb781","segment_id":"environment.md:45ca56d179d4788c","source_path":"environment.md","text_hash":"45ca56d179d4788c55ba9f7653b376d62e7faa738e92259e3d4f6f5c1b554f28","text":"Related","translated":"相关内容","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:17:10Z"} -{"cache_key":"3243c3ebdcaa9521501483661e48d2fdd966942cb24ea4dcde3d06b713aed8b4","segment_id":"index.md:3c8aa7ad1cfe03c1","source_path":"index.md","text_hash":"3c8aa7ad1cfe03c1cb68d48f0c155903ca49f14c9b5626059d279bffc98a8f4e","text":": connect to the Gateway WebSocket (LAN/tailnet/SSH as needed); legacy TCP bridge is deprecated/removed.","translated":":连接到 Gateway WebSocket(根据需要使用局域网/Tailnet/SSH);旧版 TCP 桥接已弃用/移除。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:52Z"} -{"cache_key":"3251f0f0403513aa1ec086eadd313880a5c01383a210ec45da22d6fa4782490e","segment_id":"index.md:ee8b06871d5e335e","source_path":"index.md","text_hash":"ee8b06871d5e335e6e686f4e2ee9c9e6de5d389ece6636e0b5e654e0d4dd5b7e","text":"Control UI (browser)","translated":"控制界面(浏览器)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:34Z"} -{"cache_key":"3276f34c2339c0658f45d0f009490234b47b5b52b8d90ee1387edff4a69ac8ae","segment_id":"index.md:93c89511a7a5dda3","source_path":"index.md","text_hash":"93c89511a7a5dda3b3f36253d17caee1e31f905813449d475bc6fed1a61f1430","text":"common fixes + troubleshooting","translated":"常见修复 + 故障排除","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:03:56Z"} -{"cache_key":"32a83090da1dc024c2a8cf8f0db8f301764d5bb1a471887273753a86569bd8cf","segment_id":"start/getting-started.md:frontmatter:read_when:1","source_path":"start/getting-started.md:frontmatter:read_when:1","text_hash":"8ffadc75217e7de913dec33459e2fc4726878cf78a1f8f6a6ce9b3b7305efa17","text":"You want the fastest path from install → onboarding → first message","translated":"您希望找到从安装 → 上手引导 → 发送第一条消息的最快路径","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:19Z"} -{"cache_key":"32aaa528f2fdc0ff7d03b917f5957bf4f19d264db511d3a6fcf39564f4c143f1","segment_id":"help/index.md:2adc964c084749b1","source_path":"help/index.md","text_hash":"2adc964c084749b1f2d8aef24030988b667dbda2e38a6a1699556c93e07c1cea","text":"Start here","translated":"从这里开始","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:24:38Z"} -{"cache_key":"32f6ccc5f301eef89b0add96d877ba4df42d5d5b8a9cd794abf9f467d5f12d54","segment_id":"help/index.md:8cd501e1124c3047","source_path":"help/index.md","text_hash":"8cd501e1124c30473473c06e536a2d145e2a14a6d7dc1b99028ce818e14442e2","text":"Repairs:","translated":"修复:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:24:52Z"} -{"cache_key":"3341a2da05aa7a14de4f05127a21a28fff121cd29d0c2dd4fe6bbf663fb59d7d","segment_id":"index.md:66354a1d3225edbf","source_path":"index.md","text_hash":"66354a1d3225edbf01146504d06aaea1242dcf50424054c3001fc6fa2ddece0f","text":"Remote access","translated":"远程访问","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:23Z"} -{"cache_key":"336e0d3df54cefc9b4f845d46763359b00993efe537c84b384ff77a19c5d95e9","segment_id":"start/wizard.md:593b35c1b027b42b","source_path":"start/wizard.md","text_hash":"593b35c1b027b42b1f14fcd3913017dae726062941e8039a72e3af3399f728df","text":"Gateway auth ","translated":"Gateway 认证 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:53Z"} -{"cache_key":"33bc493412fad9ad498a84a301ea34b43f9f34939896f8221f6e095724982543","segment_id":"start/wizard.md:0e3a130e3ae6be30","source_path":"start/wizard.md","text_hash":"0e3a130e3ae6be30792e3eeb94fed964dcceddef27f7e723da02c1d3a3a8df94","text":"Local gateway (loopback)","translated":"本地 Gateway(回环地址)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:45Z"} -{"cache_key":"33e6190920d1a6f91b3914cb673b9488a8bab0364506c16f588e85340bde439c","segment_id":"index.md:63a3abfa879299dd","source_path":"index.md","text_hash":"63a3abfa879299ddcc03558012bfd6075cbd72f7a175b739095bf979700297f7","text":"Multi-instance quickstart (optional):","translated":"多实例快速入门(可选):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:42Z"} -{"cache_key":"34058f497844c4ec778554dcaefe46e1ee1747532d1d13b1d71c9f0ce44c7514","segment_id":"environment.md:d08a8493f686363a","source_path":"environment.md","text_hash":"d08a8493f686363a78b913d45ebfbd87a3768d1c77b70f23b1fdade3c066e481","text":"Shell env import","translated":"Shell 环境导入","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:22:18Z"} -{"cache_key":"34086c013763b98b351cdd0b4f0249d6d22e5b03a465b1753e4de88e587c00ab","segment_id":"index.md:36ddb4d3cfcb494f","source_path":"index.md","text_hash":"36ddb4d3cfcb494fb96463d42b35ba923731677cfc9e084af9f25e3f231187d5","text":"💬 ","translated":"💬 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:51Z"} -{"cache_key":"34b531c230116c17ef31fc8a6f8428f6274208c2de206e4cdda99e9a1a9cb042","segment_id":"index.md:8f6fb4eb7f42c0e2","source_path":"index.md","text_hash":"8f6fb4eb7f42c0e245e29e63f5b82cc3ba19852681d1ed9aed291f59cf75ec0e","text":"Security","translated":"安全","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:05:29Z"} -{"cache_key":"34bfc7d107afffb5c740b7b90a1c6047e44c21fcac52d6b6f4859d91e803c9eb","segment_id":"environment.md:546f47a9170b7f79","source_path":"environment.md","text_hash":"546f47a9170b7f79afe6bb686aecab9c734c8e8a7d2b353d7e507ee932a0c348","text":"Environment variables\n\nOpenClaw pulls environment variables from multiple sources. The rule is ","translated":"环境变量\n\nOpenClaw 从多个来源获取环境变量。规则是 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:53Z"} -{"cache_key":"34e14035ff1a271359d67411ba4926d4dc09453dfd5418ece20924bcbfa96965","segment_id":"environment.md:496aca80e4d8f29f","source_path":"environment.md","text_hash":"496aca80e4d8f29fb8e8cd816c3afb48d3f103970b3a2ee1600c08ca67326dee","text":" block","translated":" 块","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:41Z"} -{"cache_key":"34ea3ba7fd58bb28161b7b4359bbcccffec2e9d4dbc54286ca2b0c1730769a8d","segment_id":"environment.md:cdb4ee2aea69cc6a","source_path":"environment.md","text_hash":"cdb4ee2aea69cc6a83331bbe96dc2caa9a299d21329efb0336fc02a82e1839a8","text":".","translated":".","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:15Z"} -{"cache_key":"35283f721f41d4ee600ccb4bbea1d3385ba23774e7a7790fdd45b6c18600469a","segment_id":"environment.md:d08a8493f686363a","source_path":"environment.md","text_hash":"d08a8493f686363a78b913d45ebfbd87a3768d1c77b70f23b1fdade3c066e481","text":"Shell env import","translated":"Shell 环境导入","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:11:49Z"} -{"cache_key":"352defd8fc42d9b060b6cd430d417fc2bd4c12fe53ba446d4a476ad42ccab112","segment_id":"start/wizard.md:0f3a1d92bc3a545d","source_path":"start/wizard.md","text_hash":"0f3a1d92bc3a545d9c34affb3f3116c0cc492f4a1045c05778fc4d4c442b9b96","text":" (plugin): bot token + base URL.","translated":" (插件):机器人令牌 + 基础 URL。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:44:43Z"} -{"cache_key":"35459952230518c31110b6b5f175abe88b59834c219cab3d71012db683db8121","segment_id":"start/getting-started.md:67b696468610b879","source_path":"start/getting-started.md","text_hash":"67b696468610b879ed7f224dbf6b0861f27e39d20454cb9d7af1ec52d3e5eeaa","text":"Dashboard","translated":"仪表盘","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:39Z"} -{"cache_key":"357d48a4c5e474910bc6ec1bc5ae8587a7e5f0207dd6c9102c7a1442f5696107","segment_id":"environment.md:cf3f9ba035da9f09","source_path":"environment.md","text_hash":"cf3f9ba035da9f09202ba669adca3109148811ef31d484cc2efa1ff50a1621b1","text":" (what the Gateway process already has from the parent shell/daemon).","translated":" (Gateway 进程从父 shell/守护进程中已获取的内容)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:06Z"} -{"cache_key":"364bf5b819ca7701a74bb51b78b68bb812f4e3f3590b3c69afe3efd9b0459c6b","segment_id":"environment.md:d4a67341570f4656","source_path":"environment.md","text_hash":"d4a67341570f4656784c5f8fe1bfb48a738ace57b52544977431d50e2b718099","text":"FAQ: env vars and .env loading","translated":"常见问题:环境变量和 `.env` 加载","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:26:40Z"} -{"cache_key":"3663f83bba62df5e7cb863e55c86882f54e5d3c7ee21fe4fa3335e3ea53f2d70","segment_id":"index.md:e64d6b29b9d90bba","source_path":"index.md","text_hash":"e64d6b29b9d90bba92ffe2539dc295a75c553684fed0350ee56bfd0aead01662","text":"Multiple gateways","translated":"多网关","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:58Z"} -{"cache_key":"36b17044c786e63bff17024017e7376bbbfab4b3abdcda6216a8ff4155e90b82","segment_id":"index.md:9182ff69cf35cb47","source_path":"index.md","text_hash":"9182ff69cf35cb477c02452600d23b52a49db7bd7c9833a9a8bc1dcd90c25812","text":"Node ≥ 22","translated":"Node ≥ 22","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:02:57Z"} -{"cache_key":"36ee9ff0bfd7f7a2fed757962b44a70c9130d57288004d2941c4090fe792a044","segment_id":"index.md:30f035b33a6c35d5","source_path":"index.md","text_hash":"30f035b33a6c35d51e09f9241c61061355c872f2fb9a82822cd2f5f443fd4ad4","text":"Group Chat Support","translated":"群聊支持","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:02:06Z"} -{"cache_key":"36f5535fb346a7e5a8ac7bf97f71b16da9e836aaac6004bc7f2baf2b4f74ee89","segment_id":"start/getting-started.md:f480ffb2979d1888","source_path":"start/getting-started.md","text_hash":"f480ffb2979d188849ef6ddeb7cefe0aec4406a459adc51df4808a3545d7095c","text":" uses ","translated":" 使用 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:17Z"} -{"cache_key":"3707b96e2e6a68d6b2b2cb1bc408bfdcc00b380bed0febd7847ebf22d0f0a144","segment_id":"start/wizard.md:acd0067e1ce6598b","source_path":"start/wizard.md","text_hash":"acd0067e1ce6598bac4486d7dec30e89e0cb9486eb7a5ab655327f2398d82ee2","text":"Stores it under ","translated":"将其存储在 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:48:01Z"} -{"cache_key":"3720955986bed01c1359c0e548caea0c5440fad4b43365d2fde56fb04a4e0759","segment_id":"start/wizard.md:610b6a1041c9c16b","source_path":"start/wizard.md","text_hash":"610b6a1041c9c16ba409d615ac9fc646e065c13b271889569a0f3cab45fb422b","text":"Signal setup (signal-cli)","translated":"Signal 设置 (signal-cli)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:47:49Z"} -{"cache_key":"3761d0df7c47bdf9c52491e5e93c6b9b8e7c948074b5925f77582063f787622c","segment_id":"index.md:42bb365211decccb","source_path":"index.md","text_hash":"42bb365211decccb3509f3bf8c4dfcb5ae05fe36dfdedb000cbf44e59e420dc9","text":" — Local imsg CLI integration (macOS)","translated":" —— 本地 imsg CLI 集成(macOS)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:56Z"} -{"cache_key":"3790b7cccef83371cab7a1989734dc2df8216f5cdb52d6e28db0e9e844c5671c","segment_id":"help/index.md:8cd501e1124c3047","source_path":"help/index.md","text_hash":"8cd501e1124c30473473c06e536a2d145e2a14a6d7dc1b99028ce818e14442e2","text":"Repairs:","translated":"修复:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:27Z"} -{"cache_key":"37b110b0b1d718b41a94fb3a9a4f13223dae87e68c5e0f999d287897a386511e","segment_id":"environment.md:cdb4ee2aea69cc6a","source_path":"environment.md","text_hash":"cdb4ee2aea69cc6a83331bbe96dc2caa9a299d21329efb0336fc02a82e1839a8","text":".","translated":"。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:22:02Z"} -{"cache_key":"37b7c0541ea6313c43233942e42fd671ee86f3f7a07973e395b38ad0ff8dbc0a","segment_id":"index.md:6b3f22c979b9e6f8","source_path":"index.md","text_hash":"6b3f22c979b9e6f8622031a6b638ec5f730c32de646d013e616078e03f5a6149","text":"iOS node","translated":"iOS 节点","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:55Z"} -{"cache_key":"380da2c38442028181e5e4e1bc68442ff14ff2bcd89177a4c1a3bc96b478155b","segment_id":"index.md:36ddb4d3cfcb494f","source_path":"index.md","text_hash":"36ddb4d3cfcb494fb96463d42b35ba923731677cfc9e084af9f25e3f231187d5","text":"💬 ","translated":"💬 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:49Z"} -{"cache_key":"3861d187be12abb8bb56846e66cdbe56efbfcc8ab9dc5fa49ad7526b34954f7c","segment_id":"help/index.md:729bc562eec2658b","source_path":"help/index.md","text_hash":"729bc562eec2658bd11ffdd522fe5277177dc73e86eaca7baac0b472a4d8f8b2","text":"If you’re looking for conceptual questions (not “something broke”):","translated":"如果你在寻找概念性问题(而非\"出了故障\"):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:56:47Z"} -{"cache_key":"38b96681367af140e653ee05ec7a261cf0941c0975166b3ac38008c0f1fd218d","segment_id":"help/index.md:71095a6d42f5d9c2","source_path":"help/index.md","text_hash":"71095a6d42f5d9c2464a8e3f231fc53636d4ce0f9356b645d245874162ec07e2","text":"Gateway troubleshooting","translated":"Gateway 故障排除","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:19Z"} -{"cache_key":"38ce802888d58badfba21b504c45ae2e126bfa2ff05300da807328abce6bb3ea","segment_id":"environment.md:cf3f9ba035da9f09","source_path":"environment.md","text_hash":"cf3f9ba035da9f09202ba669adca3109148811ef31d484cc2efa1ff50a1621b1","text":" (what the Gateway process already has from the parent shell/daemon).","translated":" (Gateway 进程从父 shell/守护进程中已继承的值)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:02Z"} -{"cache_key":"38e1bd28383c38781623486e59dac26bb496cbacc9e2eda9120b373298a51ff3","segment_id":"index.md:ba5ec51d07a4ac0e","source_path":"index.md","text_hash":"ba5ec51d07a4ac0e951608704431d59a02b21a4e951acc10505a8dc407c501ee","text":")","translated":")","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:11Z"} -{"cache_key":"3916f9bae114afcf8d795dfb5375fa24f3e06a8a118fe2ecbb2915900f6a9f82","segment_id":"index.md:e3209251e20896ec","source_path":"index.md","text_hash":"e3209251e20896ecc60fa4da2817639f317fbb576288a9fc52d11e5030ecc44a","text":"Windows (WSL2)","translated":"Windows (WSL2)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:05:14Z"} -{"cache_key":"394214a19e461907fb2a1cc918c6f38ae64e4715143377c7a9166d0b985547df","segment_id":"index.md:88d90e2eef3374ce","source_path":"index.md","text_hash":"88d90e2eef3374ce1a7b5e7fbd3b1159364b26a8ceb2493d6e546d4444b03cda","text":"Tailscale","translated":"Tailscale","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:16Z"} -{"cache_key":"3983900aa2122716086238320301d2ccc9ca38cbfbc5fadec4629f48bac4e248","segment_id":"index.md:5928d14b4d45263d","source_path":"index.md","text_hash":"5928d14b4d45263d4964dfd301c84ed2674ca8b4b698c5efeb88fb86076d2bf9","text":"🎮 ","translated":"🎮 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:02Z"} -{"cache_key":"3a153551510fda2c4710a20c9a4cc23057396667a7df9dd6e1abcab82c50b896","segment_id":"environment.md:61115f6649792387","source_path":"environment.md","text_hash":"61115f664979238731a390e84433a818965b7eaf1d38fa5b4b1507c33ef28c91","text":"Precedence (highest → lowest)","translated":"优先级(从高到低)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:22:04Z"} -{"cache_key":"3a1be3034443bc71b47581e4ea05266f8538eaa0a0fdc3da9bad0ed023893ac7","segment_id":"start/getting-started.md:e93372533f323b2f","source_path":"start/getting-started.md","text_hash":"e93372533f323b2f12783aa3a586135cf421486439c2cdcde47411b78f9839ec","text":"Node ","translated":"Node ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:24Z"} -{"cache_key":"3a3087543c4f5b0648ff7fc2645ae4cf40a2f985a95b29227569f1d421fab438","segment_id":"index.md:19525ac5e5b9c476","source_path":"index.md","text_hash":"19525ac5e5b9c476b36a38c5697063e37e8fe2fae8ef6611f620def69430cf74","text":"Canvas host","translated":"Canvas 主机","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:06Z"} -{"cache_key":"3aa380273cd8edfdd5f5b29a07a527e398f72e5526104fe71ae89a782551ca9e","segment_id":"help/index.md:8ddb7fc8a87904de","source_path":"help/index.md","text_hash":"8ddb7fc8a87904dedc2afc16400fbe4e78582b302e01c30b1319c8a465d04684","text":"Troubleshooting:","translated":"故障排除:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:14Z"} -{"cache_key":"3aa6384989e1547147163565da676d20d7c8194489e7a36036790d562a12ac49","segment_id":"index.md:f3047ab42a6a5bbf","source_path":"index.md","text_hash":"f3047ab42a6a5bbf164106356fa823ecada895064120c4e5a30e1f632741cc5f","text":"Web surfaces","translated":"Web 界面","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:11Z"} -{"cache_key":"3b073a8aca3cde51037eb2b555734543d6c8e5d498f8533174f1eb9496fc894d","segment_id":"environment.md:frontmatter:read_when:1","source_path":"environment.md:frontmatter:read_when:1","text_hash":"a3a2d99a99de98220c8e0296d6f4e4b2a34024916bd2379d1b3b9179c8fae46f","text":"You are debugging missing API keys in the Gateway","translated":"你正在调试 Gateway 中缺失的 API 密钥","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:45Z"} -{"cache_key":"3b0bba02beb661f8e7cf1069121bbd16a281b73b7a5a0c4447beb270d19cfa37","segment_id":"environment.md:b4736422e64c0a36","source_path":"environment.md","text_hash":"b4736422e64c0a369663d1b2d386f1b8f4b31b8936b588e4a54453c61a24e0fd","text":"Process environment","translated":"进程环境","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:20Z"} -{"cache_key":"3b1145589cf333c443556a480ae2d7f03f2014b1e8941d78e2bc2c9c128af7e4","segment_id":"start/wizard.md:c5c46554cb43b7f8","source_path":"start/wizard.md","text_hash":"c5c46554cb43b7f83f3e8fc3be0ad1f0370946ec6e0a19a114d9bab8a127947a","text":"OAuth credentials live in ","translated":"OAuth 凭据存储在 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:29Z"} -{"cache_key":"3b357b9dda6a24f40882977ca076c8800b43c2eae6f4cd8cbef8aa0f129fdc06","segment_id":"environment.md:b79606fb3afea5bd","source_path":"environment.md","text_hash":"b79606fb3afea5bd1609ed40b622142f1c98125abcfe89a76a661b0e8e343910","text":" config","translated":" 配置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:59Z"} -{"cache_key":"3b40d9da2852e7fbd97da9ba5dffbd04f5d5c0fc00def960a206e2c94914b245","segment_id":"index.md:8fdfb6437318756c","source_path":"index.md","text_hash":"8fdfb6437318756c950bf2261538f06236e36040986891fa7b43452b987fb9f3","text":" — an AI, probably high on tokens","translated":" — 一个可能被令牌冲昏头脑的 AI","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:05:47Z"} -{"cache_key":"3b71135c0933181aa6bde7a58dd5a3707209324d5e2168571e948b9b5f2d67e8","segment_id":"index.md:15cd10b29ec14516","source_path":"index.md","text_hash":"15cd10b29ec1451670b80eae4b381e26e84fa8bdb3e8bea90ec943532411b189","text":" (@Hyaxia, ","translated":" (@Hyaxia, ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:44Z"} -{"cache_key":"3b738961b879475be2f5ff57712c2c1bf8bd3060d1cf15dbf5426794d16203b9","segment_id":"start/wizard.md:228b0332ec267772","source_path":"start/wizard.md","text_hash":"228b0332ec267772e57c8b59f1e9e3464839a76a98fc7bf9ba4b9a4509a1d2ff","text":" (defaults) vs ","translated":" (默认设置)与 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:37Z"} -{"cache_key":"3b75f262948cbbb512b4599733ba93e13681e31c930bbdc664ab71e885662b2e","segment_id":"environment.md:77ee4c8d363762a8","source_path":"environment.md","text_hash":"77ee4c8d363762a834617dcf68d6288847eba4544071d9e11e42cf8d08c579d6","text":"Shell env","translated":"Shell 环境","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:34Z"} -{"cache_key":"3b8197284023245c9a413e63d82ca9df26e860990475095d8c3bba3a2ea3cf3c","segment_id":"index.md:2a6b24ad28722034","source_path":"index.md","text_hash":"2a6b24ad287220345e96eb8021fe29d42b0785766c8df658827e7251da2d36dc","text":"Credits","translated":"致谢","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:05:50Z"} -{"cache_key":"3bb189a0fee15a008f7403303c01b5afa61f2762fbe8f30fb11a0b88c64d50ec","segment_id":"environment.md:668e5590b5bb9990","source_path":"environment.md","text_hash":"668e5590b5bb9990eeb25bf657f7d17281a4c613ee4442036787cd4b2efd22bb","text":"If the config file is missing entirely, step 4 is skipped; shell import still runs if enabled.","translated":"如果配置文件完全缺失,步骤 4 将被跳过;如果已启用,shell 导入仍会运行。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:11:43Z"} -{"cache_key":"3be0ad5ba6125bd8e82b0ef3fe5ce52ac6e8cc36295f873bb4eeb53295a493d7","segment_id":"environment.md:f6b2ffe1d0d5f521","source_path":"environment.md","text_hash":"f6b2ffe1d0d5f521b76cabc67d6e96da2b1170eef8086d530558e9906a7f092d","text":"Models overview","translated":"模型概览","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:26:42Z"} -{"cache_key":"3c2f6b5fb86a0b339fef1dce671429b0675d7f6c8e96131c14ae045e330c64ad","segment_id":"index.md:185beb968bd1a81d","source_path":"index.md","text_hash":"185beb968bd1a81d07ebcf82376642f7b29f1b5594b21fe9edee714efbdcaa44","text":"✈️ ","translated":"✈️ ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:55Z"} -{"cache_key":"3c3837312bb9e8d810155bdffa548dbde797f82ff7edf8ac411825656a304c4a","segment_id":"start/wizard.md:6f75d6dfebf55cc4","source_path":"start/wizard.md","text_hash":"6f75d6dfebf55cc4d7cb48ee42a6c6bc47c6bcd606f0dbbc145913b7854d46fd","text":"What it sets:","translated":"它会设置:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:46:55Z"} -{"cache_key":"3c7d5d086025aacdb08eff6300599c7eb8133d3becbaefcf7fac34ff2d733860","segment_id":"index.md:468886872909c70d","source_path":"index.md","text_hash":"468886872909c70d3bfb4836ec60a6485f4cbbd0f8a0acedbacb9b477f01a251","text":"Workspace templates","translated":"工作区模板","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:46Z"} -{"cache_key":"3c85fd86ca15e8381d7fe82eaffa4dbc27dd63f820415f9a09be673d0847aff8","segment_id":"start/wizard.md:48ced72d53b97892","source_path":"start/wizard.md","text_hash":"48ced72d53b9789268649241dadbca3f8646867df4eef54f7eadac8c1c6cefc0","text":"Reset uses ","translated":"重置使用 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:24Z"} -{"cache_key":"3ce65ae798c705018325eadd2d993e1a9b4bd37081ac208ecec458bb23cd1ad2","segment_id":"start/wizard.md:bb1547f6c875dff6","source_path":"start/wizard.md","text_hash":"bb1547f6c875dff692cde4cb57350780c86b3129399197067c8b5e0fc5a90df3","text":": no auth configured yet.","translated":":暂不配置认证。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:19Z"} -{"cache_key":"3cf8f452fc7a0bba84fdf6434ebeb287af7b726270c145cf753b4fe8bd082ee2","segment_id":"start/getting-started.md:f2e04e77070557f1","source_path":"start/getting-started.md","text_hash":"f2e04e77070557f154fb52bb7c75bf115d8981374d0dccc6027944b70bc6951b","text":" on the gateway host.\nDocs: ","translated":" (在 Gateway 主机上)。\n文档: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:37Z"} -{"cache_key":"3d1656dbb878ef3bcba5b41e9ed57f4ce9c7f8963181f68a2fe1752a5e2e1c17","segment_id":"index.md:b0d125182029e6c5","source_path":"index.md","text_hash":"b0d125182029e6c500cbcc81011341df77de8fe24d9e80190c32be390c916ec2","text":"🤖 ","translated":"🤖 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:23Z"} -{"cache_key":"3d568ffb6b3b3d75349d653870affc28760361ff6599283374c4c7864f706f2d","segment_id":"index.md:2a6b24ad28722034","source_path":"index.md","text_hash":"2a6b24ad287220345e96eb8021fe29d42b0785766c8df658827e7251da2d36dc","text":"Credits","translated":"致谢","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:27Z"} -{"cache_key":"3d6a0cbc582dcbd551bd16cae84dfe04310466d13179af3d43e3a05493bbe1b4","segment_id":"index.md:10bf8b343a32f7dc","source_path":"index.md","text_hash":"10bf8b343a32f7dc01276fc8ae5cf8082e1b39c61c12d0de8ec9b596e115c981","text":"WebChat","translated":"网页聊天","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:04:41Z"} -{"cache_key":"3de4148817a3da24501b46c0db8c9432af68e4c926bfbb22af9a5310629c6f3c","segment_id":"index.md:3d8fed7c358b2ccf","source_path":"index.md","text_hash":"3d8fed7c358b2ccf225ee16857a0bb9b950fd414319749e0f6fff58c99fa5f22","text":"Subscription auth","translated":"订阅认证","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:16Z"} -{"cache_key":"3df33562454535183c5399ca80fa7d2817a4a79760aaa5230f128a95d3c78827","segment_id":"environment.md:3fe738a7ee6aaff5","source_path":"environment.md","text_hash":"3fe738a7ee6aaff51f099d9a8314510c99ced6a568eb38c67642cd43bb54eec0","text":" in the current working directory","translated":" 在当前工作目录中","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:32Z"} -{"cache_key":"3df86b9cf5fa329e474cd1383be56b18a77ca9f34aee7679099cf0a67853f799","segment_id":"start/wizard.md:ccc02bfc6371f274","source_path":"start/wizard.md","text_hash":"ccc02bfc6371f2743a3ab2ffd360c100414415a0b4c0f5fe6866820d50a58534","text":"Port, bind, auth mode, tailscale exposure.","translated":"端口、绑定、认证模式、Tailscale 暴露。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:56Z"} -{"cache_key":"3e19ae8f54b98c209753f915d52f542a7891896d7769f2f2e5ff828bfc49a093","segment_id":"start/wizard.md:7cecbbd299f4893d","source_path":"start/wizard.md","text_hash":"7cecbbd299f4893d61d339700773335a412ab1b532b435cd1aa290ab59e6391d","text":"Runtime selection:","translated":"运行时选择:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:45:30Z"} -{"cache_key":"3e685aee1a7051e665e054c4c774e80e188dc239d3df8193efef4838ae204fa8","segment_id":"environment.md:45ca56d179d4788c","source_path":"environment.md","text_hash":"45ca56d179d4788c55ba9f7653b376d62e7faa738e92259e3d4f6f5c1b554f28","text":"Related","translated":"相关内容","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:26:36Z"} -{"cache_key":"3e8225ab0a25cbca0c7a00bcb9033a5048108adac44a721f7249845d0925250c","segment_id":"index.md:4eb58187170dc141","source_path":"index.md","text_hash":"4eb58187170dc14198eacb534c8577bef076349c26f2479e1f6a2e31df8eb948","text":" — An AI, probably high on tokens","translated":" —— 一个可能被令牌冲昏头脑的 AI","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:55:04Z"} -{"cache_key":"3ec7dfcb17b352e2f217472e109e171fc287a2ee9197f39225034144554575e9","segment_id":"index.md:1a36bded6916228a","source_path":"index.md","text_hash":"1a36bded6916228a5664c8b2bcdaa5661d342fe3e632aa41453f647a3daa3a61","text":" — Pairs as a node and exposes a Canvas surface","translated":" —— 作为节点配对并暴露 Canvas 界面","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:12Z"} -{"cache_key":"3ecb8e3215b8818241e73a7e7ae26b1e5202a5384c8f99a2a5262d3bf88112e9","segment_id":"start/wizard.md:4fa6e54efd518fc2","source_path":"start/wizard.md","text_hash":"4fa6e54efd518fc2075e98b366621a5236355222198b8eac9efb802d681fcb8b","text":"Moonshot (Kimi K2)","translated":"Moonshot (Kimi K2)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:08Z"} -{"cache_key":"3f05d1942b5a9f6420ad25aea5697d040ea0fbe5470a1eed26a88ce86d2411af","segment_id":"index.md:f0a7f9d068cb7a14","source_path":"index.md","text_hash":"f0a7f9d068cb7a146d0bb89b3703688d690ed0b92734b78bcdb909aace617dbf","text":"WhatsApp group messages","translated":"WhatsApp 群组消息","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:04:56Z"} -{"cache_key":"3f27b3739c14942d3690e2325aa7381daf6a48d6732f3a116817bcbc3afe9a7e","segment_id":"index.md:36ddb4d3cfcb494f","source_path":"index.md","text_hash":"36ddb4d3cfcb494fb96463d42b35ba923731677cfc9e084af9f25e3f231187d5","text":"💬 ","translated":"💬 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:16Z"} -{"cache_key":"3f7a224f3597d7d8ffcb2fbad1804c6beb71966d8a12feeb601f0607121b1d58","segment_id":"environment.md:cda454f61dfcac70","source_path":"environment.md","text_hash":"cda454f61dfcac7007a9edc538f9f58cf38caa0652e253975979308162bccc53","text":"Gateway configuration","translated":"Gateway 配置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:26:38Z"} -{"cache_key":"4009762bd6b11f2939c149dc1407c26b61e0ce9e64027f643467f2c9166ae069","segment_id":"index.md:ded906ea94d05152","source_path":"index.md","text_hash":"ded906ea94d0515249f0bcab1ba63835b5968c142e9c7ea0cb6925317444d98c","text":"Configuration examples","translated":"配置示例","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:01Z"} -{"cache_key":"4009d09aa8998e8257bb7d745d298f61d59560b852c09e3020f282f5f783755f","segment_id":"environment.md:4ac8551788fee477","source_path":"environment.md","text_hash":"4ac8551788fee477927fdee76e727261e4a655609502f2d6e0f2121b606ed978","text":"Env var substitution in config\n\nYou can reference env vars directly in config string values using ","translated":"配置中的环境变量替换\n\n你可以使用以下方式在配置字符串值中直接引用环境变量 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:58Z"} -{"cache_key":"4009d3c80d649dec28c2565eee518b693691a79c583c891076d67e01740b29f5","segment_id":"index.md:6fa3cbf451b2a1d5","source_path":"index.md","text_hash":"6fa3cbf451b2a1d54159d42c3ea5ab8725b0c8620d831f8c1602676b38ab00e6","text":"Sessions","translated":"会话","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:30Z"} -{"cache_key":"409cb7ef4fb0281a4a1a5cc53af8948139bd4735bddf8b050a93a62498745c6c","segment_id":"start/getting-started.md:0d3a30eb74e2166c","source_path":"start/getting-started.md","text_hash":"0d3a30eb74e2166c1fc51b99b180841f808f384be53fe1392cecb67fdc9363c4","text":" (default ","translated":" (默认 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:19Z"} -{"cache_key":"40e9b8fba7f586d8cd09924e5319af4d3402b2768f2965141866fc0113a5a85a","segment_id":"start/getting-started.md:a930fff865d3a7d8","source_path":"start/getting-started.md","text_hash":"a930fff865d3a7d8c09c82d884ce158733e3cf93f6d43d81c03785aeb15ff970","text":"7) Verify end-to-end","translated":"7)端到端验证","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:55Z"} -{"cache_key":"413b18be7bd7219a7ebe8bf16cc6b2a5151753b15628b92ef08461ee654bd44b","segment_id":"environment.md:6863067eb0a2c749","source_path":"environment.md","text_hash":"6863067eb0a2c7499425c6c189b2c88bac55ca754285a6ab1ef37b75b4cfad4d","text":"See ","translated":"参见 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:17:03Z"} -{"cache_key":"41768ab6d5c2eeb79122a8d917d38fdc9d8448e4ed992fcb2b7feaa905469dcf","segment_id":"index.md:add4778f9e60899d","source_path":"index.md","text_hash":"add4778f9e60899d7f44218483498c0baf7a0468154bc593a60747ee769c718c","text":"Android node","translated":"Android 节点","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:02:40Z"} -{"cache_key":"417f7a16c5b26835f5787b2bc94c938dba0e43717380c38007d621ec582c8c21","segment_id":"start/getting-started.md:fc0d3588a29e2b90","source_path":"start/getting-started.md","text_hash":"fc0d3588a29e2b90f3946e210636d98d8ad95cf9e9d615fd975193093d8a17df","text":" (with sane defaults) as quickly as possible.","translated":" (使用合理的默认配置)尽可能快地完成。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:32Z"} -{"cache_key":"418f62c195d775d18091feee2ea101a738425ab091aecd5487195cfedd3ede3f","segment_id":"start/getting-started.md:b8aa19c1dd24f84e","source_path":"start/getting-started.md","text_hash":"b8aa19c1dd24f84eb71288bebd10a4e6007ede5365d9572df511fe428dccb632","text":"macOS menu bar app + voice wake: ","translated":"macOS 菜单栏应用 + 语音唤醒: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:21Z"} -{"cache_key":"41a9cde6dd29d317206f7b9ac006217c8ed29fdfa51d9cdc8b3aa4538ccd4415","segment_id":"start/wizard.md:a2198f472ce2fbee","source_path":"start/wizard.md","text_hash":"a2198f472ce2fbee82a5546090a5dd896b1da3bb678e8963d19eaa03e08ca092","text":"Onboarding","translated":"上手引导","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:49:05Z"} -{"cache_key":"420151a42113aa101a8d753080c801abe7deac20cde27edca350833dba6b9401","segment_id":"index.md:496bcd8a502babde","source_path":"index.md","text_hash":"496bcd8a502babde0470e7105dfed7ba95bbc3193b7c6ba196b3ed0997e84294","text":"Voice notes","translated":"语音消息","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:43Z"} -{"cache_key":"42363d142c5d5a1481ac3bb76aba070baba3e796a68efaac422608091bf9f72f","segment_id":"index.md:bbf8779fd9010043","source_path":"index.md","text_hash":"bbf8779fd9010043ac23a2f89ba34901f3a1f58296539c3177d51a9040ea209d","text":") — Blogwatcher skill","translated":")—— Blogwatcher 技能","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:47Z"} -{"cache_key":"42b861c7e5700483f345ddd4ae743bc47dbd0154e1a83326aae343859604bf6d","segment_id":"start/wizard.md:ecaaafe56fbfdf19","source_path":"start/wizard.md","text_hash":"ecaaafe56fbfdf19c4710b2509350b60bf5bce327e6e621952076da6372df33e","text":"Onboarding Wizard (CLI)","translated":"上手引导向导 (CLI)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:56Z"} -{"cache_key":"42ee1c8c7830b05cc1959ca709737c56bd2f92aff2ccf44de3dc51badc42622f","segment_id":"index.md:32ebb1abcc1c601c","source_path":"index.md","text_hash":"32ebb1abcc1c601ceb9c4e3c4faba0caa5b85bb98c4f1e6612c40faa528a91c9","text":" (","translated":" (","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:15Z"} -{"cache_key":"433cce86c05f0e0152efd90e723b067d686e917fb2054327fbf4ce5c40e30edb","segment_id":"start/wizard.md:13297db73d234731","source_path":"start/wizard.md","text_hash":"13297db73d234731958244575f85555e4aa3ff0aed3b07b5e9d4ea66cb462246","text":" (never ","translated":" (绝不使用 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:26Z"} -{"cache_key":"434e8917d28683bf448e8aabf49764186bb067e2efe6ff332497cb52f6016ddd","segment_id":"start/getting-started.md:7013af4c42fe4380","source_path":"start/getting-started.md","text_hash":"7013af4c42fe43802a9e8b0affc4f521fcd126160569969fb2ec09e1b7c422b1","text":"Setup","translated":"设置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:10Z"} -{"cache_key":"436e752948ac7b7910f23cae9160a2e4040fb7df0e3c5bfb95398c280e3e3f41","segment_id":"index.md:1a36bded6916228a","source_path":"index.md","text_hash":"1a36bded6916228a5664c8b2bcdaa5661d342fe3e632aa41453f647a3daa3a61","text":" — Pairs as a node and exposes a Canvas surface","translated":" — 作为节点配对并提供 Canvas 界面","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:02:38Z"} -{"cache_key":"4375f1f048f79fc861b543d3d9c0eedc69b7a772a32d024e3c108d3a9657af00","segment_id":"start/wizard.md:95fcce5e5b146818","source_path":"start/wizard.md","text_hash":"95fcce5e5b146818ba279f6a1ec9b3333532b069ad6e3f709818fb9194198203","text":"Keep / Modify / Reset","translated":"保留 / 修改 / 重置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:07Z"} -{"cache_key":"43cec56f6386efc26fbdda3820971f35c6a6df2c61a3125ef10c41b7a136e622","segment_id":"environment.md:frontmatter:read_when:1","source_path":"environment.md:frontmatter:read_when:1","text_hash":"a3a2d99a99de98220c8e0296d6f4e4b2a34024916bd2379d1b3b9179c8fae46f","text":"You are debugging missing API keys in the Gateway","translated":"你正在调试 Gateway 中缺失的 API 密钥","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:19:16Z"} -{"cache_key":"444c57554dc319fcc9cbfb96353a6f9c9184b4e1178353c5f92496ac99bf75b7","segment_id":"start/wizard.md:bdd5d35746968e3a","source_path":"start/wizard.md","text_hash":"bdd5d35746968e3ac912679a8a6dcd53117277e63feb28c474e582f2ada39027","text":") for scripts.","translated":")用于脚本。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:54Z"} -{"cache_key":"447176b9f6dcf6f83e411888711e6f57498e9034a0000a9e5e08b8600dfa6dd7","segment_id":"help/index.md:frontmatter:read_when:1","source_path":"help/index.md:frontmatter:read_when:1","text_hash":"857eafc389d179e83e21e46c10527fec40894fe064c63847ba06b946b7d5eb73","text":"Something broke and you want the fastest path to a fix","translated":"出了问题,你想找到最快的修复方法","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:24:30Z"} -{"cache_key":"45546bd54f25fcf7ebb35e346b789c2b8719664b05396941839eaa13d1181f5b","segment_id":"start/wizard.md:17c51cc78838cf2a","source_path":"start/wizard.md","text_hash":"17c51cc78838cf2af11aab8d6600db56cb50d4956069625db25bed4f15656a76","text":" (bun not recommended).","translated":" (不推荐 bun)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:45:52Z"} -{"cache_key":"455bca70dc67fd7daf15f2991ae1dde159fbb072397a5222ae919e12c89f6baf","segment_id":"help/index.md:frontmatter:read_when:0","source_path":"help/index.md:frontmatter:read_when:0","text_hash":"ee0615553374970664b58ebd8e5d0ebc9bc8a5f03387671afbfd0096b390aa9b","text":"You’re new and want the “what do I click/run” guide","translated":"你是新手,想要一份\"该点什么/该运行什么\"的操作指南","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:03Z"} -{"cache_key":"46356e773d9a1db34290e9332db52f9febdea4d6a86073399c8e5123a8c85d64","segment_id":"index.md:233cfad76c3aa9dd","source_path":"index.md","text_hash":"233cfad76c3aa9dd5cc0566746af197eac457a88c1e300ae788a8ada7f96b383","text":"From source (development):","translated":"从源码安装(开发):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:35Z"} -{"cache_key":"463a9a24eff5d3e3bd5240375798cafd0b6ddd708cb14e1037df77f591649f17","segment_id":"index.md:96be070791b7d545","source_path":"index.md","text_hash":"96be070791b7d545dc75084e59059d2170eed247350b351db5330fbd947e4be6","text":"👥 ","translated":"👥 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:02:04Z"} -{"cache_key":"467ace4c6c3c4e0032589ea19c3968e8869d0455ecde033420ea7e300959f288","segment_id":"help/index.md:2adc964c084749b1","source_path":"help/index.md","text_hash":"2adc964c084749b1f2d8aef24030988b667dbda2e38a6a1699556c93e07c1cea","text":"Start here","translated":"从这里开始","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:39:37Z"} -{"cache_key":"46bb3d229c815e2177cb4c1493857143b306b58d15abedb7abce66c9c5456f99","segment_id":"start/wizard.md:a9e83abe07e4c277","source_path":"start/wizard.md","text_hash":"a9e83abe07e4c2777f28ac3107308bd9178e7d0449fbf21f2098ebd37f17900e","text":" exposes every step (mode, workspace, gateway, channels, daemon, skills).","translated":" 展示每个步骤(模式、工作区、Gateway、渠道、守护进程、技能)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:09Z"} -{"cache_key":"47add7d7379785e56a63fec4ac7e41913e1c0bb8b25f6e8bb10ccbdae56f993d","segment_id":"start/wizard.md:254bb97b57f12e16","source_path":"start/wizard.md","text_hash":"254bb97b57f12e1608fefc4517de768427b2fd6d2cffbbfcbc09f3c818198d5f","text":"not","translated":"不会","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:39Z"} -{"cache_key":"47b5e5abc15bd0ac60233ab1d3fd967912accfa1934f36be76175302f173c24f","segment_id":"index.md:d53b75d922286041","source_path":"index.md","text_hash":"d53b75d9222860417f783b0829023b450905d982011d35f0e71de8eed93d90fc","text":"New install from zero:","translated":"从零开始全新安装:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:03Z"} -{"cache_key":"47e2cb719ca381b76b3e6b9692535fac0878a4d7dfface5796952396f9dbac0c","segment_id":"environment.md:45ca56d179d4788c","source_path":"environment.md","text_hash":"45ca56d179d4788c55ba9f7653b376d62e7faa738e92259e3d4f6f5c1b554f28","text":"Related","translated":"相关内容","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:19:49Z"} -{"cache_key":"47eeb5089f41d7da1014dffd88b45418309ad1273076ad53cad090d98d2cab0e","segment_id":"index.md:c7a5e268ddd8545e","source_path":"index.md","text_hash":"c7a5e268ddd8545e5a59a58ef1365189862f802cc7b61d4a3212c70565e2dff1","text":"WhatsApp Integration","translated":"WhatsApp 集成","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:50Z"} -{"cache_key":"48150c58a558cab37782c3ad92d481228e2baf17c9b76c6779b7c0ae19dbc3fa","segment_id":"index.md:e3572f8733529fd3","source_path":"index.md","text_hash":"e3572f8733529fd30a8604d41d624c15f4433df68f40bd092d1ee61f7d8d15e2","text":"Agent bridge","translated":"智能体 桥接","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:00Z"} -{"cache_key":"48483fc19877be4aa74fb6b2db7bb89e26c2c0e369d74946891db59c9fe7e7a6","segment_id":"help/index.md:6201111b83a0cb5b","source_path":"help/index.md","text_hash":"6201111b83a0cb5b0922cb37cc442b9a40e24e3b1ce100a4bb204f4c63fd2ac0","text":" and ","translated":" 和 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:56:37Z"} -{"cache_key":"4860a152d07b27cce8b414a96db2ae930f930f6c1c92cd682b9138e2a05cd6a5","segment_id":"index.md:a42f01be614f75f1","source_path":"index.md","text_hash":"a42f01be614f75f16278b390094dc43923f0b1b7d8e3209b3f43e356f42ed982","text":"), a single long-running process that owns channel connections and the WebSocket control plane.","translated":"),一个拥有 渠道 连接和 WebSocket 控制平面的单一长期运行进程。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:26Z"} -{"cache_key":"49557226fca3cfad19539dc5025d8556c1fbbc8f281440f95e52b12f86ea9c88","segment_id":"index.md:9bcda844990ec646","source_path":"index.md","text_hash":"9bcda844990ec646b3b6ee63cbdf10f70b0403727dea3b5ab601ca55e3949db9","text":" for node WebViews; see ","translated":" 用于节点 WebView;参见 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:29Z"} -{"cache_key":"495b27e9a0d8f141e73a810d800212340f9cbde9181f0f2d3fba03b48222976e","segment_id":"start/getting-started.md:b2727b53f573e590","source_path":"start/getting-started.md","text_hash":"b2727b53f573e590241952b2f1c4f4a0654a6c54c5407a1ac4a98c7360808b66","text":"3) Start the Gateway","translated":"3)启动 Gateway","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:47Z"} -{"cache_key":"496b2bcf0dbcf94d1b9bb3678101118c4ea49b1513f09378ba37b8c963882d15","segment_id":"index.md:41ed52921661c7f0","source_path":"index.md","text_hash":"41ed52921661c7f0d68d92511589cc9d7aaeab2b5db49fb27f0be336cbfdb7df","text":"Gateway","translated":"Gateway","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:47Z"} -{"cache_key":"4981d5c52ef98c93d181d87e1c2a1b8f6f862ebdb561c1be294d9137b2bb57b7","segment_id":"environment.md:b4736422e64c0a36","source_path":"environment.md","text_hash":"b4736422e64c0a369663d1b2d386f1b8f4b31b8936b588e4a54453c61a24e0fd","text":"Process environment","translated":"进程环境","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:59Z"} -{"cache_key":"49dba5d103054704ee4f938bc0a88e03d008f4944cb8cbae4a2885436d4740b2","segment_id":"start/wizard.md:c50ee45a8653de1c","source_path":"start/wizard.md","text_hash":"c50ee45a8653de1c4e2b19fb99d694cd339660b20d45c9ad30ee141b6606057e","text":"Gemini example:","translated":"Gemini 示例:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:47:20Z"} -{"cache_key":"4a98bbd6c4054f0b1a001141baff967905b1b14e1df3098677fc0e4d18ed325e","segment_id":"start/getting-started.md:2a6201c0c58ab546","source_path":"start/getting-started.md","text_hash":"2a6201c0c58ab546acacc4a77ca5dc80df9b0dd17abb7295095a6f17fe009dbe","text":" Brave Search API key for web search. Easiest path:","translated":" Brave Search API 密钥用于网络搜索。最简单的方式:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:31Z"} -{"cache_key":"4af220d89881b4bb625e5c2da4f6f1f1fcf9aa5e03c3d011a1719e95425b74ff","segment_id":"start/getting-started.md:3e86911991b89a88","source_path":"start/getting-started.md","text_hash":"3e86911991b89a88840294cff2374b6c01b6cf699d67a683d93176713ba4ca45","text":"Auth: where it lives (important)","translated":"认证:存储位置(重要)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:28Z"} -{"cache_key":"4bec757cc889c702c6234b140f6cfbd9f5667bc8d4c2ec078d752ca526c9799e","segment_id":"index.md:a42f01be614f75f1","source_path":"index.md","text_hash":"a42f01be614f75f16278b390094dc43923f0b1b7d8e3209b3f43e356f42ed982","text":"), a single long-running process that owns channel connections and the WebSocket control plane.","translated":"),一个拥有 渠道 连接和 WebSocket 控制平面的单一长期运行进程。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:49Z"} -{"cache_key":"4bf4e999ff90d118298d53d27c867bde5d3a64a39602eb35773dcd473ab68055","segment_id":"index.md:eec70d1d47ec5ac0","source_path":"index.md","text_hash":"eec70d1d47ec5ac00f04e59437e7d8b0988984c0cea3dddd81b1a2a10257960b","text":" — DMs + groups via grammY","translated":" — 通过 grammY 支持私信和群组","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:00Z"} -{"cache_key":"4c71126fdff0651fcaa439a12703ba33c43aa85a462fb7e2ad6acee8a8806c39","segment_id":"start/wizard.md:ddbd2d8bfe478133","source_path":"start/wizard.md","text_hash":"ddbd2d8bfe4781330c0adb796efa7fa7dcfb17d1fe9ed4307b023d66d8b8a35b","text":"OpenAI Code (Codex) subscription (OAuth)","translated":"OpenAI Code (Codex) 订阅 (OAuth)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:16Z"} -{"cache_key":"4c7a9d32a1bf7d55704300dc5899e3919b0f6bab738e60b30fc1fd85b58ede3a","segment_id":"start/getting-started.md:6d6dc68f9728c111","source_path":"start/getting-started.md","text_hash":"6d6dc68f9728c11122ce7459d5576d5302c97ec8e74870cb9c77db41f5c6ea0c","text":"Hetzner","translated":"Hetzner","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:41Z"} -{"cache_key":"4c851cab8cf02e3da31b63c083417b0bbd5a3d717405b1b27a0350415de4bd27","segment_id":"index.md:f0b349e90cb60b2f","source_path":"index.md","text_hash":"f0b349e90cb60b2f96222d0be1ff6532185f385f4909a19dd269ea3e9e77a04d","text":" (default); groups are isolated","translated":" (默认);群组是隔离的","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:02:01Z"} -{"cache_key":"4c93f44aa6a225228511440a8cca2a4ace485159eddb0d79727da03e98fefe9a","segment_id":"start/getting-started.md:a39d4188dfd32498","source_path":"start/getting-started.md","text_hash":"a39d4188dfd324984cf06e58ae8585aace52bc88d8a2a1f1e50b6fb1aca38f14","text":") asks the running gateway for a health snapshot.","translated":")向运行中的 Gateway 请求健康快照。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:13Z"} -{"cache_key":"4ccc6938b93e67b302401a1553a3b4331bae277f3b0cfbbd2221b77525949cd4","segment_id":"environment.md:f0442e6e05ccca16","source_path":"environment.md","text_hash":"f0442e6e05ccca160d17de0e7d509891b91b921366b2202b2b5c80435824e140","text":"Two equivalent ways to set inline env vars (both are non-overriding):","translated":"两种等效的内联环境变量设置方式(均为非覆盖模式):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:22:14Z"} -{"cache_key":"4cd593beb8d08acfb2a74edb256d16cd121e7ebd888e8d0569d819d6342f2d08","segment_id":"index.md:eef0107bb5a4e06b","source_path":"index.md","text_hash":"eef0107bb5a4e06b9de432b9e62bcf1e39ca5dfbbb9cb0cc1c803ca7671c06ab","text":"Gateway runbook","translated":"Gateway 运维手册","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:21Z"} -{"cache_key":"4d021d4ad8d2c4a6fa14ffae3a5273c55c88fa764c804d0ac7eb7877b3fd2e01","segment_id":"help/index.md:d3ef01b4a9c99103","source_path":"help/index.md","text_hash":"d3ef01b4a9c9910364c9b26b2499c8787a0461d2d24ab80376fff736a288b34c","text":"Logging","translated":"日志记录","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:44:50Z"} -{"cache_key":"4d31d3ef5331e6d1f9320391fae45b77e325f6e87ea39857dc34442559cccc01","segment_id":"index.md:0a4a282eda1af348","source_path":"index.md","text_hash":"0a4a282eda1af34874b588bce628b76331fbe907de07b57d39afdedccac2ba14","text":" http://127.0.0.1:18789/ (or http://localhost:18789/)","translated":" http://127.0.0.1:18789/(或 http://localhost:18789/)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:22Z"} -{"cache_key":"4d326b31ff8fc72fd166492afe47b0ae7beb5e3e5bf37baabdd302879d9c1d13","segment_id":"help/index.md:40281c54411735d1","source_path":"help/index.md","text_hash":"40281c54411735d1d2e4ffec7e0efc19ba0503751fa1d7358274b912604d1510","text":" broke”):","translated":" 问题\"):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:03Z"} -{"cache_key":"4daabe9de281d8ebea0b454d9bdc3fdb736a9eb954b51489ad1deb7ed2a4373c","segment_id":"index.md:ceee4f2088b9d5ba","source_path":"index.md","text_hash":"ceee4f2088b9d5ba7d417bac7395003acfbcef576fd4cc1dd3063972f038218a","text":"The name","translated":"名称","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:05:36Z"} -{"cache_key":"4db63f686185284d522be3518e148ebe548c53eb4626b6f1a02f052a09c301e9","segment_id":"index.md:11d28de5b79e3973","source_path":"index.md","text_hash":"11d28de5b79e3973f6a3e44d08725cdd5852e3e65e2ff188f6708ae9ce776afc","text":"Docs hubs (all pages linked)","translated":"文档中心(所有页面链接)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:15Z"} -{"cache_key":"4dd121c0efe15d606d29bd4960aa7aabaf0e999980bb6270b1088c55c742f415","segment_id":"help/index.md:6cb77499abdccd9a","source_path":"help/index.md","text_hash":"6cb77499abdccd9a2dbb7c93a4d31eed01613dda06302933057970df9ecdeb54","text":"Logs:","translated":"日志:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:26Z"} -{"cache_key":"4de22adc95e4976c28aa9a61533e5641e6fd5b9d045d3767ac21261a2335914c","segment_id":"index.md:9fc31bacba5cb332","source_path":"index.md","text_hash":"9fc31bacba5cb33207804b9e6a8775a3f9521c9a653133fd06e5d14206103e48","text":"Streaming + chunking","translated":"流式传输 + 分块","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:34Z"} -{"cache_key":"4e57e45dbeeb2f49d2f090659de7ad8342eedc7be647e92f8c4bc8947b7d85c6","segment_id":"start/getting-started.md:f07ac0638d44dcaa","source_path":"start/getting-started.md","text_hash":"f07ac0638d44dcaa5d24d65ea8205bd487968cdb28c4b8f55a9f35abf86e9b8e","text":"⚠️ ","translated":"⚠️ ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:59Z"} -{"cache_key":"4e7d8b9522fd7341a086f3de5bf4cd653a1d3446e763918236c087c43964aa4f","segment_id":"index.md:c491e0553683a70a","source_path":"index.md","text_hash":"c491e0553683a70a2fb52303f74675d2f7b725814ed70d5167473cb5fbe46450","text":"@steipete","translated":"@steipete","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:31Z"} -{"cache_key":"4e866938d12c4a92f34a54718f3e47f7cdd902f404e3fd33e5f5222e436f9b36","segment_id":"index.md:0d3a30eb74e2166c","source_path":"index.md","text_hash":"0d3a30eb74e2166c1fc51b99b180841f808f384be53fe1392cecb67fdc9363c4","text":" (default ","translated":" (默认 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:59Z"} -{"cache_key":"4ec0b2d188f9f730e3313959319d7b42ee967cdf4f93ad396f47590a16f996d2","segment_id":"start/wizard.md:71375dd64cd1fd1f","source_path":"start/wizard.md","text_hash":"71375dd64cd1fd1fe95d0263198b7d8e200c0705f4f183d7566aaf5e1f00bfc4","text":"Disable auth only if you fully trust every local process.","translated":"仅在您完全信任每个本地进程时才禁用认证。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:44:06Z"} -{"cache_key":"4f08a9653928ac3ab515e3d4b8ebe742f3dffa74cc24a72a01c96d8fe662140a","segment_id":"start/getting-started.md:e8f6d6288fe468ce","source_path":"start/getting-started.md","text_hash":"e8f6d6288fe468ce32979d08b723300ae13bfaaf0125ad98e9575f34d0135d5d","text":"Goal: go from ","translated":"目标:从 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:23Z"} -{"cache_key":"4f097f10df80b86a3a5591e19d0af1221fb2b938d0357f64ed981c1991f03936","segment_id":"start/wizard.md:f6b7825cb4029a0b","source_path":"start/wizard.md","text_hash":"f6b7825cb4029a0b60d38151752906e4dd2cee98bc62075b9b92745e71b0f3ec","text":" CLI path + DB access.","translated":" CLI 路径 + 数据库访问。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:44:59Z"} -{"cache_key":"4f238e68dde5c2b45bd0c18fb2483c798be3e0fa8d46bf9c1b7b14b5531d21a3","segment_id":"index.md:c4b2896a2081395e","source_path":"index.md","text_hash":"c4b2896a2081395e282313d6683f07c81e3339ef8b9d2b5a299ea5b626a0998f","text":").","translated":")。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:17Z"} -{"cache_key":"4ff9ae69dc48d779b5eab2d7fd9f54be2f2f31d6a7decf258f13342320f148b3","segment_id":"index.md:fb87b8dba88b3edc","source_path":"index.md","text_hash":"fb87b8dba88b3edced028edfe2efa5f884ab2639c1b26efa290ccd0469454d25","text":"Slash commands","translated":"斜杠命令","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:03Z"} -{"cache_key":"503ffef24b84433cfe5c8d4d7593a419616f5f14136cdb38d5cf1cd06b4a9a0e","segment_id":"index.md:0d517afa83f91ec3","source_path":"index.md","text_hash":"0d517afa83f91ec33ee74f756c400a43b11ad2824719e518f8ca791659679ef4","text":"Web surfaces (Control UI)","translated":"Web 界面(控制界面)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:59Z"} -{"cache_key":"5061a49721ce6c55da1a2514b0fd7683f5ce7d1d74f157660f8bd0bfdfe0bf6e","segment_id":"environment.md:1ec31258a6b45ea9","source_path":"environment.md","text_hash":"1ec31258a6b45ea903cd76f5b0190a99ab56afff6241a04f0681eb12b7a02484","text":"Env var equivalents:","translated":"等效的环境变量:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:55Z"} -{"cache_key":"5069b751d3f01eba9ff4cce578a200affed4e5065ca542d65061b2e2a93b8852","segment_id":"help/index.md:frontmatter:read_when:0","source_path":"help/index.md:frontmatter:read_when:0","text_hash":"ee0615553374970664b58ebd8e5d0ebc9bc8a5f03387671afbfd0096b390aa9b","text":"You’re new and want the “what do I click/run” guide","translated":"你是新手,想要一份\"我该点击/运行什么\"的指南","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:08Z"} -{"cache_key":"509d70fe9cd2a784c14c42ef3d0ca4a5767c2fa6959deb7ed3671b4ec368dfe8","segment_id":"help/index.md:frontmatter:read_when:1","source_path":"help/index.md:frontmatter:read_when:1","text_hash":"857eafc389d179e83e21e46c10527fec40894fe064c63847ba06b946b7d5eb73","text":"Something broke and you want the fastest path to a fix","translated":"出了问题,你想要最快的修复方法","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:18:59Z"} -{"cache_key":"50a84870e2aca4cf2eb629a6742293526dcc33fa7910e6ac417b9a604f50960b","segment_id":"start/wizard.md:822369845cd7506f","source_path":"start/wizard.md","text_hash":"822369845cd7506fbdc11a1e2e1410b3c4d56d1b38ce7e0e3ac68132daa3bc41","text":" (mode, bind, auth, tailscale)","translated":" (模式、绑定、认证、Tailscale)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:48:39Z"} -{"cache_key":"50b11cd9357a73a81c5f192b9ffe99a8d3c273a366ff83647c224fb21678c414","segment_id":"index.md:ec05222b3777fd7f","source_path":"index.md","text_hash":"ec05222b3777fd7f91a2964132f05e3cfc75777eaeec6f06a9a5c9c34a8fc3e9","text":"Nix mode","translated":"Nix 模式","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:36Z"} -{"cache_key":"50f4e14d41f688eeb460afe9ad362eb37e693b4ed995b45ee5d9bfaf1fab401b","segment_id":"start/getting-started.md:aa9e63906bb59344","source_path":"start/getting-started.md","text_hash":"aa9e63906bb5934462d7a9f29afd4a9562d5366c583706512cb48dce19c847df","text":"Web tools","translated":"网络工具","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:36Z"} -{"cache_key":"50f8833ee612dd2b521fe352a3b7fdf5c623c2ebbf2a839889a5ce67c5c0e461","segment_id":"help/index.md:5c94724fa7810fa9","source_path":"help/index.md","text_hash":"5c94724fa7810fa9902e565cf66c5f5a973074f2961fcd3a40bad4ee4aeca5e0","text":"If you want a quick “get unstuck” flow, start here:","translated":"如果你想要一个快速的\"解决卡点\"流程,从这里开始:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:19:03Z"} -{"cache_key":"50fd13ae6258975366903d5a2acb0d0b04ce90ba43f94a4d6c7beaca595f7ad2","segment_id":"help/index.md:bfc5930cc2660330","source_path":"help/index.md","text_hash":"bfc5930cc2660330260afd407e98d86adaec0af48dd72b88dc33ef8e9066e2c9","text":"Install sanity (Node/npm/PATH):","translated":"安装健全性检查(Node/npm/PATH):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:24:39Z"} -{"cache_key":"5101decf1454ab8482f88283cdff28292f81cb8c5b67c60c5540d20e58d322c3","segment_id":"start/wizard.md:32e1de6dc8abca82","source_path":"start/wizard.md","text_hash":"32e1de6dc8abca82d76e0f29f7946d2ee7a92d4966b491162f39ccb8a4dd545b","text":": optional QR login.","translated":":可选二维码登录。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:44:21Z"} -{"cache_key":"513ac8bfe713d5e2eb46a1c890b9a73bb5fd37a64fbf5ddd1761b54104f0ce75","segment_id":"index.md:25d853ca04397b6a","source_path":"index.md","text_hash":"25d853ca04397b6ae248036d4d029d19d94a4981290387e5c29ef61b0eca9021","text":"Media: audio","translated":"媒体:音频","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:05:01Z"} -{"cache_key":"5151695b8579a569668c665a07f985e54e47ae59b74de6c35d4eeb91d791b91c","segment_id":"environment.md:87e89abb4c1c551f","source_path":"environment.md","text_hash":"87e89abb4c1c551fe08d355d097f18b8de78edca5f556997085681662fce8eed","text":"Config ","translated":"配置 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:48Z"} -{"cache_key":"5164ecd8153172c108648dc8feef9d627a89b9324d78c60e951e3f1c3af844f2","segment_id":"index.md:bbf8779fd9010043","source_path":"index.md","text_hash":"bbf8779fd9010043ac23a2f89ba34901f3a1f58296539c3177d51a9040ea209d","text":") — Blogwatcher skill","translated":")— Blogwatcher 技能","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:06:21Z"} -{"cache_key":"5190486a1cf97164d85f07222ca6e274b6674eeda169c17a0eccc3c7be43b044","segment_id":"start/wizard.md:c8e1d64e1512e6b8","source_path":"start/wizard.md","text_hash":"c8e1d64e1512e6b81ad317afe04f71cc8ea0fe457ff607c007e34800a6e8e103","text":" keeps the defaults:","translated":" 保留默认设置:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:43Z"} -{"cache_key":"51c65ff267a63fd40e68e63331750ce27c6e882f309e162d6972e537cabf4072","segment_id":"environment.md:453c14128fbfb5f6","source_path":"environment.md","text_hash":"453c14128fbfb5f6757511557132a1dbb3bcbf243267630bfec49db8518c7780","text":"Env var substitution in config","translated":"配置中的 环境变量 替换","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:41:23Z"} -{"cache_key":"51e4a79d50e7b6faf4b5fbce36a1c2dc9d941659190740833308d280cb27a5bb","segment_id":"help/index.md:569ca49f4aaf7846","source_path":"help/index.md","text_hash":"569ca49f4aaf7846e952c1d4aeca72febd0b79fa1c4f9db08fd3127551218572","text":"Install","translated":"安装","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:19Z"} -{"cache_key":"5256dac86be4cff1bbfdd8b43cd74fa2633b518c084db7f691706eedee0e1d77","segment_id":"index.md:6b3f22c979b9e6f8","source_path":"index.md","text_hash":"6b3f22c979b9e6f8622031a6b638ec5f730c32de646d013e616078e03f5a6149","text":"iOS node","translated":"iOS 节点","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:02:35Z"} -{"cache_key":"525b28d219cb06fdcc377d15a5e9c3f60ba1e1169087c1b9ab43b1efe3a8349d","segment_id":"start/wizard.md:d92f3712b6e72ea2","source_path":"start/wizard.md","text_hash":"d92f3712b6e72ea2bac4e633c85d861d9f300aa323fd76c8781a8f56d8a4c009","text":"(configurable).","translated":"(可配置)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:43Z"} -{"cache_key":"5268570b8d2770d6d5f735117d493a2ea8bd09de727afcf860253c47a704ded3","segment_id":"start/getting-started.md:c2ab5611178d6d90","source_path":"start/getting-started.md","text_hash":"c2ab5611178d6d908636cc22a3aed2cb295c4108fc42f754094d3e67505358a6","text":"Recommended:","translated":"推荐:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:28Z"} -{"cache_key":"526b2832980f55051a3a71d889b1300bbb233cd79e79b885d4e785d9114dba2b","segment_id":"environment.md:d08a8493f686363a","source_path":"environment.md","text_hash":"d08a8493f686363a78b913d45ebfbd87a3768d1c77b70f23b1fdade3c066e481","text":"Shell env import","translated":"Shell 环境导入","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:41:12Z"} -{"cache_key":"5275f3af15c7dfcb4b24b60d848e0c9ed11c9e2abf25bc62a2b99a7cab4c7542","segment_id":"index.md:2adc964c084749b1","source_path":"index.md","text_hash":"2adc964c084749b1f2d8aef24030988b667dbda2e38a6a1699556c93e07c1cea","text":"Start here","translated":"从这里开始","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:03Z"} -{"cache_key":"52aeed244ab712fffb8102660391a13fc4a8f9a479605dd7bcbfa4b355c58834","segment_id":"start/wizard.md:8b1d44c58a75ff49","source_path":"start/wizard.md","text_hash":"8b1d44c58a75ff49adca5363a3cbd3e61bfee0645eddb1496b8a6750129b7bc8","text":"Skills: ","translated":"技能: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:49:15Z"} -{"cache_key":"52ef5bab0c525d962f3d30c6cc5f251916fbadf5e697dc633e2ace0ecbbb42c2","segment_id":"start/wizard.md:d80ef914e27a7691","source_path":"start/wizard.md","text_hash":"d80ef914e27a7691f1ed9989a37a43dfd34cfef90ee4459a627bf718954df4a3","text":": config is auto-written.","translated":":配置会自动写入。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:57Z"} -{"cache_key":"531330c3712e720f0c442c71f862e191045a1b8230f18bd10f68e2319bf22155","segment_id":"index.md:468886872909c70d","source_path":"index.md","text_hash":"468886872909c70d3bfb4836ec60a6485f4cbbd0f8a0acedbacb9b477f01a251","text":"Workspace templates","translated":"工作区模板","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:04:23Z"} -{"cache_key":"534402481da76bfd10c88a10c6a4910b6e634bdddd9e419a006b283058cff637","segment_id":"environment.md:f0442e6e05ccca16","source_path":"environment.md","text_hash":"f0442e6e05ccca160d17de0e7d509891b91b921366b2202b2b5c80435824e140","text":"Two equivalent ways to set inline env vars (both are non-overriding):","translated":"两种等效的内联环境变量设置方式(均为非覆盖式):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:19:33Z"} -{"cache_key":"5348f8f12aaa8a00c0f5a88d0cad414c4fe54eaba081f2173b39cbf188125da3","segment_id":"index.md:4eb58187170dc141","source_path":"index.md","text_hash":"4eb58187170dc14198eacb534c8577bef076349c26f2479e1f6a2e31df8eb948","text":" — An AI, probably high on tokens","translated":" — 大概是一个嗑多了 token 的 AI 说的","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:09Z"} -{"cache_key":"53513c3f1d1bda6a78f2c08ae26548a59521cc465217abb5716c816e50b3f663","segment_id":"help/index.md:729bc562eec2658b","source_path":"help/index.md","text_hash":"729bc562eec2658bd11ffdd522fe5277177dc73e86eaca7baac0b472a4d8f8b2","text":"If you’re looking for conceptual questions (not “something broke”):","translated":"如果你在寻找概念性问题的答案(而不是\"出了什么问题\"):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:21:39Z"} -{"cache_key":"5360de70878292f462b4ab63b6b2169dbb4bfcdbb0826892292183e82654a749","segment_id":"help/index.md:569ca49f4aaf7846","source_path":"help/index.md","text_hash":"569ca49f4aaf7846e952c1d4aeca72febd0b79fa1c4f9db08fd3127551218572","text":"Install","translated":"安装","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:56:25Z"} -{"cache_key":"5474cc8e7d4c6f83b601be6d40ebc9282578264e3f75ebf4da637cac7907ed88","segment_id":"index.md:7d8b3819c6a9fb72","source_path":"index.md","text_hash":"7d8b3819c6a9fb726f40c191f606079b473f6f72d4080c13bf3b99063a736187","text":"Ops and safety:","translated":"运维和安全:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:53:45Z"} -{"cache_key":"549c689e9c5183f7b035a845a929a3bf6f9db58a4887d12d0cb2455f24ac5335","segment_id":"index.md:898e28d91a14b400","source_path":"index.md","text_hash":"898e28d91a14b400e7dc11f9dc861afe9143c18bf9424b1d1b274841615f38b1","text":"If you want to lock it down, start with ","translated":"如果你想进行锁定配置,请从以下内容开始 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:03:35Z"} -{"cache_key":"54d155bfaa944dfce20caeefa7452e7022732c19d46e7b3c31c6656fdb93f33d","segment_id":"environment.md:32ebb1abcc1c601c","source_path":"environment.md","text_hash":"32ebb1abcc1c601ceb9c4e3c4faba0caa5b85bb98c4f1e6612c40faa528a91c9","text":" (","translated":" (","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:58Z"} -{"cache_key":"550ba8127479edc00f347fd187d45bbfe02ae216e0dbe41b3d6a40db52c003e0","segment_id":"help/index.md:71095a6d42f5d9c2","source_path":"help/index.md","text_hash":"71095a6d42f5d9c2464a8e3f231fc53636d4ce0f9356b645d245874162ec07e2","text":"Gateway troubleshooting","translated":"Gateway 故障排除","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:56:29Z"} -{"cache_key":"557e4752d46bf19af760606c924d355964729b977705da1c324ed0d5488df7c5","segment_id":"environment.md:1ec31258a6b45ea9","source_path":"environment.md","text_hash":"1ec31258a6b45ea903cd76f5b0190a99ab56afff6241a04f0681eb12b7a02484","text":"Env var equivalents:","translated":"等效的环境变量:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:11:52Z"} -{"cache_key":"5588623b87444ab2f10920e15cae26afa748d33fcaa532d91d6190d720f1c44b","segment_id":"help/index.md:6cb77499abdccd9a","source_path":"help/index.md","text_hash":"6cb77499abdccd9a2dbb7c93a4d31eed01613dda06302933057970df9ecdeb54","text":"Logs:","translated":"日志:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:44:48Z"} -{"cache_key":"5598b6f2bb72cf8a1238b70f389ac26d5c39189a4b9ad8b76af4cd49eb33a713","segment_id":"start/wizard.md:4410e6ca609a533f","source_path":"start/wizard.md","text_hash":"4410e6ca609a533faee63dec02ec71a5c50e5b97062f0d93369139e0fe1b0d82","text":": optional ","translated":":可选 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:44:48Z"} -{"cache_key":"55a8e387b1f1138051af732f3f201a7f97a6e0a670aff0a74c5c5b4a509f6434","segment_id":"start/wizard.md:d2089be672953d11","source_path":"start/wizard.md","text_hash":"d2089be672953d1136faa84079af1b6f3967fed8932dabffba3032d30e3c0618","text":"Token","translated":"令牌","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:56Z"} -{"cache_key":"55bccdb299ca0c443fbee7ae8c28a88be0a40e6973b497cd17f15dd048a91558","segment_id":"start/wizard.md:dbd212a8183236f0","source_path":"start/wizard.md","text_hash":"dbd212a8183236f07f7a17afce31b2d18665e319b32dae90af1d04765fe2625d","text":"Config reference: ","translated":"配置参考: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:49:08Z"} -{"cache_key":"56135692918078250894cd24cb873bc5e59b3913ca7c8f70192db42b5c1552a3","segment_id":"index.md:4d4d75c23a2982e1","source_path":"index.md","text_hash":"4d4d75c23a2982e184011f79e62190533f93cdad41ba760046419678fa68d430","text":"Runtime requirement: ","translated":"运行时要求: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:08Z"} -{"cache_key":"562db402fedea0d89bb4b457c0bf0a29473db6c37066eb838cf16cee6491bcb0","segment_id":"index.md:81023dcc765309dd","source_path":"index.md","text_hash":"81023dcc765309dd05af7638f927fd7faa070c58abe7cad33c378aa02db9baa2","text":" (token is required for non-loopback binds).","translated":" (非回环绑定需要令牌)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:47Z"} -{"cache_key":"569404a9b6463e543124c499f821d6ac2f2c24b6ad6a2821e13fdf758bc5ae6e","segment_id":"environment.md:f0442e6e05ccca16","source_path":"environment.md","text_hash":"f0442e6e05ccca160d17de0e7d509891b91b921366b2202b2b5c80435824e140","text":"Two equivalent ways to set inline env vars (both are non-overriding):","translated":"两种等效的方式来设置内联环境变量(两者都是非覆盖的):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:11:47Z"} -{"cache_key":"56a23cfaebcc81253e55771aec19e4fd69bdd738fccc96d76b27a9229c483aa0","segment_id":"start/wizard.md:7c19f1358e5a91a8","source_path":"start/wizard.md","text_hash":"7c19f1358e5a91a8bf5165c597be85be56510330c5e754af349899104e6dca05","text":": if ","translated":":如果 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:11Z"} -{"cache_key":"56c452948915062308b68b03169a7e032ae1404911a12ac62b0234c408ec18a5","segment_id":"environment.md:61115f6649792387","source_path":"environment.md","text_hash":"61115f664979238731a390e84433a818965b7eaf1d38fa5b4b1507c33ef28c91","text":"Precedence (highest → lowest)","translated":"优先级(从高到低)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:24Z"} -{"cache_key":"56f0053c5e04eb858cff8d23ac7c15f18df295163eca33fcf5481592fe4c9e7e","segment_id":"index.md:11450a0f023dc48c","source_path":"index.md","text_hash":"11450a0f023dc48cc9cef026357e2b4569a2b756290191c45a9eb0120a919cb7","text":" and (for groups) mention rules.","translated":" 以及(针对群组的)提及规则。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:41Z"} -{"cache_key":"570aa7e523634c91d2e5091a861a2656c0af61316e18d9d53d28ff9b1dd32ee3","segment_id":"index.md:bf0e823c81b87c5d","source_path":"index.md","text_hash":"bf0e823c81b87c5de79676155debf20a29b52d6d7eb7e77deda73a56d0afbaaa","text":"🧠 ","translated":"🧠 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:15Z"} -{"cache_key":"576285ac236140f5584a71845cd3ab297a14b96100ac5c8efa39439ea81af132","segment_id":"start/getting-started.md:0b5979b793d7bafc","source_path":"start/getting-started.md","text_hash":"0b5979b793d7bafcae2346d1323747631b04df91cbbdbf878cb9b419233af218","text":"optional background service","translated":"可选的后台服务","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:02Z"} -{"cache_key":"5797b6a21c5b4993623f1b645eada0826ba49d498f93da9e4535b2bc66ecebe3","segment_id":"index.md:2f1626425f985d9a","source_path":"index.md","text_hash":"2f1626425f985d9ad8c124ea8ccb606e404ae5f43c58bd16b6c109d6d2694083","text":"Most operations flow through the ","translated":"大多数操作通过 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:33Z"} -{"cache_key":"57faa67fdf48914b9f543f1f16050dbd5161c7af426c58b0391d519d6506deca","segment_id":"help/index.md:569ca49f4aaf7846","source_path":"help/index.md","text_hash":"569ca49f4aaf7846e952c1d4aeca72febd0b79fa1c4f9db08fd3127551218572","text":"Install","translated":"安装","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:39:40Z"} -{"cache_key":"580953a19863c3d4f19ed1bfc789c4681bf548a213b44d05890c81e3c183bddc","segment_id":"index.md:e3572f8733529fd3","source_path":"index.md","text_hash":"e3572f8733529fd30a8604d41d624c15f4433df68f40bd092d1ee61f7d8d15e2","text":"Agent bridge","translated":"智能体 桥接","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:26Z"} -{"cache_key":"580e74e39c7246c3298ca172ea6f14364440b964fe9bc6a8d341194037dea02e","segment_id":"start/wizard.md:37e38f71b148eca2","source_path":"start/wizard.md","text_hash":"37e38f71b148eca2086a3c2186d62507e4f8cbb09a54edcb316d651bb1f29557","text":": local ","translated":":本地 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:44:56Z"} -{"cache_key":"581b9d2ca381a3956cb2c34ee44736e34f2fc8c9c12beacf66c3940034bf38b3","segment_id":"index.md:a97c0f391117ef55","source_path":"index.md","text_hash":"a97c0f391117ef554586ed43255ab3ff0e15adcfc1829c62b6d359672c0bec93","text":" — Mention-based by default; owner can toggle ","translated":" — 默认基于提及触发;所有者可切换 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:33Z"} -{"cache_key":"58518d711b63edb4aa641534a198510edcada769a3213a0a69a4f1c7a11cdc5f","segment_id":"start/wizard.md:7ddb0704314b289e","source_path":"start/wizard.md","text_hash":"7ddb0704314b289e7df028a91980144a09de964e2155c0b1d2b5263996c9bb7a","text":"Vercel AI Gateway","translated":"Vercel AI Gateway","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:53Z"} -{"cache_key":"5854b7c02dc640d3a8eefbdbcfe6257017838bee852fb6459e657c3d25dba670","segment_id":"environment.md:46ab081177a452aa","source_path":"environment.md","text_hash":"46ab081177a452aa62354b581730f4675cb03e58cde8282071da30cabe18fb2e","text":"Optional login-shell import","translated":"可选的登录 shell 导入","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:34Z"} -{"cache_key":"58685380a9fc556f1364bbc64e7d1471c341cc4b6e23c0f7792b7f1f83b90c0b","segment_id":"start/wizard.md:d3c2c33c63d513d7","source_path":"start/wizard.md","text_hash":"d3c2c33c63d513d77ca245c9b66527155c15adcf3b687fa72b4da67f80ed27b9","text":" exists, choose ","translated":" 存在,请选择 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:03Z"} -{"cache_key":"587a20717b7a463343b0975b76259c80107d7b353e2274384589d2b39f9426e1","segment_id":"start/wizard.md:320754cd5c316bdf","source_path":"start/wizard.md","text_hash":"320754cd5c316bdfec2957a249e26bef7cc1bcd3d7a6668b9378a14704714b40","text":"Wizard attempts to enable lingering via ","translated":"向导会尝试通过 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:45:19Z"} -{"cache_key":"58b9a1752caf49f80928c56d27ed1a2bc036495ad60d1dae62913fb293b46a55","segment_id":"start/wizard.md:0cfdc51cb2368973","source_path":"start/wizard.md","text_hash":"0cfdc51cb236897362d81cf81a533f21184ce1f5e83afe14713a943593ac3a0f","text":": stores the key for you.","translated":":为您存储密钥。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:46Z"} -{"cache_key":"58ff8f5714b801a09dbe57ef9e43f987926fb18ddfbf06dd710873990251b4c2","segment_id":"index.md:723fad6d27da9393","source_path":"index.md","text_hash":"723fad6d27da939353c65417bbaf646b65903b316eb4456297ff4a1c20811e8d","text":": HTTP file server on ","translated":":HTTP 文件服务器位于 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:57Z"} -{"cache_key":"5962bcb8baac7a5a279ff1ee2c82efe20db4c0c28e1f6244a25aa3de214a48e6","segment_id":"start/getting-started.md:frontmatter:summary","source_path":"start/getting-started.md:frontmatter:summary","text_hash":"f6955d3daff59d2b0a5cdb5731848998bfb3b6b1fa133c8587b5da1137b49dd1","text":"Beginner guide: from zero to first message (wizard, auth, channels, pairing)","translated":"新手指南:从零开始到发送第一条消息(向导、认证、渠道、配对)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:15Z"} -{"cache_key":"5999b798f983aca853bfa20dee21a17340561fab7d1e736475141ee6a6c6c9ef","segment_id":"help/index.md:bfc5930cc2660330","source_path":"help/index.md","text_hash":"bfc5930cc2660330260afd407e98d86adaec0af48dd72b88dc33ef8e9066e2c9","text":"Install sanity (Node/npm/PATH):","translated":"安装完整性检查(Node/npm/PATH):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:44:40Z"} -{"cache_key":"59c1f2c382072b7399fb13a23472af019ef5e481c697051eeacd4250a633a44a","segment_id":"index.md:76d6f9c532961885","source_path":"index.md","text_hash":"76d6f9c5329618856f133dc695e78f085545ae05fae74228fb1135cba7009fca","text":") — Pi creator, security pen-tester","translated":")— Pi 创作者,安全渗透测试员","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:40Z"} -{"cache_key":"59cd3f5bae0fc6f3c5c68e641d8023b8abc6683a5b46e97eeddd4252f7bd9cf3","segment_id":"index.md:a97c0f391117ef55","source_path":"index.md","text_hash":"a97c0f391117ef554586ed43255ab3ff0e15adcfc1829c62b6d359672c0bec93","text":" — Mention-based by default; owner can toggle ","translated":" —— 默认基于提及触发;所有者可以切换 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:43Z"} -{"cache_key":"5a54b33c72ae9262caf7fb631174cd7ba166e35d90a0fedada04f1341d480d2b","segment_id":"environment.md:907940a35852447a","source_path":"environment.md","text_hash":"907940a35852447aad5f21c5a180d993ff31cfd5807b1352ed0c24eabe183465","text":"never override existing values","translated":"永远不覆盖已有的值","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:53Z"} -{"cache_key":"5a584dcf9fe91e72165672d18b1e4edf88478a25cd6219842c6b26e791f4649f","segment_id":"index.md:9f4d843a5d04e23b","source_path":"index.md","text_hash":"9f4d843a5d04e23b22eb79b3bfa0fbad70ede435ddb5d047e7d77e830efa6019","text":" — Bot token + WebSocket events","translated":" — Bot 令牌 + WebSocket 事件","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:47Z"} -{"cache_key":"5ac64275154111e455f8ad15880f47a2dfd9dc428ac06b485dff574b25771a69","segment_id":"index.md:9dea37e7f1ff0e24","source_path":"index.md","text_hash":"9dea37e7f1ff0e24f7daecf6ea9cc38a58194f11fbeab1d3cfaa3a5645099ef4","text":"Updating / rollback","translated":"更新 / 回滚","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:04:05Z"} -{"cache_key":"5acb6159e9978fd41ab798d8bdb9d754f75409541ef52fc4f584c82e1d2111b0","segment_id":"help/index.md:5c94724fa7810fa9","source_path":"help/index.md","text_hash":"5c94724fa7810fa9902e565cf66c5f5a973074f2961fcd3a40bad4ee4aeca5e0","text":"If you want a quick “get unstuck” flow, start here:","translated":"如果你想快速\"解决卡住的问题\",从这里开始:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:24:34Z"} -{"cache_key":"5ad3f65c184c4a08ef211b77a6927634d4ffbb4237d717ea6df811df08f138ec","segment_id":"start/wizard.md:c2912d74db583b26","source_path":"start/wizard.md","text_hash":"c2912d74db583b2672bc6ee18cac65b4f95a547cf5535cf457fd7534981644b1","text":": prompts for ","translated":":提示输入 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:35Z"} -{"cache_key":"5af6e45efa085bf05463db83e35c7d337a67597574fe09331f7220925949bba6","segment_id":"help/index.md:frontmatter:read_when:1","source_path":"help/index.md:frontmatter:read_when:1","text_hash":"857eafc389d179e83e21e46c10527fec40894fe064c63847ba06b946b7d5eb73","text":"Something broke and you want the fastest path to a fix","translated":"出了问题,你想找到最快的修复方法","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:21:34Z"} -{"cache_key":"5af8a2aa97675994afa5c5fe3b78418fb9836171d4db6c883e7d26189c199a7e","segment_id":"index.md:4d87941d681ca4e8","source_path":"index.md","text_hash":"4d87941d681ca4e89ca303d033b7d383d3acfbb6d9d9616bd88d7c19cf92c3dd","text":"Pi","translated":"Pi","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:58Z"} -{"cache_key":"5b3300af7348ec2a1e6a63faed5d2d36b21f592dda0270c5431d43adae59b1d1","segment_id":"index.md:6201111b83a0cb5b","source_path":"index.md","text_hash":"6201111b83a0cb5b0922cb37cc442b9a40e24e3b1ce100a4bb204f4c63fd2ac0","text":" and ","translated":" 和 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:13Z"} -{"cache_key":"5b6535c3e3743405e859a5b26d0d96cc35789c5a3c642c76ea81b79386635441","segment_id":"start/wizard.md:b482e45229e19f5f","source_path":"start/wizard.md","text_hash":"b482e45229e19f5f7ba590b5ac81bdb25d5d24116ed961bfa0eb1a23c20a204c","text":" (or ","translated":" (或 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:37Z"} -{"cache_key":"5c1d43ddd497832b75c32dfbaaa644936f42480df0b9630a0974cf6e2f523656","segment_id":"start/wizard.md:8a5edab282632443","source_path":"start/wizard.md","text_hash":"8a5edab282632443219e051e4ade2d1d5bbc671c781051bf1437897cbdfea0f1","text":" / ","translated":" / ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:48:32Z"} -{"cache_key":"5c3c725a47f409c7342bc422f59aeb14d9de2c891fc092f6eda3299a14e1def4","segment_id":"environment.md:ffa63583dfa6706b","source_path":"environment.md","text_hash":"ffa63583dfa6706b87d284b86b0d693a161e4840aad2c5cf6b5d27c3b9621f7d","text":"missing","translated":"缺失的","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:49Z"} -{"cache_key":"5c5f7754116c27bc91d76e82699d3d46ae75acf3ebcebfd217d6a8c4667f47be","segment_id":"start/getting-started.md:c16fb1db14572857","source_path":"start/getting-started.md","text_hash":"c16fb1db145728574044899ab5577f464ecd30cd4b297b45b4385ce39dcbab70","text":"If you installed the service during onboarding, the Gateway should already be running:","translated":"如果您在上手引导过程中安装了服务,Gateway 应该已经在运行:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:49Z"} -{"cache_key":"5c775f8101cacd367ff5c7722b3b2c3a5dce43493d19e42aa30282c74ee24a7b","segment_id":"index.md:2b402c90e9b15d9c","source_path":"index.md","text_hash":"2b402c90e9b15d9c3ef65c432c4111108f54ee544cda5424db46f6ac974928e4","text":"🔐 ","translated":"🔐 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:23Z"} -{"cache_key":"5c780db9d3f1b4fef594dae3510c0bf35d432d48acf5889e9d4f4f6e844d46a5","segment_id":"start/getting-started.md:8816c52bc5877a2b","source_path":"start/getting-started.md","text_hash":"8816c52bc5877a2b24e3a2f4ae7313d29cf4eba0ca568a36f2d00616cfe721d0","text":"Wizard","translated":"向导","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:06Z"} -{"cache_key":"5c90f7114b3baa2b4a5d8c980df5c3be37909dda0be1f3318d91f8810181cd50","segment_id":"index.md:37ed7c96b16160d4","source_path":"index.md","text_hash":"37ed7c96b16160d491e44676aa09fe625301de9c018ad086e263f59398b8be8a","text":"🎤 ","translated":"🎤 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:02:19Z"} -{"cache_key":"5cfd51b6ed282f1ab9449da2a23c095cd4c28c738d56b5e6525e372d0f602907","segment_id":"index.md:cec2be6f871d276b","source_path":"index.md","text_hash":"cec2be6f871d276b45d13e3010c788f01b03ae2f1caca3264bbf759afacace46","text":"Telegram Bot","translated":"Telegram 机器人","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:35Z"} -{"cache_key":"5d5941af110e6856ee1abe848dc7404970d7e151226fe533a22e9a7f936292ea","segment_id":"index.md:88d90e2eef3374ce","source_path":"index.md","text_hash":"88d90e2eef3374ce1a7b5e7fbd3b1159364b26a8ceb2493d6e546d4444b03cda","text":"Tailscale","translated":"Tailscale","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:40Z"} -{"cache_key":"5d83de16c61f5425e1149b23d1001f7ef7ed0028c6f453ce8f74df31fd2a2262","segment_id":"environment.md:f0442e6e05ccca16","source_path":"environment.md","text_hash":"f0442e6e05ccca160d17de0e7d509891b91b921366b2202b2b5c80435824e140","text":"Two equivalent ways to set inline env vars (both are non-overriding):","translated":"两种等效的内联 环境变量 设置方式(均不会覆盖):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:41:10Z"} -{"cache_key":"5daf1c9089fed361745301c1f4a5ef332e660187481b4a0ee10f384c16d08098","segment_id":"index.md:ab201ddd7ab330d0","source_path":"index.md","text_hash":"ab201ddd7ab330d04be364c0ac14ce68c52073a0ee8d164a98c3034e91ce1848","text":" from the repo.","translated":" 从仓库中执行。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:40Z"} -{"cache_key":"5dbafe2a97e2fd217ed8ae3c96a68526e3aeb0924d460025aaed526821245bc7","segment_id":"index.md:297d5c673f5439aa","source_path":"index.md","text_hash":"297d5c673f5439aa31dca3bbc965cb657a89a643803997257defb3baef870f89","text":"Open the dashboard (local Gateway):","translated":"打开仪表板(本地 Gateway):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:47:55Z"} -{"cache_key":"5e1da320f32d4ee8aff0094e46c98e584ddfc953913e27eeb950f1a73cdbda40","segment_id":"environment.md:ffa63583dfa6706b","source_path":"environment.md","text_hash":"ffa63583dfa6706b87d284b86b0d693a161e4840aad2c5cf6b5d27c3b9621f7d","text":"missing","translated":"缺失的","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:42Z"} -{"cache_key":"5e2c30218fd9868878dbe2c938ebef80fe51f6b4f9e17f12144d1a8349afb7b3","segment_id":"start/wizard.md:2d8879a4fb313aa0","source_path":"start/wizard.md","text_hash":"2d8879a4fb313aa0515b0a575b00f60de6a2369e30129bc31c20ae0c25e538bd","text":" and chat in the browser. Docs: ","translated":" 然后在浏览器中对话。文档: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:09Z"} -{"cache_key":"5e43eebc024e0b75c56a6288f219508bbe17b68fe85f1eca16ec03c1481bc99b","segment_id":"help/index.md:frontmatter:read_when:1","source_path":"help/index.md:frontmatter:read_when:1","text_hash":"857eafc389d179e83e21e46c10527fec40894fe064c63847ba06b946b7d5eb73","text":"Something broke and you want the fastest path to a fix","translated":"遇到故障了,你想找到最快的修复方法","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:56:14Z"} -{"cache_key":"5e4d7f1b9311d07ef5ce4f39f1e47a953b0916b1a5ca7df4b395179b564796fc","segment_id":"start/getting-started.md:4c3d9aa7ad8a4496","source_path":"start/getting-started.md","text_hash":"4c3d9aa7ad8a449660623429f93ee51afcf8e2d77d7ca16229a19d52262ecab6","text":"Next steps (optional, but great)","translated":"后续步骤(可选,但强烈推荐)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:16Z"} -{"cache_key":"5e58639dd12e22ac1e6e022b66e5c0edfaf2e17279bd951b86047e5ed952b65d","segment_id":"index.md:f1e3b32c8eb0df8e","source_path":"index.md","text_hash":"f1e3b32c8eb0df8ea105f043edf614005742c15581e2cebc5a9c3bafb0b90303","text":"Multi-agent routing","translated":"多 智能体 路由","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:18Z"} -{"cache_key":"5e6f4e17b35988acf25c0cf67edb5bb0267aa378b3a700d43efdf21503475c13","segment_id":"environment.md:f15f5f9f4ef4d668","source_path":"environment.md","text_hash":"f15f5f9f4ef4d6688876c894f8eba251ed1db6eaf2209084028d43c9e76a8ba1","text":" (aka ","translated":" (即 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:34Z"} -{"cache_key":"5e819d45951c185c25d0c543873e913e628e57d81aa0a617e31158890a669e15","segment_id":"help/index.md:5c94724fa7810fa9","source_path":"help/index.md","text_hash":"5c94724fa7810fa9902e565cf66c5f5a973074f2961fcd3a40bad4ee4aeca5e0","text":"If you want a quick “get unstuck” flow, start here:","translated":"如果你想要一个快速的\"快速排障\"流程,请从这里开始:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:56:18Z"} -{"cache_key":"5e941e344b30824bf659b63b0325cbbc0fe0a2b4a687eff1e79174aa1133b8e8","segment_id":"help/index.md:24669ff48290c187","source_path":"help/index.md","text_hash":"24669ff48290c1875d8067bbd241e8a55444839747bffb8ab99f3a34ef248436","text":"Doctor","translated":"诊断","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:56:44Z"} -{"cache_key":"5ee69009fd3da1ee495a4d68f7cce4f38b9e39bf9d9e6fca4bd1ddc066a70819","segment_id":"index.md:2566561f81db7a7c","source_path":"index.md","text_hash":"2566561f81db7a7c4adb6cee3e93139155a6b01d52ff0d3d5c11648f46bc79bb","text":"📱 ","translated":"📱 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:24Z"} -{"cache_key":"5eebf79b3ae425984310ea74305f2dfe6ce49f0942b2144044781ecb00b105c9","segment_id":"start/getting-started.md:41884234ba7e0041","source_path":"start/getting-started.md","text_hash":"41884234ba7e0041d39bd06003bd12c5b7811a92b95bb7dbba71bd33b2a1a896","text":"If a token is configured, paste it into the Control UI settings (stored as ","translated":"如果配置了令牌,请将其粘贴到控制界面设置中(存储为 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:55Z"} -{"cache_key":"5eecedb868edab3c718ba04090d4964a74779499d46101c0661259e7f90e4f65","segment_id":"environment.md:frontmatter:summary","source_path":"environment.md:frontmatter:summary","text_hash":"78351223e7068721146d2de022fdf440c2866b2ee02fbbb50bf64369b999820b","text":"Where OpenClaw loads environment variables and the precedence order","translated":"OpenClaw 加载环境变量的位置及优先级顺序","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:21:46Z"} -{"cache_key":"5f10dfed67a40e4e3332100f92b41fe1b3d47e0e6e6bf4bb6385fa478524c38b","segment_id":"index.md:898e28d91a14b400","source_path":"index.md","text_hash":"898e28d91a14b400e7dc11f9dc861afe9143c18bf9424b1d1b274841615f38b1","text":"If you want to lock it down, start with ","translated":"如果你想锁定访问权限,请从以下内容开始 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:39Z"} -{"cache_key":"5f5af7c41d6bd3bdcf3992da945b51ccd3a2d373b7acdfc6afb17d462e38e72b","segment_id":"start/wizard.md:c084c70e0e8978a4","source_path":"start/wizard.md","text_hash":"c084c70e0e8978a4add1624dfb4f3f6ddb9b8d09530122749fe443d68bae6ce0","text":"OpenCode Zen example:","translated":"OpenCode Zen 示例:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:47:34Z"} -{"cache_key":"5f87ef9c51ba75be8e473df32b40b1fd4a7c3000ad679f5551be4605640d997e","segment_id":"help/index.md:3c33340bd23b8db8","source_path":"help/index.md","text_hash":"3c33340bd23b8db89f18fe7d05a954738c0dd5ba9623cf6bdb7bb5d1a3729cfc","text":"FAQ (concepts)","translated":"常见问题(概念)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:05Z"} -{"cache_key":"5f9b30a629fbd7152505c6cd2a19f6200a808e96198dcce0f0a87efaa862a6ca","segment_id":"start/getting-started.md:6a40edf1fc87a29f","source_path":"start/getting-started.md","text_hash":"6a40edf1fc87a29f243a7eefdbed57d19bfe16ab2e039d7ae1a44c097297e2f3","text":"WhatsApp","translated":"WhatsApp","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:14Z"} -{"cache_key":"600dc3f3ca0e2b1ab03d4449dfd67b69ddc839f9bd15a60ba9e382f875570e53","segment_id":"start/wizard.md:cda454f61dfcac70","source_path":"start/wizard.md","text_hash":"cda454f61dfcac7007a9edc538f9f58cf38caa0652e253975979308162bccc53","text":"Gateway configuration","translated":"Gateway 配置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:49:10Z"} -{"cache_key":"604e3fe87674a94bdb57317af8bf1685c73dd5bad1c72ed1570c2f0989c34fb0","segment_id":"index.md:b214cd10585678ca","source_path":"index.md","text_hash":"b214cd10585678ca1250ce1ae1a50ad4001de4577a10e36be396a3409314e442","text":"@badlogicc","translated":"@badlogicc","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:06:02Z"} -{"cache_key":"605a5c23c689ae3b3531bdda797af578f1b09bf2801b93d2a9956d79651c1d79","segment_id":"environment.md:3bfb78f689d2a990","source_path":"environment.md","text_hash":"3bfb78f689d2a9908d74fb3694eb6284201f276d61c8c83e50b9f258b83ff807","text":"), applied only for missing expected","translated":"),仅在缺少预期","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:19Z"} -{"cache_key":"606008c50996fdd54d71d6dd64dacb4235aea44dd1e4f38bef2dbd70e9bc71b0","segment_id":"start/wizard.md:72e16ab00d3e1b7f","source_path":"start/wizard.md","text_hash":"72e16ab00d3e1b7fe8d1c9127fc3f475192ad16f8c1a7f40e71a18b5541d7315","text":"); it tries without sudo first.","translated":");它会先尝试不使用 sudo。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:45:27Z"} -{"cache_key":"609cc86f40f9b958987a73b8bf63da515fc2edd851f410e949b9c29c097e3a77","segment_id":"start/wizard.md:aeb8df5ac5b2a23f","source_path":"start/wizard.md","text_hash":"aeb8df5ac5b2a23f4491dec84235080e499723987ce22d246e3a40face0afa55","text":"Vercel AI Gateway (multi-model proxy)","translated":"Vercel AI Gateway(多模型代理)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:48Z"} -{"cache_key":"609f00fe9446aa4a32a1eb8cdb850f7655716d5b18db42ac65dd51c107637f56","segment_id":"index.md:eec70d1d47ec5ac0","source_path":"index.md","text_hash":"eec70d1d47ec5ac00f04e59437e7d8b0988984c0cea3dddd81b1a2a10257960b","text":" — DMs + groups via grammY","translated":" — 通过 grammY 支持私聊和群组","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:37Z"} -{"cache_key":"60b4aabf7487a78610b106bb8bdece56d18d22bc8bc54fa17ebbaffd4d111e1b","segment_id":"start/wizard.md:28513cbd3be49624","source_path":"start/wizard.md","text_hash":"28513cbd3be496244d0e2e1f54d3bc382d466ca58f6b127dd6b5213e36c298b5","text":"If the config is invalid or contains legacy keys, the wizard stops and asks\n you to run ","translated":"如果配置无效或包含遗留键,向导会停止并要求您运行 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:19Z"} -{"cache_key":"60bfa0a92eff33a33728f88b482cb2663dc1e19e6a3dc3023021e231ee0a89db","segment_id":"index.md:3c8aa7ad1cfe03c1","source_path":"index.md","text_hash":"3c8aa7ad1cfe03c1cb68d48f0c155903ca49f14c9b5626059d279bffc98a8f4e","text":": connect to the Gateway WebSocket (LAN/tailnet/SSH as needed); legacy TCP bridge is deprecated/removed.","translated":":连接到 Gateway WebSocket(根据需要使用 LAN/tailnet/SSH);旧版 TCP 桥接已弃用/移除。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:16Z"} -{"cache_key":"60c75897f641a043a33c9a88656df4a3dc1cce376a938c3b6df6b981339df50c","segment_id":"start/getting-started.md:5f0802429b8d0ea9","source_path":"start/getting-started.md","text_hash":"5f0802429b8d0ea99aec0b3456fac2d5721bbddd7ca4edeb47bb71a2a6619e63","text":"Discord: ","translated":"Discord: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:24Z"} -{"cache_key":"60cd1a8fee21c221c625fe6961c620592e9f99a88910d9f557d86f92e17d793c","segment_id":"start/wizard.md:1d6bc09c9a9a3dad","source_path":"start/wizard.md","text_hash":"1d6bc09c9a9a3dad8fcbe9ed89a206b2dba3d8cf16046315aee976577d534cae","text":"Downloads the appropriate release asset.","translated":"下载相应的发布资源。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:47:59Z"} -{"cache_key":"60f998f050fe63afd0938f40b2f1cf78a16d5dd9fa6abc631aa8e217ce1e7cc5","segment_id":"index.md:053bc65874ad6098","source_path":"index.md","text_hash":"053bc65874ad6098e58c41c57b378a2f36b0220e5e0b46722245e6c2f796818c","text":"Discord","translated":"Discord","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:53:15Z"} -{"cache_key":"61277a40a0e409e2f324452a28cc35c44e1ac080b4400e7bdaa3c161ce51d545","segment_id":"start/wizard.md:3fcf806de5c2ace5","source_path":"start/wizard.md","text_hash":"3fcf806de5c2ace5327f65078cfb2139aaa8dd33ffdc3b04e9fef6f11778423c","text":"MiniMax M2.1","translated":"MiniMax M2.1","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:55Z"} -{"cache_key":"613744b9849b1cacbbcdcebd3fcb2637696f177d0364b9e32042a74bf2c1b350","segment_id":"index.md:80fc402133201fbe","source_path":"index.md","text_hash":"80fc402133201fbe0e4e9962a9570e741856aa8b0c033f1a20a9bcb06c68e809","text":"Discovery","translated":"发现","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:20Z"} -{"cache_key":"613d01b2aa6e9a9127f428233d5f88e84e2c86b5079776f57becfe4143f86992","segment_id":"start/wizard.md:3ccbb3a92014470f","source_path":"start/wizard.md","text_hash":"3ccbb3a92014470f73c71c81684da45b1e07ee3a49cca372ec678ce89229ea58","text":"Vercel AI Gateway example:","translated":"Vercel AI Gateway 示例:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:47:26Z"} -{"cache_key":"614a1ff5ae5f98f2f46f1ee6bbb53ace3482d9d15a8842906f26dcbad10c4d71","segment_id":"index.md:084514e91f37c3ce","source_path":"index.md","text_hash":"084514e91f37c3ce85360e26c70b77fdc95f0d3551ce309db96fbcf956a53b01","text":"Dashboard (browser Control UI)","translated":"仪表板(浏览器控制界面)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:30Z"} -{"cache_key":"619f1d68210cd4f4763a855771ec7e821343568b465996ee365552e40ecaadc4","segment_id":"index.md:da22b9d6584e1d8a","source_path":"index.md","text_hash":"da22b9d6584e1d8aa709165be214e0f9bdf2be428816e9ce1c4506bf86218cb4","text":"Core Contributors","translated":"核心贡献者","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:47Z"} -{"cache_key":"61f5af5889e4b2f0a5990d65fdd5b3fdc94d5fd178ef4d80c9cb134a37745cd5","segment_id":"index.md:4818a3f84331b702","source_path":"index.md","text_hash":"4818a3f84331b702815c94b4402067e09e9e2d27ebc1a79258df8315f2c8600b","text":"📎 ","translated":"📎 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:02:13Z"} -{"cache_key":"6261f859049427393c85f0f32d3db92e9fd57735f4855522a37fb535f791a35a","segment_id":"environment.md:frontmatter:read_when:0","source_path":"environment.md:frontmatter:read_when:0","text_hash":"90fc0487bff88009979cff1061c1a882df8c3b1baa9c43538331d9d5dab15479","text":"You need to know which env vars are loaded, and in what order","translated":"你需要了解哪些环境变量会被加载,以及它们的加载顺序","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:44Z"} -{"cache_key":"62631b9bcaa4b5c5f2603b93e0f658180f8b3f6c897506e90a26feab650f09b8","segment_id":"index.md:3f8466cd9cb153d0","source_path":"index.md","text_hash":"3f8466cd9cb153d0c78a88f6a209e2206992db28c6dab45424132dc187974e2b","text":"Note: legacy Claude/Codex/Gemini/Opencode paths have been removed; Pi is the only coding-agent path.","translated":"注意:旧版 Claude/Codex/Gemini/Opencode 路径已被移除;Pi 是唯一的编程 智能体 路径。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:02:46Z"} -{"cache_key":"627572a4323c2872b6db51c5d819b4213c571df88da85e170f85d77f96eb55d8","segment_id":"index.md:81023dcc765309dd","source_path":"index.md","text_hash":"81023dcc765309dd05af7638f927fd7faa070c58abe7cad33c378aa02db9baa2","text":" (token is required for non-loopback binds).","translated":" (非回环绑定需要令牌)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:10Z"} -{"cache_key":"62bd68ff9cbf96b3905a12162b9474b1284e8e16101d63a711144fd5a7c311cc","segment_id":"help/index.md:8cd501e1124c3047","source_path":"help/index.md","text_hash":"8cd501e1124c30473473c06e536a2d145e2a14a6d7dc1b99028ce818e14442e2","text":"Repairs:","translated":"修复:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:56:42Z"} -{"cache_key":"62eab355a91a29c11800cfb1fa5d04f8a626123e8f9e9b12bb46a42fee12b00d","segment_id":"environment.md:f7e239a42b7cd986","source_path":"environment.md","text_hash":"f7e239a42b7cd986a1558fed234e975ed2e96e9d37cf0a93f381778c461c89dd","text":"OpenClaw pulls environment variables from multiple sources. The rule is ","translated":"OpenClaw 从多个来源获取环境变量。规则是 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:51Z"} -{"cache_key":"633b27d62b9c0884576b289c4417f9e9caf3a669d9743346c3713e6df7135d9d","segment_id":"start/getting-started.md:d6053f5f95b19aef","source_path":"start/getting-started.md","text_hash":"d6053f5f95b19aef2ba01e965f8caaf95fd2746c1965b907a7f8c0083680351d","text":"Wizard doc: ","translated":"向导文档: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:26Z"} -{"cache_key":"63707c20cc5a0d1176ffd1db451cc4c84b2168e4ec534e052a7a0906e97abeb7","segment_id":"environment.md:ffa63583dfa6706b","source_path":"environment.md","text_hash":"ffa63583dfa6706b87d284b86b0d693a161e4840aad2c5cf6b5d27c3b9621f7d","text":"missing","translated":"缺失的","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:51Z"} -{"cache_key":"63a4d4ad29115c6bce10a5f64dad28c623d7d4c7b9e7c78d6281496a1e2f3d34","segment_id":"environment.md:28b1103adde15a9d","source_path":"environment.md","text_hash":"28b1103adde15a9ddd8fc71f0c57dc155395ade46a0564865ccb5135b01c99b7","text":"OpenClaw pulls environment variables from multiple sources. The rule is **never override existing values**.","translated":"OpenClaw 从多个来源拉取环境变量。规则是**永远不覆盖已有的值**。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:11:39Z"} -{"cache_key":"63aa81c04f67fe845a1309e5882381f68dcf88a5cbba1ebe971adb247324ff2d","segment_id":"help/index.md:cad44fbae951d379","source_path":"help/index.md","text_hash":"cad44fbae951d3791565b0cee788c01c3bd10e0176167acb691b8dba0f7895f8","text":"Gateway logging","translated":"Gateway 日志记录","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:39:52Z"} -{"cache_key":"63d76859e8f7dbf46bffcdaf3a95db6646334012c91a4d543fdf67f5e2c95e1a","segment_id":"index.md:4d4d75c23a2982e1","source_path":"index.md","text_hash":"4d4d75c23a2982e184011f79e62190533f93cdad41ba760046419678fa68d430","text":"Runtime requirement: ","translated":"运行时要求: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:02:53Z"} -{"cache_key":"63da7e7d14afa27ec40108c6b4b12db69d8f34c281095027a0939c0191ac77d6","segment_id":"start/wizard.md:c127ea338fd00fac","source_path":"start/wizard.md","text_hash":"c127ea338fd00fac2629a67910d8cbeade17990294fede336b54298e9b13a40c","text":"Telegram + WhatsApp DMs default to ","translated":"Telegram + WhatsApp 私信默认为 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:04Z"} -{"cache_key":"63edf6f6952fda49b0c75bad9c622396999c6b488d33644d8098f6346a1b2a17","segment_id":"start/getting-started.md:d7b4edd9ca795c46","source_path":"start/getting-started.md","text_hash":"d7b4edd9ca795c469606230849212eb080f0591477cff35400f276649d3910a9","text":" shows “no auth configured”, go back to the wizard and set OAuth/key auth — the agent won’t be able to respond without it.","translated":" 显示\"未配置认证\",请返回向导设置 OAuth/密钥认证——智能体在没有认证的情况下将无法响应。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:04Z"} -{"cache_key":"64412b08e5674ea41e50286a0e96cecf117837ff2738c6ff030b0949cfb72990","segment_id":"index.md:0a4a282eda1af348","source_path":"index.md","text_hash":"0a4a282eda1af34874b588bce628b76331fbe907de07b57d39afdedccac2ba14","text":" http://127.0.0.1:18789/ (or http://localhost:18789/)","translated":" http://127.0.0.1:18789/(或 http://localhost:18789/)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:47:58Z"} -{"cache_key":"644dafc0cc5f8edf1a480b2645ce841416abfc28022f45d45aed1ace6e2f8e0a","segment_id":"start/getting-started.md:eea56a0072aa60af","source_path":"start/getting-started.md","text_hash":"eea56a0072aa60afb5d46c629647ded6ff689e0f44e5725c90788fd103a509fa","text":" is the best pasteable, read-only debug report.\nHealth probes: ","translated":" 是最佳的可粘贴只读调试报告。\n健康探针: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:09Z"} -{"cache_key":"649d0c8a8010fa282e9856eafb02cc5527e7227c27b3c2dfe4eaa9713feb6a05","segment_id":"environment.md:0f18d564547eb32a","source_path":"environment.md","text_hash":"0f18d564547eb32aed995d190644ce9605af6b501b582d871359ebcd4fa51f66","text":" for full","translated":" 了解完整","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:47:09Z"} -{"cache_key":"64cf4d8cfd9d6b5409d1cff5433fe8065140174f76482589a8fb0e49fbdf3fee","segment_id":"start/wizard.md:f3e485ab2f76c031","source_path":"start/wizard.md","text_hash":"f3e485ab2f76c031c52bd164935ed8cac883a7aadf24bdf4fd09e484603968c0","text":"Anthropic OAuth (Claude Code CLI)","translated":"Anthropic OAuth (Claude Code CLI)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:55Z"} -{"cache_key":"64d70118440cf15f1338e65f651e5974d1a46e5c7a82edadd6ec50d965818d6d","segment_id":"start/wizard.md:f9225188070a558a","source_path":"start/wizard.md","text_hash":"f9225188070a558a048f29723fbee7dedb56bdc8f3e8caf0517b063bcc309c16","text":" walks you through:","translated":" 引导您完成:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:16Z"} -{"cache_key":"65168a9f26b2e2f8956203b7db6e482a46a9e40ffda04423b3ad3da71e0e1f5e","segment_id":"index.md:f12242785ecda793","source_path":"index.md","text_hash":"f12242785ecda7935ded50cd48418357d32d3bac290f7a199bc9f0c7fbd13123","text":") — Location parsing (Telegram + WhatsApp)","translated":")— 位置解析(Telegram + WhatsApp)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:02Z"} -{"cache_key":"65234bc3c31a162f6a66e59fb06d36ff735b520d4b8aad7c6f24230f5d0ec345","segment_id":"index.md:6638cf2301d3109d","source_path":"index.md","text_hash":"6638cf2301d3109da66a44ee3506fbd35b29773fa4ca33ff35eb838c21609e19","text":"Features (high level)","translated":"功能(概述)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:22Z"} -{"cache_key":"65a3efc02834181b87543fe4787306b30aed7810e28d100617fe8ba5465b15dc","segment_id":"help/index.md:frontmatter:summary","source_path":"help/index.md:frontmatter:summary","text_hash":"aece82a2d540ab1a9a21c7b038127cae6e9db2149491564bb1856b6f8999f205","text":"Help hub: common fixes, install sanity, and where to look when something breaks","translated":"帮助中心:常见修复方法、安装完整性检查,以及出现问题时的排查方向","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:00Z"} -{"cache_key":"65ab4527cf40950eae093485da13531121309a7404aabda07b243ec350c17d62","segment_id":"index.md:7e2735e5df8f4e9f","source_path":"index.md","text_hash":"7e2735e5df8f4e9f006d10e079fe8045612aa662b02a9d1948081d1173798dec","text":"MIT — Free as a lobster in the ocean 🦞","translated":"MIT — 像海洋中的龙虾一样自由 🦞","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:06:51Z"} -{"cache_key":"65d8ee3af16e324a3478a3d1f4e54621fb52f93e2508b55e9e9e991562425a84","segment_id":"index.md:37ed7c96b16160d4","source_path":"index.md","text_hash":"37ed7c96b16160d491e44676aa09fe625301de9c018ad086e263f59398b8be8a","text":"🎤 ","translated":"🎤 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:41Z"} -{"cache_key":"65e123a5806897466856108c21b4b513c5975eae6575984c019adafbb796a36d","segment_id":"start/wizard.md:b1ff7bd17092d95e","source_path":"start/wizard.md","text_hash":"b1ff7bd17092d95ea7811719ce3df6d79b0c3a576695636fc411f2d95dc908b2","text":"Mattermost","translated":"Mattermost","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:44:40Z"} -{"cache_key":"65e76ddd96b75b84f98d4165a471f8fcf85255313b695d5718400e8d5c87aada","segment_id":"index.md:d372b90f0ccffad0","source_path":"index.md","text_hash":"d372b90f0ccffad0ae6e3df3c3aaeccd7a17eb59b4bc492a5469dc05ac3629ec","text":", OpenClaw uses the bundled Pi binary in RPC mode with per-sender sessions.","translated":",OpenClaw 将使用内置的 Pi 二进制文件以 RPC 模式运行,并采用按发送者区分的会话。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:37Z"} -{"cache_key":"661b1fde84d92d603e939aea97a699f0c3d13d8ef1cf06240cdcf4086ea99e9a","segment_id":"start/getting-started.md:d087dd8116e1ea75","source_path":"start/getting-started.md","text_hash":"d087dd8116e1ea751e94c787e0c856f9fb51528528551b60ef7c610f12439120","text":"Telegram: ","translated":"Telegram: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:21Z"} -{"cache_key":"6689e918af1f418c89cbfd79e956dccccd85d3f2c0d7d08ca42674bb5fb46837","segment_id":"index.md:b79cac926e0b2e34","source_path":"index.md","text_hash":"b79cac926e0b2e347e72cc91d5174037c9e17ae7733fd7bdb570f71b10cd7bfc","text":"Help","translated":"帮助","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:03:50Z"} -{"cache_key":"669bd1fca3c6f7a5810302de54fcba2375123e94dfe30b61bbbb0df0b365b558","segment_id":"start/wizard.md:dcae3eda386cc9bb","source_path":"start/wizard.md","text_hash":"dcae3eda386cc9bbc068aaf01dc3a2543abb6d0504e176138ad4fbc4087767b5","text":" if present or prompts for a key, then saves it for daemon use.","translated":" (如果存在)或提示输入密钥,然后保存供守护进程使用。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:52Z"} -{"cache_key":"66c7246d1b6097539541673d8d9c8153a54d4fdb537ad31be453e514fb3754b9","segment_id":"index.md:f0d82ba647b4a33d","source_path":"index.md","text_hash":"f0d82ba647b4a33da3008927253f9bed21e380f54eab0608b1136de4cbff1286","text":"OpenClaw bridges WhatsApp (via WhatsApp Web / Baileys), Telegram (Bot API / grammY), Discord (Bot API / channels.discord.js), and iMessage (imsg CLI) to coding agents like ","translated":"OpenClaw 将 WhatsApp(通过 WhatsApp Web / Baileys)、Telegram(Bot API / grammY)、Discord(Bot API / channels.discord.js)和 iMessage(imsg CLI)桥接至编程智能体,例如 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:27:55Z"} -{"cache_key":"66cb3d6e2c27c1ee009c0531751f45f9927e2b3d09a4702546a67a9275ee5c49","segment_id":"environment.md:a806a90c34d867e4","source_path":"environment.md","text_hash":"a806a90c34d867e4445dda95ff64422e0b9a527d8fdd03490f255cddbeb84fdb","text":"Env var","translated":"环境变量","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:48Z"} -{"cache_key":"66d9604676a679978159598a722db6d8c4c96e082051763e3b1d5f47576894e2","segment_id":"environment.md:ab5aec4424cf678d","source_path":"environment.md","text_hash":"ab5aec4424cf678dcfb1ad3d2c2929c1e0b2b1ff61b82b961ada48ad033367b4","text":" (dotenv default; does not override).","translated":" (dotenv 默认行为;不覆盖)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:27Z"} -{"cache_key":"66e16e494883bd6fd041d66e577243e277a362ce785db530887996c9c14b93a9","segment_id":"start/wizard.md:frontmatter:read_when:1","source_path":"start/wizard.md:frontmatter:read_when:1","text_hash":"9bd20424220aa1c64181f1dce46bd8fe5d63d8cd8544f5a1cbaddb1030ad108b","text":"Setting up a new machine","translated":"设置新机器","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:55Z"} -{"cache_key":"66f6fd3c85fe2be6d76b21dae8ef66bb76ee3ebd3d92291e61abee595aa0e39d","segment_id":"index.md:66354a1d3225edbf","source_path":"index.md","text_hash":"66354a1d3225edbf01146504d06aaea1242dcf50424054c3001fc6fa2ddece0f","text":"Remote access","translated":"远程访问","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:18Z"} -{"cache_key":"672567848acf9fed5207cc54f76e9d0bffe7cbbd85569cbe74fc4a01e703b1ff","segment_id":"index.md:ab201ddd7ab330d0","source_path":"index.md","text_hash":"ab201ddd7ab330d04be364c0ac14ce68c52073a0ee8d164a98c3034e91ce1848","text":" from the repo.","translated":" 从仓库中执行。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:03:12Z"} -{"cache_key":"67355c084d419c2ec0eddd93cd1bf67b68218e2c141a65ebcdd96022e1a446df","segment_id":"environment.md:0ec3a996c8167512","source_path":"environment.md","text_hash":"0ec3a996c81675128a64349203e6af81e6d257ceb3124b120e0b894b26024680","text":" (dotenv default; does not","translated":" (dotenv 默认;不会","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:43Z"} -{"cache_key":"673925efd6296fa4423b6a1607689bebb6f61f0f1273c1ebc52daa1b44eb43b5","segment_id":"index.md:8816c52bc5877a2b","source_path":"index.md","text_hash":"8816c52bc5877a2b24e3a2f4ae7313d29cf4eba0ca568a36f2d00616cfe721d0","text":"Wizard","translated":"向导","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:08Z"} -{"cache_key":"675e8725187ebc4c5ee0560ddc38667c783d61c37a69680ea73fb1ca832690d1","segment_id":"index.md:65fd6e65268ff905","source_path":"index.md","text_hash":"65fd6e65268ff9057a49d832cccfcd5a376e46a908a2129be5b43f945fa8d8ca","text":": Gateway WS defaults to ","translated":":Gateway WS 默认监听 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:50Z"} -{"cache_key":"67688daae57335b03c42a3b327f5dc0a54f849238f4d03b3b6e113d76e3c21b0","segment_id":"index.md:11d28de5b79e3973","source_path":"index.md","text_hash":"11d28de5b79e3973f6a3e44d08725cdd5852e3e65e2ff188f6708ae9ce776afc","text":"Docs hubs (all pages linked)","translated":"文档中心(所有页面链接)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:03:47Z"} -{"cache_key":"678ce4ebc70142dc95d2df24b30a8f49ed54750c7cbdee7128254851be4d33f6","segment_id":"start/wizard.md:e9643f092e1f762c","source_path":"start/wizard.md","text_hash":"e9643f092e1f762c9a7e15bf5429a6c0081c210e464e56a3a35830834a9d4d59","text":"To add more isolated agents (separate workspace + sessions + auth), use:","translated":"要添加更多隔离的智能体(独立的工作区 + 会话 + 认证),请使用:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:43Z"} -{"cache_key":"67bfbb214f6fd84279273d721c587d520c889b48409a1123879c6d79522f7558","segment_id":"start/wizard.md:47eea376ece81e4b","source_path":"start/wizard.md","text_hash":"47eea376ece81e4bb17a281eabb2ddc5aa0458acd4c91a43f576f337ef5ee175","text":" wipe anything unless you explicitly choose ","translated":" 不会删除任何内容,除非您明确选择 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:11Z"} -{"cache_key":"67db94076306469669c78e1176f5af9cd7a5e6ba4528ce053e203e96bd12fdc7","segment_id":"help/index.md:cad44fbae951d379","source_path":"help/index.md","text_hash":"cad44fbae951d3791565b0cee788c01c3bd10e0176167acb691b8dba0f7895f8","text":"Gateway logging","translated":"Gateway 日志记录","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:24:51Z"} -{"cache_key":"681929db09dc269d58c525c09744bdebddf03842689478831d1f59575161d74f","segment_id":"index.md:274162b77e02a189","source_path":"index.md","text_hash":"274162b77e02a1898044ea787db109077a2969634f007221c29b53c2e159b0cc","text":". Plugins add Mattermost (Bot API + WebSocket) and more.\nOpenClaw also powers the OpenClaw assistant.","translated":"。插件可添加 Mattermost(Bot API + WebSocket)等更多渠道支持。\nOpenClaw 同时也驱动着 OpenClaw 助手。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:27:58Z"} -{"cache_key":"685f06b3659dc0d7b4f41f7b15a9722e9de70a2794b168650f8414873d7c168f","segment_id":"index.md:7ac362063b9f2046","source_path":"index.md","text_hash":"7ac362063b9f204602f38f9f1ec9cf047f03e0d7b83896571c9df6d31ad41e9c","text":"Nodes","translated":"节点","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:13Z"} -{"cache_key":"6871c777c178113b08a646e4826f7bc149fa796d803947ab84e9d7a8af45cea7","segment_id":"environment.md:1ec31258a6b45ea9","source_path":"environment.md","text_hash":"1ec31258a6b45ea903cd76f5b0190a99ab56afff6241a04f0681eb12b7a02484","text":"Env var equivalents:","translated":"环境变量 等效项:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:13Z"} -{"cache_key":"687dd62cc9018f0e74dadb0abaab9318503de6d5071253dca9c789f4352b9efa","segment_id":"start/wizard.md:fd3ef9f6b8315cd4","source_path":"start/wizard.md","text_hash":"fd3ef9f6b8315cd4cdfef9c6e295ed50e858a820f31a9b6555366054af144907","text":"Recommended: set up a Brave Search API key so the agent can use ","translated":"推荐:设置 Brave Search API 密钥,以便智能体可以使用 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:17Z"} -{"cache_key":"68c5c21091478bdd701de8955d662e20de4e91e7cf7626d3a7ad444230c802d0","segment_id":"index.md:6b8ebac7903757ce","source_path":"index.md","text_hash":"6b8ebac7903757ce7399cc729651a27e459903c24c64aa94827b20d8a2a411d2","text":"For Tailnet access, run ","translated":"如需 Tailnet 访问,请运行 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:45Z"} -{"cache_key":"68e1b25eafa11dfe6ffd16682d3f4f72d3f1774db82b6cd7b08e0dc617d7dbf4","segment_id":"start/wizard.md:1e3abf61a37e3cad","source_path":"start/wizard.md","text_hash":"1e3abf61a37e3cad36b11b459b1cc39e76feb6a0c369fe5270957468288dcc5c","text":"If ","translated":"如果 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:01Z"} -{"cache_key":"690712dd7f5a91ba48c9cbced5b6696f3db30d836271a363f94e57d84e674554","segment_id":"start/wizard.md:873f11af0a4e26ee","source_path":"start/wizard.md","text_hash":"873f11af0a4e26ee426ad19295a3f36d0256b0a6da1e0744832fe62d7a0cdf27","text":"Model/Auth","translated":"模型/认证","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:44Z"} -{"cache_key":"690bea2d411c2b07780745f517baf643d26686e96f534e5bb1f2eaaf441448b5","segment_id":"start/getting-started.md:d059230b2daf747b","source_path":"start/getting-started.md","text_hash":"d059230b2daf747b7ca874e806c334070d67c8f02fa017ad61f2701d61354d55","text":"Recommended Anthropic path:","translated":"推荐的 Anthropic 路径:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:30Z"} -{"cache_key":"69223c700e3933064992a3b935b8e443e6475dd5e5f63ba2447d85b76f68b53e","segment_id":"environment.md:61115f6649792387","source_path":"environment.md","text_hash":"61115f664979238731a390e84433a818965b7eaf1d38fa5b4b1507c33ef28c91","text":"Precedence (highest → lowest)","translated":"优先级(从高到低)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:28Z"} -{"cache_key":"697717108124b156f8f1fb7c823e71fd6d5bbbe71e43ed8b4c62e2bbbdafa7bd","segment_id":"environment.md:a16d7a83f4f565a8","source_path":"environment.md","text_hash":"a16d7a83f4f565a8d1aca9d8646b3eaa76308e8307be4634f9261ed0a0dccd67","text":"Config `env` block","translated":"配置 `env` 块","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:11:45Z"} -{"cache_key":"698c8d3774af0dc5196c75622b024794a3f45792871ab62821e75607b64fe050","segment_id":"environment.md:cdb4ee2aea69cc6a","source_path":"environment.md","text_hash":"cdb4ee2aea69cc6a83331bbe96dc2caa9a299d21329efb0336fc02a82e1839a8","text":".","translated":"。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:54Z"} -{"cache_key":"69b9351215888d772cb7294618ccac031ec230dc7dd3d94db9a0fc323fdd68e1","segment_id":"index.md:be48ae89c73a75da","source_path":"index.md","text_hash":"be48ae89c73a75da3454d565526d777938c20664618905a9bc77d6a0a21a689d","text":"\"EXFOLIATE! EXFOLIATE!\"","translated":"\"去角质!去角质!\"","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:50Z"} -{"cache_key":"6a0067f355b734f73cc5d06c2415e833a0237f4e1c0f086d4be41b01ca666065","segment_id":"help/index.md:frontmatter:summary","source_path":"help/index.md:frontmatter:summary","text_hash":"aece82a2d540ab1a9a21c7b038127cae6e9db2149491564bb1856b6f8999f205","text":"Help hub: common fixes, install sanity, and where to look when something breaks","translated":"帮助中心:常见修复方法、安装健全性检查,以及出问题时该去哪里排查","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:24:25Z"} -{"cache_key":"6a24e3ca10f074b02180cd94a12d97d06ba02d3ed50c0b414b6e82f6a567e2aa","segment_id":"start/wizard.md:6a40edf1fc87a29f","source_path":"start/wizard.md","text_hash":"6a40edf1fc87a29f243a7eefdbed57d19bfe16ab2e039d7ae1a44c097297e2f3","text":"WhatsApp","translated":"WhatsApp","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:44:14Z"} -{"cache_key":"6a33a478d12a3b427e017a6e516fcb413a3a5342725b674ac3ac5c9e5aca3973","segment_id":"index.md:c0aa8fcb6528510a","source_path":"index.md","text_hash":"c0aa8fcb6528510aea46361e8c871d88340063926a8dfdd4ba849b6190dec713","text":": it is the only process allowed to own the WhatsApp Web session. If you need a rescue bot or strict isolation, run multiple gateways with isolated profiles and ports; see ","translated":":它是唯一允许拥有 WhatsApp Web 会话 的进程。如果需要救援机器人或严格隔离,请使用隔离的配置文件和端口运行多个网关;参见 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:56Z"} -{"cache_key":"6a386646cb5e09a391827ea6dd82475e9d6edbe2c6acbd9c797f030f3c24bcff","segment_id":"index.md:bf0e823c81b87c5d","source_path":"index.md","text_hash":"bf0e823c81b87c5de79676155debf20a29b52d6d7eb7e77deda73a56d0afbaaa","text":"🧠 ","translated":"🧠 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:41Z"} -{"cache_key":"6a47aab59ec3c6e8096fa2733fa963a3233dc254b4ec8a306635e196ffe0928f","segment_id":"index.md:316cd41f595f3095","source_path":"index.md","text_hash":"316cd41f595f3095f149f98af70f77ab85404307a1505467ee45a26b316a9984","text":"Guided setup (recommended):","translated":"引导式设置(推荐):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:06Z"} -{"cache_key":"6a5441f83cd64d6920441e8eedade5c472aa328b00ed9f05ccf638493bce1b10","segment_id":"environment.md:d4a67341570f4656","source_path":"environment.md","text_hash":"d4a67341570f4656784c5f8fe1bfb48a738ace57b52544977431d50e2b718099","text":"FAQ: env vars and .env loading","translated":"常见问题:环境变量 和 .env 加载","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:34Z"} -{"cache_key":"6a914cfd2e0ac0d7ccc179c0361f67fc4574234e9d8cbfce616285591ed37b2e","segment_id":"start/wizard.md:769e62863db91849","source_path":"start/wizard.md","text_hash":"769e62863db91849711d2b06aa7480c8874950c7764035a155268ae80bcaaa5d","text":". Docs: ","translated":"存储。文档: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:25Z"} -{"cache_key":"6ac32faba08302a413cf9de9061c4f7ab03bd96929649f2c17c6a6d2b1c25ce2","segment_id":"environment.md:f0442e6e05ccca16","source_path":"environment.md","text_hash":"f0442e6e05ccca160d17de0e7d509891b91b921366b2202b2b5c80435824e140","text":"Two equivalent ways to set inline env vars (both are non-overriding):","translated":"两种等效的内联环境变量设置方式(两者都不会覆盖):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:26:07Z"} -{"cache_key":"6af973157939ccd33570e5047d622de4263119466c45f46681f300f577b79faf","segment_id":"start/getting-started.md:7bac3209ac343388","source_path":"start/getting-started.md","text_hash":"7bac3209ac3433880eb9d1d0a1867cd9a0617f43ca27493375bc005051d869b7","text":"OAuth credentials (legacy import): ","translated":"OAuth 凭据(旧版导入): ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:36Z"} -{"cache_key":"6b0625352ff5092cab159cf3242fc10826b63c47c7d7524d3c3ee8e85cbe8f9f","segment_id":"index.md:5afbb1c887f6d850","source_path":"index.md","text_hash":"5afbb1c887f6d8501dba36cd2113d8f8b6ce6fa711a0d3e7efdc66f170abd2c2","text":"Cron jobs","translated":"定时任务","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:05:22Z"} -{"cache_key":"6b14f5e839df1e54026ee6d3db5886a6e9360039fd681101a4a9a2b101ff0919","segment_id":"index.md:084514e91f37c3ce","source_path":"index.md","text_hash":"084514e91f37c3ce85360e26c70b77fdc95f0d3551ce309db96fbcf956a53b01","text":"Dashboard (browser Control UI)","translated":"仪表盘(浏览器控制界面)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:21Z"} -{"cache_key":"6b3dbfa396df75c279946f5b8741a67863a0107d3f08c55dc642a8fac173a4c8","segment_id":"index.md:1074116f823ec992","source_path":"index.md","text_hash":"1074116f823ec992e76d7e8be19d3235fec5ddd7020562b06e7242e410174686","text":"Remote use","translated":"远程使用","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:11Z"} -{"cache_key":"6b44e5cb8d21527ef6ad754e2792b9416080f2a132c8fd7b6d431fc76113aad9","segment_id":"environment.md:a42cc4a7174c83a8","source_path":"environment.md","text_hash":"a42cc4a7174c83a853752b3e74cb001a234f3eca099688fdf0dd2540c60bb1e2","text":" expected keys:","translated":" 预期的键:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:22:25Z"} -{"cache_key":"6c18bb32586b6c812ebf5323b8ed442c63be7b4014bc62e51f0d7f5eb46d223b","segment_id":"environment.md:582967534d0f909d","source_path":"environment.md","text_hash":"582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf","text":" in ","translated":" 在 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:54Z"} -{"cache_key":"6c1b9632694258c227417b61df6433ac71eca1f2d35ff31cb5e145a7188dacfe","segment_id":"start/getting-started.md:d7849463c3ab6a49","source_path":"start/getting-started.md","text_hash":"d7849463c3ab6a496d77b8e6745d00ad430324bc5ed419a859f7c9e494102d68","text":"Manual run (foreground):","translated":"手动运行(前台):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:51Z"} -{"cache_key":"6c3d2263be9d0d6dd77934bd87f882599e2e9449e67bdee4388f84ab0aa6571b","segment_id":"start/wizard.md:698fdfc9c55bd3e4","source_path":"start/wizard.md","text_hash":"698fdfc9c55bd3e4ed5a9365317ae70aac20783ec38057088da27012a470a901","text":"Gateway port ","translated":"Gateway 端口 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:50Z"} -{"cache_key":"6cbd9a98f43c5cd7ee42cde62e8bdf2fab7d10c65a1aebd8540be50477452284","segment_id":"environment.md:6db0742daaf9f191","source_path":"environment.md","text_hash":"6db0742daaf9f191ab7816d2c9d317b1ea1693453a8c63b95af8b01477e0f5bb","text":" runs your login shell and imports only ","translated":" 运行你的登录 shell,并仅导入 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:26:12Z"} -{"cache_key":"6ce678386b3562455734243bc70c673a1b20aeb902456025275220465b508211","segment_id":"index.md:274162b77e02a189","source_path":"index.md","text_hash":"274162b77e02a1898044ea787db109077a2969634f007221c29b53c2e159b0cc","text":". Plugins add Mattermost (Bot API + WebSocket) and more.\nOpenClaw also powers the OpenClaw assistant.","translated":"。插件可添加 Mattermost(Bot API + WebSocket)等更多平台。\nOpenClaw 还为 OpenClaw 助手提供支持。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:01Z"} -{"cache_key":"6d11b3d022e2bde1caefb2917a26aa0169fa2e6e13c62d6595b010d9130fecb9","segment_id":"environment.md:87e89abb4c1c551f","source_path":"environment.md","text_hash":"87e89abb4c1c551fe08d355d097f18b8de78edca5f556997085681662fce8eed","text":"Config ","translated":"配置 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:57Z"} -{"cache_key":"6d347e25d4ffcc9340ab0172ccb04190e3780bc68d026152202edbdce466b09e","segment_id":"index.md:82ba9b60b12da3ab","source_path":"index.md","text_hash":"82ba9b60b12da3ab4e7dbcb0d7d937214cff80c82268311423a6dc8c4bc09df5","text":"OpenClaw 🦞","translated":"OpenClaw 🦞","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:48Z"} -{"cache_key":"6d365b29cf4305b02714d7c3f130301954ffc45574d088db9bb553d065f20854","segment_id":"index.md:1e37e607483201e2","source_path":"index.md","text_hash":"1e37e607483201e2152d2e9c68874dd4027648efdd9cfccb7bf8c9837398d143","text":"), serving ","translated":"),提供 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:11Z"} -{"cache_key":"6d78259f49a7bf9fd44a58e590c3f18b7646b810d8e07e7d34b5fb0e73aa5844","segment_id":"start/wizard.md:fe21d672d145bf9d","source_path":"start/wizard.md","text_hash":"fe21d672d145bf9dcbb12ba1cc1677a0b8718bed342f5bfeb774b2996fed9889","text":"Lets you choose a node manager: ","translated":"让您选择一个 Node 管理器: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:45:45Z"} -{"cache_key":"6da895990489d77240c02d6c6f51892e4f6b7a5ec658cca2e3f6e92084fa7a72","segment_id":"index.md:5cf9ea2e20780551","source_path":"index.md","text_hash":"5cf9ea2e2078055129b38cfbc394142ca6ca41556bd6e31cbd527425647c1d1e","text":"One Gateway per host (recommended)","translated":"每台主机一个 Gateway(推荐)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:53Z"} -{"cache_key":"6dc2e2b52833ce2b82f2a886285fffff2f3a6e1d9d23875ec57d61f1328cda06","segment_id":"environment.md:668e5590b5bb9990","source_path":"environment.md","text_hash":"668e5590b5bb9990eeb25bf657f7d17281a4c613ee4442036787cd4b2efd22bb","text":"If the config file is missing entirely, step 4 is skipped; shell import still runs if enabled.","translated":"如果配置文件完全缺失,则跳过第 4 步;如果已启用,shell 导入仍会运行。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:41:07Z"} -{"cache_key":"6e0b579a98c31961263b11f7805c45b08b9850506746275df639a7a236ceccf5","segment_id":"index.md:496bcd8a502babde","source_path":"index.md","text_hash":"496bcd8a502babde0470e7105dfed7ba95bbc3193b7c6ba196b3ed0997e84294","text":"Voice notes","translated":"语音消息","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:56Z"} -{"cache_key":"6e109ac5e9791bc39a36e94e14a107a5e270e18cd20cd2b8d50132d6170c9dc9","segment_id":"environment.md:6f59001999ef7b71","source_path":"environment.md","text_hash":"6f59001999ef7b7128bab80d2034c419f3034497e05f69fbdf67f7b655cdc173","text":"Configuration: Env var substitution","translated":"配置:环境变量替换","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:47:07Z"} -{"cache_key":"6e297c0b91d3a16fec1d93183437778addf7c0908be226b39d4ee3dacab5c6f4","segment_id":"start/getting-started.md:b1ff7bd17092d95e","source_path":"start/getting-started.md","text_hash":"b1ff7bd17092d95ea7811719ce3df6d79b0c3a576695636fc411f2d95dc908b2","text":"Mattermost","translated":"Mattermost","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:30Z"} -{"cache_key":"6e3de6afce0bcbadbe662882ab64575df2fa60edee81930593c1f854e7bed6e7","segment_id":"start/wizard.md:de500b08e6825815","source_path":"start/wizard.md","text_hash":"de500b08e6825815c64066def01809cd44b9b86fe3de9142c48edb43644e6ec5","text":"Z.AI example:","translated":"Z.AI 示例:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:47:24Z"} -{"cache_key":"6e7bb00810a1c89548ff84b0cadc9b0b1f2f3c12625ab3fcbc78216c60a02b81","segment_id":"help/index.md:6cb77499abdccd9a","source_path":"help/index.md","text_hash":"6cb77499abdccd9a2dbb7c93a4d31eed01613dda06302933057970df9ecdeb54","text":"Logs:","translated":"日志:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:21Z"} -{"cache_key":"6ed4c62933bde0307cf9d37c7cb57e20d5fecc3da59e7ea185f4c101f80f4344","segment_id":"index.md:1eb6926214b56b39","source_path":"index.md","text_hash":"1eb6926214b56b396336f22c22a6f8a4c360cfe7109c8be0f9869655b9ff6235","text":"Pairing (DM + nodes)","translated":"配对(私聊 + 节点)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:34Z"} -{"cache_key":"6f2bf42e3ab6c9dfe240a6e878f8d322a9ec3956cf722b0d0b6aa221467d33cd","segment_id":"start/wizard.md:fd5f5ef720b423af","source_path":"start/wizard.md","text_hash":"fd5f5ef720b423af38c9113f3fce3be2eeccfef9f35b56c075bc8145297ebe59","text":" (auto-installs UI deps).","translated":" (自动安装 UI 依赖项)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:46:09Z"} -{"cache_key":"6f721a6913c75aac92f1890a4942631c3370e08f7e4180950dcc08a03e0765ba","segment_id":"environment.md:9c85ab59cb358b12","source_path":"environment.md","text_hash":"9c85ab59cb358b1299c623e16f52f3aee204a81fb6d1c956e37607a220d13b08","text":"You can reference env vars directly in config string values using `${VAR_NAME}` syntax:","translated":"你可以使用 `${VAR_NAME}` 语法在配置字符串值中直接引用环境变量:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:11:56Z"} -{"cache_key":"6f9e33ab431225304bd1fa8a39bb0efd5d4279d45975ebd5b20f24e09bb98cbc","segment_id":"start/wizard.md:531995e8b52db462","source_path":"start/wizard.md","text_hash":"531995e8b52db462df5a6b23a5f7af4d5c57415a397438b002364edebcdc1e14","text":" writes ","translated":" 写入 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:48:45Z"} -{"cache_key":"6fc0fd840e70231dec1ea7ea900c6bab5c29245170836fc0625f3898b05f4edb","segment_id":"index.md:b5ccaf9b1449291c","source_path":"index.md","text_hash":"b5ccaf9b1449291c92f855b8318aeb2880a9aa1a75272d17f55cf646071b3eae","text":"Gmail hooks (Pub/Sub)","translated":"Gmail 钩子(Pub/Sub)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:53:53Z"} -{"cache_key":"6fe259de45e43265b4853300aa3cd6972b5cbbd607ab967eed0618c0f860247a","segment_id":"help/index.md:5c94724fa7810fa9","source_path":"help/index.md","text_hash":"5c94724fa7810fa9902e565cf66c5f5a973074f2961fcd3a40bad4ee4aeca5e0","text":"If you want a quick “get unstuck” flow, start here:","translated":"如果你想快速了解\"快速排障\"流程,请从这里开始:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:39:33Z"} -{"cache_key":"70155d1dc5c21119f33f83bea22521d80b2d73a2d089a04817d3cf20cb55177c","segment_id":"index.md:93c89511a7a5dda3","source_path":"index.md","text_hash":"93c89511a7a5dda3b3f36253d17caee1e31f905813449d475bc6fed1a61f1430","text":"common fixes + troubleshooting","translated":"常见修复 + 故障排除","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:22Z"} -{"cache_key":"70626932ec406bd2253ce4134561af2088dc5ee89aa51a4336f95288b4f863c2","segment_id":"environment.md:a16d7a83f4f565a8","source_path":"environment.md","text_hash":"a16d7a83f4f565a8d1aca9d8646b3eaa76308e8307be4634f9261ed0a0dccd67","text":"Config `env` block","translated":"配置 `env` 块","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:19:30Z"} -{"cache_key":"70d246c2dab8d15be4dc7dcf914f0df1b95aeb517a09c88d86fa095e1c465095","segment_id":"index.md:268ebcd6be28e8d8","source_path":"index.md","text_hash":"268ebcd6be28e8d853ace3a6e28f269fbda1343b53e3f0de97ea3d5bf1a0e33e","text":"Clawd","translated":"Clawd","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:06:07Z"} -{"cache_key":"71667555ad1cea654225fec33df1804c97a0b8167affbf3d3c426ccb778e780a","segment_id":"start/wizard.md:82e1216ede141cb1","source_path":"start/wizard.md","text_hash":"82e1216ede141cb1553d20be7356c3f1ab9da9a4a05303cf7cd05ef01142558f","text":"Gateway settings (port/bind/auth/tailscale)","translated":"Gateway 设置(端口/绑定/认证/Tailscale)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:23Z"} -{"cache_key":"7170dcd349905701fd3cde7dc5bce0aed2618717e87ffa06e9ab230041f689a1","segment_id":"environment.md:cdb4ee2aea69cc6a","source_path":"environment.md","text_hash":"cdb4ee2aea69cc6a83331bbe96dc2caa9a299d21329efb0336fc02a82e1839a8","text":".","translated":"。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:26Z"} -{"cache_key":"724a450b6cdfc09dd0fc5acf94bb7f20a45c43e524810239d0e6e7cac65ff74b","segment_id":"index.md:bd293e4db98037bc","source_path":"index.md","text_hash":"bd293e4db98037bc9da5137af50453ac9c81b49e14eb4c47f121b12bed880877","text":" — Direct chats collapse into shared ","translated":" — 直接聊天合并到共享的 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:59Z"} -{"cache_key":"72d5ce369dd6489f427c02710fae70f6426a51de9441678410a023761cee215b","segment_id":"start/wizard.md:8f7c7d2f15e90b42","source_path":"start/wizard.md","text_hash":"8f7c7d2f15e90b420fb6f2cc7632d7d7a433bc94eeb262d9718286e5ffd9b365","text":"Related docs","translated":"相关文档","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:49:00Z"} -{"cache_key":"730b6369e65b8f27f57a90f6ee355beca28d783793767209a7cfe7beb736769b","segment_id":"start/wizard.md:eda31fe8fb873697","source_path":"start/wizard.md","text_hash":"eda31fe8fb873697fd7d5bfba08f263eaa917808a644bddd2b6d89d3a6b1c868","text":"QuickStart vs Advanced","translated":"快速入门与高级模式","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:30Z"} -{"cache_key":"73164a8584f9cc4e546493100199d4ebcbb65ce74c33e21d06da689c6d7b9328","segment_id":"start/wizard.md:ce85fecfbffa2746","source_path":"start/wizard.md","text_hash":"ce85fecfbffa2746f0a9b66464140eb2ed5a085ce85fff062ef0ff8b5686a0a5","text":".\nSessions are stored under ","translated":"下。会话存储在 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:48:54Z"} -{"cache_key":"73343b447da60470e1e14745df6653212cfb901cb8591540364f6cc906d42fd8","segment_id":"index.md:f1e3b32c8eb0df8e","source_path":"index.md","text_hash":"f1e3b32c8eb0df8ea105f043edf614005742c15581e2cebc5a9c3bafb0b90303","text":"Multi-agent routing","translated":"多 智能体 路由","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:43Z"} -{"cache_key":"7354cca5c4abf7f22290854ebf29a79803372316786f435b6d197b844847c177","segment_id":"start/wizard.md:fdd0a77c1e77ac7b","source_path":"start/wizard.md","text_hash":"fdd0a77c1e77ac7bffeea35de300966019f55c682bd3046ae045d8d5db9e68cb","text":"Writes ","translated":"写入 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:48:04Z"} -{"cache_key":"7364ee790ee697a9be18a8878b36241f6087253c4952dec1d7f9ed766fb7ba57","segment_id":"index.md:c491e0553683a70a","source_path":"index.md","text_hash":"c491e0553683a70a2fb52303f74675d2f7b725814ed70d5167473cb5fbe46450","text":"@steipete","translated":"@steipete","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:05:55Z"} -{"cache_key":"7396e8f216f016e9505d0ce0709809834376675cca202b48cc8592fdc8461357","segment_id":"environment.md:f7e239a42b7cd986","source_path":"environment.md","text_hash":"f7e239a42b7cd986a1558fed234e975ed2e96e9d37cf0a93f381778c461c89dd","text":"OpenClaw pulls environment variables from multiple sources. The rule is ","translated":"OpenClaw 从多个来源获取环境变量。规则是 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:21Z"} -{"cache_key":"73b0734779c4cb925c37ffe5e84b08453879c88667f95afe39d096031f55d1ec","segment_id":"environment.md:aac7246f5e97142c","source_path":"environment.md","text_hash":"aac7246f5e97142c3f257b7d8b84976f10c29e1b89804bb9d3eb7c43cc03cb8e","text":"Environment variables","translated":"环境变量","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:21:55Z"} -{"cache_key":"73c3930f846d6be7446b678ee4181328fead10032d5ac3217dd5a7dad818f119","segment_id":"environment.md:6db0742daaf9f191","source_path":"environment.md","text_hash":"6db0742daaf9f191ab7816d2c9d317b1ea1693453a8c63b95af8b01477e0f5bb","text":" runs your login shell and imports only ","translated":" 运行你的登录 shell 并仅导入 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:49Z"} -{"cache_key":"740260cd2027024814eb7dbbe5605642907d5720259bea069322bf4422ab7abe","segment_id":"index.md:e1b33cfa2a781bde","source_path":"index.md","text_hash":"e1b33cfa2a781bde9ef6c1d08bf95993c62f780a6664f5c5b92e3d3633e1fcf8","text":" (@nachoiacovino, ","translated":" (@nachoiacovino, ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:53Z"} -{"cache_key":"741c513df5edc25161f93a87a83b3335320749b9560fb3dedddcd1a9e02f8309","segment_id":"start/wizard.md:9f6f919dc1088468","source_path":"start/wizard.md","text_hash":"9f6f919dc1088468f8197ef0c27501e1c0a71a94b9faed9d363410305d3a472b","text":"Agent workspace","translated":"智能体工作区","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:51Z"} -{"cache_key":"743cddc057adf1927666ea67a9d672d0e924c93c938fac5086b278e6d0dac789","segment_id":"index.md:e3209251e20896ec","source_path":"index.md","text_hash":"e3209251e20896ecc60fa4da2817639f317fbb576288a9fc52d11e5030ecc44a","text":"Windows (WSL2)","translated":"Windows (WSL2)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:53:40Z"} -{"cache_key":"74759aa496b1b361eadf49b7e6245708b41bb91d571dc6a34e0f79ab602f23f9","segment_id":"environment.md:aac7246f5e97142c","source_path":"environment.md","text_hash":"aac7246f5e97142c3f257b7d8b84976f10c29e1b89804bb9d3eb7c43cc03cb8e","text":"Environment variables","translated":"Could you please provide the file path or the full text about \"Environment variables\" that you'd like me to translate?","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:11:37Z"} -{"cache_key":"74784eac2b412aa6a24c3e0d7f66e14ac2ac8aeb85905dafd36f4f6c680fd94d","segment_id":"environment.md:39d9dca6df060f67","source_path":"environment.md","text_hash":"39d9dca6df060f6708b30f0f6b1581105c607e96a66f282bf4a0fe75e92dc205","text":"Env var substitution in","translated":"环境变量替换在","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:56Z"} -{"cache_key":"74a32b88954158955f70bb053e86f28337b079cf11feb27cec6a4af1d9926f6b","segment_id":"start/getting-started.md:13bf3a75f8be5632","source_path":"start/getting-started.md","text_hash":"13bf3a75f8be5632d9f92212f0c5a61750a0b4654af5db87a9d91ade89b72e5b","text":"Default posture: unknown DMs get a short code and messages are not processed until approved.\nIf your first DM gets no reply, approve the pairing:","translated":"默认策略:未知私信会收到一个短码,消息在批准之前不会被处理。\n如果您的第一条私信没有收到回复,请批准配对:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:39Z"} -{"cache_key":"74b57577f77fd5b865970d086c56b3f7d760c94e57a5c11babad0173e6b6bc1f","segment_id":"start/getting-started.md:df3db5b08f6e98f3","source_path":"start/getting-started.md","text_hash":"df3db5b08f6e98f31a9242361eb5d1f325c35f4acbb6c7cd8ac9afa85bf8eaa7","text":"Local vs Remote","translated":"本地 vs 远程","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:00Z"} -{"cache_key":"753971a27214ecb4551eb400d1bace8931dd2b658bef6bc8d55506b6adeba974","segment_id":"environment.md:668e5590b5bb9990","source_path":"environment.md","text_hash":"668e5590b5bb9990eeb25bf657f7d17281a4c613ee4442036787cd4b2efd22bb","text":"If the config file is missing entirely, step 4 is skipped; shell import still runs if enabled.","translated":"如果配置文件完全缺失,则跳过第 4 步;如果已启用,shell 导入仍会运行。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:22:07Z"} -{"cache_key":"759d3f3cb39af3e2d57e711d9680a2b999ef3bc08a4184eccd9b1d53c18f7b1f","segment_id":"index.md:95cae5ed127bd44d","source_path":"index.md","text_hash":"95cae5ed127bd44dcc30345a1925d77f333284b43a6f97832f149a63dc38e0e0","text":"The wizard now generates a gateway token by default (even for loopback).","translated":"向导 现在默认会生成网关令牌(即使是回环连接)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:06Z"} -{"cache_key":"75deb7505d1a042e24a4c83cdddf479326929a80edeffcfaa49863bf115ab848","segment_id":"help/index.md:24669ff48290c187","source_path":"help/index.md","text_hash":"24669ff48290c1875d8067bbd241e8a55444839747bffb8ab99f3a34ef248436","text":"Doctor","translated":"诊断工具","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:39:58Z"} -{"cache_key":"76148f338fd0041621eb7cda1759d78690a3cb0d0d9a1ca8c2cd4af02dfff679","segment_id":"start/wizard.md:9022ac86cfbabdac","source_path":"start/wizard.md","text_hash":"9022ac86cfbabdac3512fdd7797b7f0a3db628d4873e0b3d64b2f5c752724d03","text":"Tailscale exposure ","translated":"Tailscale 暴露 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:00Z"} -{"cache_key":"762684ab35f0d829663da7f4de49060030ad02772df37776113660266af70236","segment_id":"help/index.md:729bc562eec2658b","source_path":"help/index.md","text_hash":"729bc562eec2658bd11ffdd522fe5277177dc73e86eaca7baac0b472a4d8f8b2","text":"If you’re looking for conceptual questions (not “something broke”):","translated":"如果你在寻找概念性问题的解答(而不是\"出了问题\"):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:32Z"} -{"cache_key":"762e4d6415fd6b11bfb7837a3d751030659263ba7f6292f3defcf734097ada17","segment_id":"environment.md:6f59001999ef7b71","source_path":"environment.md","text_hash":"6f59001999ef7b7128bab80d2034c419f3034497e05f69fbdf67f7b655cdc173","text":"Configuration: Env var substitution","translated":"配置:环境变量替换","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:13:05Z"} -{"cache_key":"76653677000dc673dea8f2bff5f0d86e7118627d575314948b1592b82cd490be","segment_id":"environment.md:baa5be7f6320780b","source_path":"environment.md","text_hash":"baa5be7f6320780bd7bb7b7ddbb8cd1ffb26ccf7d94d363350668c50aedcf95f","text":" (applied only if missing).","translated":" (仅在缺失时应用)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:56Z"} -{"cache_key":"76934bd605258decffe7f40a10419e7a19405bc7a09f19c65a9447682a805337","segment_id":"start/wizard.md:8e70d4cdad7bdb70","source_path":"start/wizard.md","text_hash":"8e70d4cdad7bdb70b333c34e14862f46905fbfd6fb678a968f857747f2ee2389","text":"Pick a default model from detected options (or enter provider/model manually).","translated":"从检测到的选项中选择默认模型(或手动输入提供商/模型)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:22Z"} -{"cache_key":"76be6836deb53495879f2e5cc5f57af37d12f5fb67d27f22ecc8c7dc885a6c7a","segment_id":"index.md:4b4051e77af8844f","source_path":"index.md","text_hash":"4b4051e77af8844fcf86a298214527e7840938258f99bfe97b900bbc0d8d2f4b","text":"The dashboard is the browser Control UI for chat, config, nodes, sessions, and more.\nLocal default: http://127.0.0.1:18789/\nRemote access: ","translated":"仪表板是用于聊天、配置、节点、会话 等功能的浏览器控制界面。\n本地默认地址:http://127.0.0.1:18789/\n远程访问: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:33Z"} -{"cache_key":"76ffac273c1ab348f20e97d66f7d9a8218789d2df1be41d676e824f64c949ef4","segment_id":"start/wizard.md:72ea058924a0acec","source_path":"start/wizard.md","text_hash":"72ea058924a0acecc4dd9dae83410a37dd2c43d9b526fb770f88685d27aed0b1","text":"Remote mode","translated":"远程模式","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:34Z"} -{"cache_key":"7748e8a6d7f7a768cc6003487448b27848640b4e9df17154fcf6ad93c707b4aa","segment_id":"environment.md:frontmatter:read_when:0","source_path":"environment.md:frontmatter:read_when:0","text_hash":"90fc0487bff88009979cff1061c1a882df8c3b1baa9c43538331d9d5dab15479","text":"You need to know which env vars are loaded, and in what order","translated":"你需要了解加载了哪些环境变量,以及加载的顺序","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:21:48Z"} -{"cache_key":"7749f2ac757311f26619b43b362bfc9265176ac801f7a38b42ab835c8af89d85","segment_id":"environment.md:6863067eb0a2c749","source_path":"environment.md","text_hash":"6863067eb0a2c7499425c6c189b2c88bac55ca754285a6ab1ef37b75b4cfad4d","text":"See ","translated":"参见 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:41:30Z"} -{"cache_key":"775fa7e7f44ee6a3a24c821c866f68606b4ecad281b47f4b744de729460eb521","segment_id":"index.md:cec2be6f871d276b","source_path":"index.md","text_hash":"cec2be6f871d276b45d13e3010c788f01b03ae2f1caca3264bbf759afacace46","text":"Telegram Bot","translated":"Telegram 机器人","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:58Z"} -{"cache_key":"7781b8121d68b25732c0ef1ac9c2b3c6573a376f2912bd6a3860f4d7f6bf3e45","segment_id":"environment.md:08ba1569cc7ada49","source_path":"environment.md","text_hash":"08ba1569cc7ada49ef908e8f19b1d36252072d5876086ae6726c55672d571603","text":" non-overriding):","translated":" 非覆盖的):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:31Z"} -{"cache_key":"77936e1851104e6dac3b5785a85c10f838ca0173ad387391588eb25f884c3a59","segment_id":"environment.md:e234227b0e001687","source_path":"environment.md","text_hash":"e234227b0e001687821541fac3af38fc6be293ec6e13910c6826b9afc8ca33be","text":" syntax:","translated":" 语法:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:17:01Z"} -{"cache_key":"77a1d6fe1f2415835e41760b0765c3b93b4853664de26c500cf7acf3c512d60e","segment_id":"index.md:7ac362063b9f2046","source_path":"index.md","text_hash":"7ac362063b9f204602f38f9f1ec9cf047f03e0d7b83896571c9df6d31ad41e9c","text":"Nodes","translated":"节点","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:57Z"} -{"cache_key":"77b6a43a45b36b25b51859a5b976fa12609b6d19ed351bc0e84fae2290d32da9","segment_id":"help/index.md:2adc964c084749b1","source_path":"help/index.md","text_hash":"2adc964c084749b1f2d8aef24030988b667dbda2e38a6a1699556c93e07c1cea","text":"Start here","translated":"从这里开始","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:12Z"} -{"cache_key":"7806b590e1e2ff8ab2244875f7a2c370ab3b11462fd2061e5f4af9cf72f70d19","segment_id":"start/wizard.md:9c706a2bb9ebcb20","source_path":"start/wizard.md","text_hash":"9c706a2bb9ebcb206633616f2a40867b0c02716657ac4c0e95c7c1939287d3d8","text":"; auth profiles live in ","translated":";认证配置存储在 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:31Z"} -{"cache_key":"78161c8de8a14607cd003796d4c4ace7048f9116ecbe036601136d7f0cef4ff3","segment_id":"start/getting-started.md:bfd99edf844f6205","source_path":"start/getting-started.md","text_hash":"bfd99edf844f62050af2f7d37df7cfa7f651b8e1be341eb4f07c3849ca4efc43","text":"Fastest chat: open the Control UI (no channel setup needed). Run ","translated":"最快聊天方式:打开控制界面(无需设置渠道)。运行 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:33Z"} -{"cache_key":"785cae01bc172c4c47e2e82cda4c5afd7d37d7069a008e44c8a4176eeacafe67","segment_id":"help/index.md:a8ab86b9313a9236","source_path":"help/index.md","text_hash":"a8ab86b9313a92362150f5e5ba8a19de4ee52f2e3162f9bd2bc6cf128a2fcd18","text":"If you’re looking for conceptual questions (not “something","translated":"如果你在寻找概念性问题(不是\"出了什么","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:00Z"} -{"cache_key":"78ae0fabb1aab02156d5bf1b4e148ba155369b079aa0b733aca5a750a3d0cdc2","segment_id":"index.md:329f3c913c0a1636","source_path":"index.md","text_hash":"329f3c913c0a16363949eb8ee7eb0cda7e81137a3851108019f33e5d18b57d8f","text":"Switching between npm and git installs later is easy: install the other flavor and run ","translated":"之后在 npm 和 git 安装之间切换很简单:安装另一种方式然后运行 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:30Z"} -{"cache_key":"791458a3464d7dd0036471e90590958905611942f9f0aefd8917c701e4e587d4","segment_id":"start/wizard.md:0516de0bbbd36c95","source_path":"start/wizard.md","text_hash":"0516de0bbbd36c95c5c45902d43caf2abdab59363114c4d6abae961f6ed1c1cb","text":" imply non-interactive mode. Use ","translated":" 意味着非交互模式。请使用 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:50Z"} -{"cache_key":"79156ca764918ee2f487da88a8917572551bbb6cac71a256748ba30bce781f0e","segment_id":"index.md:96be070791b7d545","source_path":"index.md","text_hash":"96be070791b7d545dc75084e59059d2170eed247350b351db5330fbd947e4be6","text":"👥 ","translated":"👥 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:37Z"} -{"cache_key":"791d43fa7f63c6479c1e7d2393c2b2790beee2cffe5aaebc547d18ed1b73741f","segment_id":"start/wizard.md:45e595586df0bdc3","source_path":"start/wizard.md","text_hash":"45e595586df0bdc3f10caef3511b7e215c0b32a1626548d1c8648501cdcb4c00","text":"If the Gateway is loopback‑only, use SSH tunneling or a tailnet.","translated":"如果 Gateway 仅绑定回环地址,请使用 SSH 隧道或 tailnet。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:46:32Z"} -{"cache_key":"7938daa81ee4f2884173676b22aaf901e847b654ce9f368be964ab10461b5852","segment_id":"environment.md:87e89abb4c1c551f","source_path":"environment.md","text_hash":"87e89abb4c1c551fe08d355d097f18b8de78edca5f556997085681662fce8eed","text":"Config ","translated":"配置 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:20Z"} -{"cache_key":"794456d8a1d905f17357dfe11942245d5486b210b163a8ed1608b11b27ce3508","segment_id":"index.md:45808d75bf8911fa","source_path":"index.md","text_hash":"45808d75bf8911fa21637f9dd3f0dace1877748211976b5d61fcc5c15db594d0","text":"Webhooks","translated":"Webhooks","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:05:24Z"} -{"cache_key":"794de06f9e33b312b5ae297991b32a00290f5f484059283f191e6169ee2e70c4","segment_id":"index.md:2566561f81db7a7c","source_path":"index.md","text_hash":"2566561f81db7a7c4adb6cee3e93139155a6b01d52ff0d3d5c11648f46bc79bb","text":"📱 ","translated":"📱 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:28Z"} -{"cache_key":"7956d19ecce3a275c0f47424d4f75e289b9f7e5742f3adbe0f6eee5ac4c906ca","segment_id":"environment.md:46ab081177a452aa","source_path":"environment.md","text_hash":"46ab081177a452aa62354b581730f4675cb03e58cde8282071da30cabe18fb2e","text":"Optional login-shell import","translated":"可选的登录 shell 导入","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:56Z"} -{"cache_key":"79a4ac9cc430df4e4cb0a8710c8d21a52baeef560c6220facc6199d5e5a383fc","segment_id":"index.md:98a670e2fb754896","source_path":"index.md","text_hash":"98a670e2fb7548964e8b78b90fef47f679580423427bfd15e5869aca9681d0dd","text":"\"We're all just playing with our own prompts.\"","translated":"\"我们都只是在玩弄自己的提示词罢了。\"","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:23Z"} -{"cache_key":"79b1bfcd80bed91b72fe6f15f1e6e1fdfd069cddc7f2fcc4fbd28f573a874866","segment_id":"index.md:eef0107bb5a4e06b","source_path":"index.md","text_hash":"eef0107bb5a4e06b9de432b9e62bcf1e39ca5dfbbb9cb0cc1c803ca7671c06ab","text":"Gateway runbook","translated":"Gateway 运行手册","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:04:28Z"} -{"cache_key":"7a2de748330ae022b15280d0444a6c2794d4c60313452e6f4c2470a395e58ca8","segment_id":"index.md:bd293e4db98037bc","source_path":"index.md","text_hash":"bd293e4db98037bc9da5137af50453ac9c81b49e14eb4c47f121b12bed880877","text":" — Direct chats collapse into shared ","translated":" — 私聊折叠为共享 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:25Z"} -{"cache_key":"7a3ab97c36c385c05719cd51ac71cf8b98e65cc27b71ffc71d3670f568d36e6c","segment_id":"start/getting-started.md:5a4d846f4fe5a72f","source_path":"start/getting-started.md","text_hash":"5a4d846f4fe5a72f693af0c9d3a98b2a2df8c99456429765f51706ff7b76b7f7","text":"Gateway (from this repo):","translated":"Gateway(从此仓库):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:54Z"} -{"cache_key":"7a4ee345ffcdd6965857db8eb1605eb4460433be999c17d2b03a9a6a9789bdaa","segment_id":"help/index.md:6201111b83a0cb5b","source_path":"help/index.md","text_hash":"6201111b83a0cb5b0922cb37cc442b9a40e24e3b1ce100a4bb204f4c63fd2ac0","text":" and ","translated":" 和 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:24:49Z"} -{"cache_key":"7a78848fc43c9758427283f5941f66521236977cbaeaeeb04577de87c4b55c59","segment_id":"index.md:11450a0f023dc48c","source_path":"index.md","text_hash":"11450a0f023dc48cc9cef026357e2b4569a2b756290191c45a9eb0120a919cb7","text":" and (for groups) mention rules.","translated":" 以及(针对群组的)提及规则。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:03:37Z"} -{"cache_key":"7a917e0cad8ee2f671d93d95939ff19d4545eac6723d3c7be11326cb65db5d25","segment_id":"index.md:c491e0553683a70a","source_path":"index.md","text_hash":"c491e0553683a70a2fb52303f74675d2f7b725814ed70d5167473cb5fbe46450","text":"@steipete","translated":"@steipete","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:20Z"} -{"cache_key":"7ab5c873654dc79ffc905151bf0bff3f05a41e3e7d6e20a368d64aa3c7c8300e","segment_id":"help/index.md:156597e2632411d1","source_path":"help/index.md","text_hash":"156597e2632411d1d5f634db15004072607ba45072a4e17dfa51790a37b6781f","text":"Gateway issues:","translated":"Gateway 问题:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:44:44Z"} -{"cache_key":"7adf10c75a13a4f39d1360a5f4f45f0e22b608904e9ca8616eed396a35b7c3c0","segment_id":"index.md:cda454f61dfcac70","source_path":"index.md","text_hash":"cda454f61dfcac7007a9edc538f9f58cf38caa0652e253975979308162bccc53","text":"Gateway configuration","translated":"Gateway 配置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:07Z"} -{"cache_key":"7ae5133ee1cd21463f6a5373822eeddcebba9435512ebf67ec49d2f88d1a770f","segment_id":"index.md:1eb6926214b56b39","source_path":"index.md","text_hash":"1eb6926214b56b396336f22c22a6f8a4c360cfe7109c8be0f9869655b9ff6235","text":"Pairing (DM + nodes)","translated":"配对(私信 + 节点)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:04:08Z"} -{"cache_key":"7b14aa70efca84fdf7555ed77d263fae52ddaff260e935d45a3e22031f551c2a","segment_id":"environment.md:87e89abb4c1c551f","source_path":"environment.md","text_hash":"87e89abb4c1c551fe08d355d097f18b8de78edca5f556997085681662fce8eed","text":"Config ","translated":"配置 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:39Z"} -{"cache_key":"7b2f32af1ab182e748188eda2538cc9248faff3296bf459ee2365bf753cd3637","segment_id":"environment.md:907940a35852447a","source_path":"environment.md","text_hash":"907940a35852447aad5f21c5a180d993ff31cfd5807b1352ed0c24eabe183465","text":"never override existing values","translated":"永远不覆盖已有的值","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:22:00Z"} -{"cache_key":"7b38154bd954f484fa2247a129ccab23889881422b6d5415970eb7ef1dc4170f","segment_id":"environment.md:1ec31258a6b45ea9","source_path":"environment.md","text_hash":"1ec31258a6b45ea903cd76f5b0190a99ab56afff6241a04f0681eb12b7a02484","text":"Env var equivalents:","translated":"等效的环境变量:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:19:40Z"} -{"cache_key":"7b5e958eea98aae071adeeff78912bbce4b3a9616dabe5ade50538f31a372e6e","segment_id":"index.md:c011d6097bfbc8e9","source_path":"index.md","text_hash":"c011d6097bfbc8e936280addcf2e3e7d06ea2223ffd596973191b800a7035c32","text":"License","translated":"许可证","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:58Z"} -{"cache_key":"7b8d987fa7611cd9dfdf4089d114bce0fb150f5f3af5cfda3fdcf455be7afced","segment_id":"environment.md:3fe738a7ee6aaff5","source_path":"environment.md","text_hash":"3fe738a7ee6aaff51f099d9a8314510c99ced6a568eb38c67642cd43bb54eec0","text":" in the current working directory","translated":" 在当前工作目录中","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:08Z"} -{"cache_key":"7b91b68fc1e996f0909c890f91668386f9ef94974d0f8774a4d34d3cef43c638","segment_id":"help/index.md:frontmatter:read_when:1","source_path":"help/index.md:frontmatter:read_when:1","text_hash":"857eafc389d179e83e21e46c10527fec40894fe064c63847ba06b946b7d5eb73","text":"Something broke and you want the fastest path to a fix","translated":"出了问题,你想找到最快的修复方法","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:05Z"} -{"cache_key":"7c403e93e8396d4740e889ff8e6d078fe8079017dfda145496b3da29b0887144","segment_id":"environment.md:ab5aec4424cf678d","source_path":"environment.md","text_hash":"ab5aec4424cf678dcfb1ad3d2c2929c1e0b2b1ff61b82b961ada48ad033367b4","text":" (dotenv default; does not override).","translated":" (dotenv 默认行为;不会覆盖)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:38Z"} -{"cache_key":"7c487d305535a19790619ad3f172d0128d891e7b8488e84a7fb73ed9a7a9b32a","segment_id":"start/wizard.md:32ebb1abcc1c601c","source_path":"start/wizard.md","text_hash":"32ebb1abcc1c601ceb9c4e3c4faba0caa5b85bb98c4f1e6612c40faa528a91c9","text":"(","translated":"(","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:19Z"} -{"cache_key":"7c9e5b6fba8c9d85221b3c38a9d527d2d683facfd83a93e06f304e13c6771022","segment_id":"environment.md:b4736422e64c0a36","source_path":"environment.md","text_hash":"b4736422e64c0a369663d1b2d386f1b8f4b31b8936b588e4a54453c61a24e0fd","text":"Process environment","translated":"进程环境","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:27Z"} -{"cache_key":"7d14d64c713aa996c01b08945c1784ed78fa95b602c35f9fba369de60b9ffea5","segment_id":"environment.md:f7e239a42b7cd986","source_path":"environment.md","text_hash":"f7e239a42b7cd986a1558fed234e975ed2e96e9d37cf0a93f381778c461c89dd","text":"OpenClaw pulls environment variables from multiple sources. The rule is ","translated":"OpenClaw 从多个来源获取 环境变量。规则是 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:22Z"} -{"cache_key":"7d6ed7204c12f1d91564243dad60b560217dc6a29de3adf7a809de221b42c06a","segment_id":"start/wizard.md:bcd475104a873a42","source_path":"start/wizard.md","text_hash":"bcd475104a873a42ffaaed1aca9434981ce857adba97ebec4adc9e74e4d852f4","text":"allowlist","translated":"允许名单","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:05Z"} -{"cache_key":"7d8297d7b387f5a5302e0a09ea73266ba2e2075985e1af83b24a633c161cf10d","segment_id":"environment.md:46ab081177a452aa","source_path":"environment.md","text_hash":"46ab081177a452aa62354b581730f4675cb03e58cde8282071da30cabe18fb2e","text":"Optional login-shell import","translated":"可选的登录 shell 导入","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:29Z"} -{"cache_key":"7d82becc6d15c1be9fb97c06f9cc8ed5bf4949814e9d7af50d07380cb51e82f2","segment_id":"index.md:bd293e4db98037bc","source_path":"index.md","text_hash":"bd293e4db98037bc9da5137af50453ac9c81b49e14eb4c47f121b12bed880877","text":" — Direct chats collapse into shared ","translated":" —— 直接聊天折叠为共享的 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:32Z"} -{"cache_key":"7d927444fcf26b06d31a6f1f5d134416f8539e3aa1cc8dd3a4a7c5819fd1534a","segment_id":"index.md:f12242785ecda793","source_path":"index.md","text_hash":"f12242785ecda7935ded50cd48418357d32d3bac290f7a199bc9f0c7fbd13123","text":") — Location parsing (Telegram + WhatsApp)","translated":")— 位置解析(Telegram + WhatsApp)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:06:46Z"} -{"cache_key":"7da93ed9cf09f854e305f5deb4ddfac979802a4d1f6587247eea91555bdadc73","segment_id":"environment.md:1ec31258a6b45ea9","source_path":"environment.md","text_hash":"1ec31258a6b45ea903cd76f5b0190a99ab56afff6241a04f0681eb12b7a02484","text":"Env var equivalents:","translated":"等效的环境变量:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:54Z"} -{"cache_key":"7dca802a270f89fb4612993c8e7567b27da97fabd7b9ebd9c732ca2d53393244","segment_id":"help/index.md:729bc562eec2658b","source_path":"help/index.md","text_hash":"729bc562eec2658bd11ffdd522fe5277177dc73e86eaca7baac0b472a4d8f8b2","text":"If you’re looking for conceptual questions (not “something broke”):","translated":"如果你在寻找概念性问题的解答(而不是\"出了问题\"):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:24:56Z"} -{"cache_key":"7ddd9124594671bfd422e2bad8d56887ff8035a346f99a68d806deca63db0dcc","segment_id":"environment.md:46ab081177a452aa","source_path":"environment.md","text_hash":"46ab081177a452aa62354b581730f4675cb03e58cde8282071da30cabe18fb2e","text":"Optional login-shell import","translated":"可选的登录 shell 导入","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:58Z"} -{"cache_key":"7e1f91e8aeccc2aabf2dee95b6ee40ec27afb0aa5af4c97967b411ccded6826e","segment_id":"start/wizard.md:608acf5d419e2dad","source_path":"start/wizard.md","text_hash":"608acf5d419e2dadaef0b8082406cdbdb689e27953723644bf677feb09d1cf58","text":"Synthetic (Anthropic-compatible)","translated":"Synthetic(Anthropic 兼容)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:03Z"} -{"cache_key":"7e39b80026e0b63d7df55fcc142e8a2876ff972da67c4b263b619848e43417ec","segment_id":"index.md:19525ac5e5b9c476","source_path":"index.md","text_hash":"19525ac5e5b9c476b36a38c5697063e37e8fe2fae8ef6611f620def69430cf74","text":"Canvas host","translated":"Canvas 主机","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:18Z"} -{"cache_key":"7e93af146d7d04064fcba89e95f5a12c7320475af9b1c2e3208185cecb16a369","segment_id":"index.md:25d853ca04397b6a","source_path":"index.md","text_hash":"25d853ca04397b6ae248036d4d029d19d94a4981290387e5c29ef61b0eca9021","text":"Media: audio","translated":"媒体:音频","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:50Z"} -{"cache_key":"7ea531b1b4d75bfda8cb0a3a62e895b86310ab3f79a08cdcaddc1f2ccc61fbc2","segment_id":"index.md:3f8466cd9cb153d0","source_path":"index.md","text_hash":"3f8466cd9cb153d0c78a88f6a209e2206992db28c6dab45424132dc187974e2b","text":"Note: legacy Claude/Codex/Gemini/Opencode paths have been removed; Pi is the only coding-agent path.","translated":"注意:旧版 Claude/Codex/Gemini/Opencode 路径已移除;Pi 是唯一的编程智能体路径。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:04Z"} -{"cache_key":"7ec6a54cb7ceb1c31b47de147210b7193006db1d64b608c52b697512bd7e41aa","segment_id":"environment.md:32ebb1abcc1c601c","source_path":"environment.md","text_hash":"32ebb1abcc1c601ceb9c4e3c4faba0caa5b85bb98c4f1e6612c40faa528a91c9","text":" (","translated":" (","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:37Z"} -{"cache_key":"7eefff451137a5fd592db6fef6e65447cae69abe23699c34cb838a1c3cc04d73","segment_id":"start/wizard.md:d3745cec7a646b22","source_path":"start/wizard.md","text_hash":"d3745cec7a646b229f6d7123ef3557f68640f35a54a593f1e0e32776da0677c1","text":" (auto‑generated, even on loopback)","translated":" (自动生成,即使在回环地址上也是如此)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:58Z"} -{"cache_key":"7f2e9e14503f22acab8659b458900c0864bdc52ee5055d4a3a742508a8e41314","segment_id":"environment.md:45ca56d179d4788c","source_path":"environment.md","text_hash":"45ca56d179d4788c55ba9f7653b376d62e7faa738e92259e3d4f6f5c1b554f28","text":"Related","translated":"相关","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:47:13Z"} -{"cache_key":"7f4d30ae34bbfb95b016db35c14a77f46cdda52ff397a69b63ad655c6128f0f6","segment_id":"index.md:30f035b33a6c35d5","source_path":"index.md","text_hash":"30f035b33a6c35d51e09f9241c61061355c872f2fb9a82822cd2f5f443fd4ad4","text":"Group Chat Support","translated":"群聊支持","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:31Z"} -{"cache_key":"7f8a0ec6c0614299ed8aca539dde67e208ecc32d4022975fbb37f7930f3f70e5","segment_id":"start/getting-started.md:4cc7ae6d3b7fbaaf","source_path":"start/getting-started.md","text_hash":"4cc7ae6d3b7fbaaf56673ea3268caa38af191a587867ef1090c9f689ecccec96","text":"Headless/server tip: do OAuth on a normal machine first, then copy ","translated":"无头/服务器提示:先在普通机器上完成 OAuth,然后复制 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:40Z"} -{"cache_key":"7fec8c329b4438aef905e1918364b86faca2a2580bb29eded4850a67ba16109b","segment_id":"environment.md:496aca80e4d8f29f","source_path":"environment.md","text_hash":"496aca80e4d8f29fb8e8cd816c3afb48d3f103970b3a2ee1600c08ca67326dee","text":" block","translated":" 块","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:48Z"} -{"cache_key":"8070c35741bdfaa2f8878a7460406a597ccf7fec7994522389adeafea46b6e8e","segment_id":"environment.md:frontmatter:read_when:0","source_path":"environment.md:frontmatter:read_when:0","text_hash":"90fc0487bff88009979cff1061c1a882df8c3b1baa9c43538331d9d5dab15479","text":"You need to know which env vars are loaded, and in what order","translated":"你需要了解加载了哪些环境变量,以及加载的顺序","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:10Z"} -{"cache_key":"807dfa0f0d41dd91a0565a166afd1780eea045b0d30e177d91cc9dcf7dfce7db","segment_id":"help/index.md:569ca49f4aaf7846","source_path":"help/index.md","text_hash":"569ca49f4aaf7846e952c1d4aeca72febd0b79fa1c4f9db08fd3127551218572","text":"Install","translated":"安装","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:44:42Z"} -{"cache_key":"8088f34c0eace7e3e9131feea6cc0e9f333432c1fbc78720f10574d1b05197fb","segment_id":"help/index.md:6cb77499abdccd9a","source_path":"help/index.md","text_hash":"6cb77499abdccd9a2dbb7c93a4d31eed01613dda06302933057970df9ecdeb54","text":"Logs:","translated":"日志:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:39:46Z"} -{"cache_key":"81c954a409a9f6266a05f27d77a4b578631b1f6d86deca557279fd2f82ed29b5","segment_id":"index.md:2b402c90e9b15d9c","source_path":"index.md","text_hash":"2b402c90e9b15d9c3ef65c432c4111108f54ee544cda5424db46f6ac974928e4","text":"🔐 ","translated":"🔐 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:49Z"} -{"cache_key":"81cc99b7c2a7579fa478992233a19aeaea8c64586f07c24fe9e6f22f70610a96","segment_id":"index.md:1a36bded6916228a","source_path":"index.md","text_hash":"1a36bded6916228a5664c8b2bcdaa5661d342fe3e632aa41453f647a3daa3a61","text":" — Pairs as a node and exposes a Canvas surface","translated":" — 作为节点配对并提供 Canvas 界面","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:58Z"} -{"cache_key":"81e5e8a79bbaec139591a64a84574dfb14fcf22e8f803b68ddaa5950103c4c58","segment_id":"index.md:774f1d6b2910de20","source_path":"index.md","text_hash":"774f1d6b2910de200115afec1bd87fe1ea6b0bc2142ac729e121e10a45df4b5d","text":" ← ","translated":" ← ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:56Z"} -{"cache_key":"822efbc5bcf680421493847f6b76e9626f1d8202ff5ff47cd3e141ecdac58a9f","segment_id":"environment.md:496aca80e4d8f29f","source_path":"environment.md","text_hash":"496aca80e4d8f29fb8e8cd816c3afb48d3f103970b3a2ee1600c08ca67326dee","text":" block","translated":" 块","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:27Z"} -{"cache_key":"829cc48b5c60f16b09e63437a5de27acc17910473f8e3dfbc505a0d3e3b593c7","segment_id":"start/wizard.md:79a482cf546c23b0","source_path":"start/wizard.md","text_hash":"79a482cf546c23b04cd48a33d4ca8411f62e5b7dc8c3a8f30165e28e747f263a","text":"iMessage","translated":"iMessage","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:44:54Z"} -{"cache_key":"82d122e7cc5c895b61dec28850c3f07a68e69c19f554d9088318f62c6cd30fe1","segment_id":"environment.md:6d28a9f099e563d9","source_path":"environment.md","text_hash":"6d28a9f099e563d9322b5bcdea9ff98af87e9c213c2222462ae738d2fb27ecbe","text":" block\n\nTwo equivalent ways to set inline env vars (both are non-overriding):","translated":" 块\n\n设置内联环境变量的两种等效方式(均为非覆盖式):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:44Z"} -{"cache_key":"8334186d1a61e931ed7b3905a26e470159f86593819124c5626df7a012733ee9","segment_id":"environment.md:frontmatter:summary","source_path":"environment.md:frontmatter:summary","text_hash":"78351223e7068721146d2de022fdf440c2866b2ee02fbbb50bf64369b999820b","text":"Where OpenClaw loads environment variables and the precedence order","translated":"其中 OpenClaw 加载 环境变量 及优先级顺序","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:56:59Z"} -{"cache_key":"833685db37cf96f2342238018bd6a4a6e7812d1794a7389dc1e349917b140f50","segment_id":"environment.md:668e5590b5bb9990","source_path":"environment.md","text_hash":"668e5590b5bb9990eeb25bf657f7d17281a4c613ee4442036787cd4b2efd22bb","text":"If the config file is missing entirely, step 4 is skipped; shell import still runs if enabled.","translated":"如果配置文件完全缺失,则跳过第 4 步;如果启用了 shell 导入,它仍会运行。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:19:28Z"} -{"cache_key":"834bd8857aa5700b0ec493efb4625ba88e34c885a8254b13f6c44a75589021d2","segment_id":"index.md:9bcda844990ec646","source_path":"index.md","text_hash":"9bcda844990ec646b3b6ee63cbdf10f70b0403727dea3b5ab601ca55e3949db9","text":" for node WebViews; see ","translated":" 用于节点 WebView;请参阅 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:13Z"} -{"cache_key":"83b7bced23d11aea94d1b763db57522ce0fca9820fb5edcea109120ea955a46f","segment_id":"start/wizard.md:5cb343f0285df34e","source_path":"start/wizard.md","text_hash":"5cb343f0285df34e67f5215d063e3b53693dd3cdf65667f7d5c142f5db73f7a1","text":"Fastest first chat: open the Control UI (no channel setup needed). Run","translated":"最快的首次对话方式:打开 Control UI(无需设置渠道)。运行","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:07Z"} -{"cache_key":"83c4839813667de3bf67a2a050db86be067fa4bef9fa310d5baab23f82ebcfa5","segment_id":"index.md:aaa095329e21d86e","source_path":"index.md","text_hash":"aaa095329e21d86e24e8bec91bc001f7983d73a7a04c75646c0256448dac30ef","text":" — The space lobster who demanded a better name","translated":" — 那只要求取个更好名字的太空龙虾","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:06:09Z"} -{"cache_key":"841cbd53411a6aaa5b137d69b3feaa95de0ed0148f868dabd711786998382edb","segment_id":"index.md:6d6577cb1c128ac1","source_path":"index.md","text_hash":"6d6577cb1c128ac18a286d3c352755d1a265b1e3a03eded8885532c3f36e32ed","text":"Mario Zechner","translated":"Mario Zechner","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:36Z"} -{"cache_key":"842bdf601f288020ae8179f0d66f0d2d8a43112867d80efbb045acadbcd6626e","segment_id":"start/wizard.md:05bf3242414a96a7","source_path":"start/wizard.md","text_hash":"05bf3242414a96a764b57402b44b5852bbb0612ca017a9716e6364d47ecb0924","text":"Daemon install (LaunchAgent / systemd user unit)","translated":"守护进程安装(LaunchAgent / systemd 用户单元)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:28Z"} -{"cache_key":"843740adfdf616f31568963f47687512da2b547b5149b531b829112c01b57f5c","segment_id":"index.md:0b7e778664921066","source_path":"index.md","text_hash":"0b7e77866492106632e98e7718a8e1e89e8cb0ee3f44c1572dfd9e54845023de","text":"/concepts/streaming","translated":"/concepts/streaming","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:13Z"} -{"cache_key":"8469bc6049cc48c182c013768278e481d3ab521929f95cd267c63d0dc4bb5d38","segment_id":"index.md:5afbb1c887f6d850","source_path":"index.md","text_hash":"5afbb1c887f6d8501dba36cd2113d8f8b6ce6fa711a0d3e7efdc66f170abd2c2","text":"Cron jobs","translated":"定时任务","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:53:48Z"} -{"cache_key":"847900fa4457fc7d1dc92fa9688360479e337cedd03a88db8cd9f03cee8dbe51","segment_id":"index.md:99260acc29f71e4b","source_path":"index.md","text_hash":"99260acc29f71e4baeb36805a1fdbd2c17254b57c8e5a9cba29ee56518832397","text":" — Route provider accounts/peers to isolated agents (workspace + per-agent sessions)","translated":" —— 将 提供商 账户/对等方路由到隔离的 智能体(工作区 + 按 智能体 的 会话)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:21Z"} -{"cache_key":"84c686db4b4fc386bbb4efa35c380073babbc5fb4b2eb1ba3a8213a5f135a5bc","segment_id":"start/getting-started.md:161660030aa6c9e3","source_path":"start/getting-started.md","text_hash":"161660030aa6c9e32470cc1c023dab32dc748d80b0e61882b368cb775d12638e","text":" → ","translated":" → ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:27Z"} -{"cache_key":"84e200d4c823802e34a99da4faa8328d0e250aca858b0a32cc08e3ae12e0cc0e","segment_id":"start/wizard.md:e4442451c634e0db","source_path":"start/wizard.md","text_hash":"e4442451c634e0db2db0fae78725becbeafd567302e3ecbfeb5ccdc5887d29be","text":" from GitHub releases:","translated":" (从 GitHub 发布版本):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:47:56Z"} -{"cache_key":"85040674d9e2db6adb1ebb8c6215e72171d213a9dac8bd3c6bcb438178adc88b","segment_id":"index.md:0a4a282eda1af348","source_path":"index.md","text_hash":"0a4a282eda1af34874b588bce628b76331fbe907de07b57d39afdedccac2ba14","text":" http://127.0.0.1:18789/ (or http://localhost:18789/)","translated":" http://127.0.0.1:18789/(或 http://localhost:18789/)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:15Z"} -{"cache_key":"85cb0b7ed6991128b9fe65b7b103c5f32da742641cb24ffc1a3469002a2bcad6","segment_id":"start/getting-started.md:e24d86fa815827a4","source_path":"start/getting-started.md","text_hash":"e24d86fa815827a4dc5b8b22711caaf036427796512a74167ebaf615c495f9f8","text":"Telegram / Discord / others","translated":"Telegram / Discord / 其他","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:17Z"} -{"cache_key":"85e39779810391375b7241f2d999fbd5e6b2830ddf226a9ad561132c40d4fd47","segment_id":"start/wizard.md:21b111cbfe6e8fca","source_path":"start/wizard.md","text_hash":"21b111cbfe6e8fca2d181c43f53ad548b22e38aca955b9824706a504b0a07a2d","text":"Default ","translated":"默认 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:41Z"} -{"cache_key":"85fdea7998dfe111261588f998c93aceaa9b04ba174bc16bd188e3bbd8f3228a","segment_id":"environment.md:668e5590b5bb9990","source_path":"environment.md","text_hash":"668e5590b5bb9990eeb25bf657f7d17281a4c613ee4442036787cd4b2efd22bb","text":"If the config file is missing entirely, step 4 is skipped; shell import still runs if enabled.","translated":"如果配置文件完全缺失,则跳过第 4 步;如果已启用,shell 导入仍会运行。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:40Z"} -{"cache_key":"860ba81b08f80660c665451acb02944ed74cb09a277f70d86255a6bf6bb7b88f","segment_id":"index.md:f3047ab42a6a5bbf","source_path":"index.md","text_hash":"f3047ab42a6a5bbf164106356fa823ecada895064120c4e5a30e1f632741cc5f","text":"Web surfaces","translated":"Web 界面","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:35Z"} -{"cache_key":"861a980448662449d74017ee4183d74a8e54a772a24fefc3044d1dfffb8ca634","segment_id":"index.md:b332c3492d5eb10a","source_path":"index.md","text_hash":"b332c3492d5eb10a118eb6d8b0dcd689bc2477ce2ae16b303753b942b54377bc","text":"Configuration","translated":"配置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:00Z"} -{"cache_key":"861c7c8e316f48bf6b0d22e066b9c76410b8d9b77a12fc7f28213c04ed5f1c30","segment_id":"help/index.md:frontmatter:read_when:0","source_path":"help/index.md:frontmatter:read_when:0","text_hash":"ee0615553374970664b58ebd8e5d0ebc9bc8a5f03387671afbfd0096b390aa9b","text":"You’re new and want the “what do I click/run” guide","translated":"你是新手,想要一份\"我该点什么/运行什么\"的指南","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:24:28Z"} -{"cache_key":"86305fdb36e4df79c4c5037e3d1a5117141feccd13f65dcf1b0fd366ec22c4bc","segment_id":"index.md:5583785669449fc8","source_path":"index.md","text_hash":"5583785669449fc81a8037458c908c11a8f345c21c28f7f3a95de742bd52199a","text":"Media Support","translated":"媒体支持","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:49Z"} -{"cache_key":"868f3087136c15f059a91fe3ef5ac07ed6a0791e0a14a9740fb959acda8fad28","segment_id":"help/index.md:569ca49f4aaf7846","source_path":"help/index.md","text_hash":"569ca49f4aaf7846e952c1d4aeca72febd0b79fa1c4f9db08fd3127551218572","text":"Install","translated":"安装","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:16Z"} -{"cache_key":"869c590a57afd29927a22cac794ad6fc2f4e464aebb30c0e06b85b2cc3be5bb4","segment_id":"start/wizard.md:69ba7688eac60797","source_path":"start/wizard.md","text_hash":"69ba7688eac60797286dd7bead426bcbd3405746cb3465ac44c997955bd95df2","text":"Config + credentials + sessions","translated":"配置 + 凭据 + 会话","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:41Z"} -{"cache_key":"86a9e0f21a152909fc53f77e35bd973583e2a5dc7cfe3837cf2c783d037a7a93","segment_id":"environment.md:frontmatter:read_when:1","source_path":"environment.md:frontmatter:read_when:1","text_hash":"a3a2d99a99de98220c8e0296d6f4e4b2a34024916bd2379d1b3b9179c8fae46f","text":"You are debugging missing API keys in the Gateway","translated":"你正在调试 Gateway 中缺失的 API 密钥","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:12Z"} -{"cache_key":"86ece013a8e276db3f513a6afa8df20c009f53d42bb3dc02b84dcb39f8697ffe","segment_id":"help/index.md:b79cac926e0b2e34","source_path":"help/index.md","text_hash":"b79cac926e0b2e347e72cc91d5174037c9e17ae7733fd7bdb570f71b10cd7bfc","text":"Help","translated":"帮助","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:19:01Z"} -{"cache_key":"87897ef5886d39e96385313c32bc5580aff102c89185c03679de8a223d712e01","segment_id":"index.md:a194ca16424ddd17","source_path":"index.md","text_hash":"a194ca16424ddd17dacc45f1cbd7d0e41376d8955a7b6d02bc38c295cedd04e4","text":"RPC adapters","translated":"RPC 适配器","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:49Z"} -{"cache_key":"879702cd9a8560ed1fa329cb78a77dcbe84c66bfa29f3a1460261552dca9dfb2","segment_id":"index.md:66d0f523a379b2de","source_path":"index.md","text_hash":"66d0f523a379b2de6f8d5fba3a817ebc395f7bcaa54cc132ca9dfa665d1e9378","text":"Skills","translated":"技能","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:42Z"} -{"cache_key":"87b42c17fb63bfdcd059198572016f6b8b3cd297aaa991c4c1dea8723a68fbfe","segment_id":"index.md:9abe8e9025013e78","source_path":"index.md","text_hash":"9abe8e9025013e78a6bf2913f8c20ee43134ad001ce29ced89e2af9c07096d8f","text":"Media: images","translated":"媒体:图片","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:48Z"} -{"cache_key":"87d80d180c9d4789c20123b3bc177f99c4d00909f70c6fe3c209c078bdcafdce","segment_id":"index.md:1074116f823ec992","source_path":"index.md","text_hash":"1074116f823ec992e76d7e8be19d3235fec5ddd7020562b06e7242e410174686","text":"Remote use","translated":"远程使用","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:36Z"} -{"cache_key":"87f8e99a729beb8e55fdef7ca70ebe4b11f4ff1c5dbbfcb3e654429198c6bf0f","segment_id":"help/index.md:729bc562eec2658b","source_path":"help/index.md","text_hash":"729bc562eec2658bd11ffdd522fe5277177dc73e86eaca7baac0b472a4d8f8b2","text":"If you’re looking for conceptual questions (not “something broke”):","translated":"如果你在寻找概念性问题(不是\"出了故障\"):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:19:05Z"} -{"cache_key":"88ab429b0aa43b0cfc93a1fc0e69576a2acbf64d0cd407fc1028488a0c27c9fc","segment_id":"index.md:fdef9f917ee2f72f","source_path":"index.md","text_hash":"fdef9f917ee2f72fbd5c08b709272d28a2ae7ad8787c7d3b973063f0ebeeff7a","text":" to update the gateway service entrypoint.","translated":" 以更新网关服务入口点。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:03:03Z"} -{"cache_key":"88d02146dbe2246af19afc2deecbb627547528cd1bf8b9839d358e8987a88a99","segment_id":"index.md:9c870aa6e5e93270","source_path":"index.md","text_hash":"9c870aa6e5e93270170d5a81277ad3e623afe8d4efd186d3e28f3d2b646d52e6","text":"How it works","translated":"工作原理","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:42Z"} -{"cache_key":"88f63f39528cb8bcb530a350a6b610125dbf6ab7034c2509a772e2ec28ed9476","segment_id":"help/index.md:frontmatter:read_when:1","source_path":"help/index.md:frontmatter:read_when:1","text_hash":"857eafc389d179e83e21e46c10527fec40894fe064c63847ba06b946b7d5eb73","text":"Something broke and you want the fastest path to a fix","translated":"出了问题,你想找到最快的修复方法","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:10Z"} -{"cache_key":"8901c6c35445bae28f7f5cc6059387556bb67f591a89a7b3ff0d7b65dc1e85fd","segment_id":"environment.md:frontmatter:read_when:2","source_path":"environment.md:frontmatter:read_when:2","text_hash":"822b3d74ce16c1be19059fad4ca5bf7ae9327f58fa1ff4e75e78d5afa75c038f","text":"You are documenting provider auth or deployment environments","translated":"你正在编写提供商认证或部署环境的文档","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:47Z"} -{"cache_key":"8969e9b451aa17e28e3e2c32711b88094beda02a41bf0b2eb68d21aa8e84a63a","segment_id":"environment.md:3fe738a7ee6aaff5","source_path":"environment.md","text_hash":"3fe738a7ee6aaff51f099d9a8314510c99ced6a568eb38c67642cd43bb54eec0","text":" in the current working directory","translated":" 在当前工作目录中","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:40Z"} -{"cache_key":"89f351289752118559ed644ee4aaac84085f4b398cf7c7c80c25aa46429e85c4","segment_id":"index.md:82ba9b60b12da3ab","source_path":"index.md","text_hash":"82ba9b60b12da3ab4e7dbcb0d7d937214cff80c82268311423a6dc8c4bc09df5","text":"OpenClaw 🦞","translated":"OpenClaw 🦞","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:27:48Z"} -{"cache_key":"8a0eac24b3b1941f1a90900aecb71bf1530e8645519ce53d22168a6ee01e583d","segment_id":"start/wizard.md:41ed52921661c7f0","source_path":"start/wizard.md","text_hash":"41ed52921661c7f0d68d92511589cc9d7aaeab2b5db49fb27f0be336cbfdb7df","text":"Gateway","translated":"Gateway","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:54Z"} -{"cache_key":"8a1775a68c3ab8aefdffaadd63ebe7cbc027e198b618fb72bb9a1b16edd08d3a","segment_id":"index.md:9f4d843a5d04e23b","source_path":"index.md","text_hash":"9f4d843a5d04e23b22eb79b3bfa0fbad70ede435ddb5d047e7d77e830efa6019","text":" — Bot token + WebSocket events","translated":" —— 机器人令牌 + WebSocket 事件","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:49Z"} -{"cache_key":"8a32ea50ef9d28ef09b557c184b4db0a493dd539261fde0ce5260a60bb881904","segment_id":"index.md:4818a3f84331b702","source_path":"index.md","text_hash":"4818a3f84331b702815c94b4402067e09e9e2d27ebc1a79258df8315f2c8600b","text":"📎 ","translated":"📎 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:47Z"} -{"cache_key":"8a81f73e519177081d755623ff45ac47552fa513f5aaf9c77335ce2c329087f3","segment_id":"start/getting-started.md:524bf322c2034388","source_path":"start/getting-started.md","text_hash":"524bf322c2034388f76cd94c1c7834341cedfa09bc4a864676749a08b243416d","text":"model/auth (OAuth recommended)","translated":"模型/认证(推荐使用 OAuth)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:53Z"} -{"cache_key":"8a83aabc21a6b84ce7552d72a9bc0a7c2d99864c31350064cbd39564354421f1","segment_id":"index.md:9adcfa4aa10a4e8b","source_path":"index.md","text_hash":"9adcfa4aa10a4e8b991a72ccc45261cd64f296aed5b257e4caf9c87aff1290a0","text":" — Send and receive images, audio, documents","translated":" —— 发送和接收图片、音频、文档","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:51Z"} -{"cache_key":"8a984f774ac8874be4797ffddd21cbdddc9379fa6bc51121620fbe9395cd91cf","segment_id":"help/index.md:bfc5930cc2660330","source_path":"help/index.md","text_hash":"bfc5930cc2660330260afd407e98d86adaec0af48dd72b88dc33ef8e9066e2c9","text":"Install sanity (Node/npm/PATH):","translated":"安装完整性检查(Node/npm/PATH):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:18Z"} -{"cache_key":"8ac55f265f3496db43dce513fde21c137826476afcff2ed1b3e86e613ff28b3c","segment_id":"start/wizard.md:44dab6c89cc5e6d9","source_path":"start/wizard.md","text_hash":"44dab6c89cc5e6d9a3112d3cb45c19cd16c3a9963082276015d4b624e5e67782","text":"Some channels are delivered as plugins. When you pick one during onboarding, the wizard\nwill prompt to install it (npm or a local path) before it can be configured.","translated":"部分渠道以插件形式提供。当您在上手引导期间选择某个渠道时,向导会提示先安装它(通过 npm 或本地路径),然后才能进行配置。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:48:57Z"} -{"cache_key":"8b2c90beec3893be65468e57df762fcbc285a9772042200eee3d4bf8f7ff9c0d","segment_id":"index.md:96be070791b7d545","source_path":"index.md","text_hash":"96be070791b7d545dc75084e59059d2170eed247350b351db5330fbd947e4be6","text":"👥 ","translated":"👥 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:29Z"} -{"cache_key":"8b921a960a8b92bc6210c2e228fe886cd93000a5a77f1cb5ac97233de2c4f965","segment_id":"index.md:fb87b8dba88b3edc","source_path":"index.md","text_hash":"fb87b8dba88b3edced028edfe2efa5f884ab2639c1b26efa290ccd0469454d25","text":"Slash commands","translated":"斜杠命令","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:04:03Z"} -{"cache_key":"8bdf5dbe57d7db52bbddf554ea4eed6bfa8e92209d24733e8f57355beba0ecb9","segment_id":"index.md:74926756385b8442","source_path":"index.md","text_hash":"74926756385b844294a215b2830576e3b2e93b84c5a8c8112b3816c5960f3022","text":" — DMs + guild channels via channels.discord.js","translated":" — 通过 channels.discord.js 支持私聊和服务器频道","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:43Z"} -{"cache_key":"8c2486104e938755d3aef3b6c16fe1e13db8efe500c6559d60fc003ad1acd319","segment_id":"environment.md:cf3f9ba035da9f09","source_path":"environment.md","text_hash":"cf3f9ba035da9f09202ba669adca3109148811ef31d484cc2efa1ff50a1621b1","text":" (what the Gateway process already has from the parent shell/daemon).","translated":" (Gateway 进程从父 shell/守护进程继承的已有环境变量)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:33Z"} -{"cache_key":"8c7d9724c491e8ae94a27ab7b11fb116922f6f3b5d61664aae76ab5fd88d2f0a","segment_id":"index.md:5cf9ea2e20780551","source_path":"index.md","text_hash":"5cf9ea2e2078055129b38cfbc394142ca6ca41556bd6e31cbd527425647c1d1e","text":"One Gateway per host (recommended)","translated":"每台主机一个 Gateway(推荐)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:40Z"} -{"cache_key":"8c84e9f488f94b32acf52cfc44019211a043af87a9c65b7305825db1a67fa421","segment_id":"environment.md:fefb88f0e707cf40","source_path":"environment.md","text_hash":"fefb88f0e707cf40854f27e99b81ac3cb08f0249f47ee200a80e6a5c16841b99","text":"Two equivalent ways to set inline env vars (both are","translated":"两种等效的内联环境变量设置方式(两者都是","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:29Z"} -{"cache_key":"8c9152b9d2d5dae37266587767f1afb6c33e8f471714b92f4a8cd7f91787afc2","segment_id":"environment.md:a258b30f88c30650","source_path":"environment.md","text_hash":"a258b30f88c30650e73073d5bdde5cfcc6987100ae62d37789e5c46a0d85b7c6","text":"Global ","translated":"全局 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:29Z"} -{"cache_key":"8cac6173616db6cb8fe86a594893041cbcf322a1e0faeaf01528aeac4ca00759","segment_id":"help/index.md:6201111b83a0cb5b","source_path":"help/index.md","text_hash":"6201111b83a0cb5b0922cb37cc442b9a40e24e3b1ce100a4bb204f4c63fd2ac0","text":" and ","translated":" 和 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:24Z"} -{"cache_key":"8ceb849e69710631dc80f2eaa57838541deab798818efa76d69b2923f4ab9815","segment_id":"start/wizard.md:b06d5b13b5a1b910","source_path":"start/wizard.md","text_hash":"b06d5b13b5a1b91014ecd8016bec44f379a5269376b602326c42a399004c8491","text":": run ","translated":":运行 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:04Z"} -{"cache_key":"8d99559630736c2a11c549fcfed24d9ff242793fbac2956e758c3ac5b9f5fe7d","segment_id":"start/wizard.md:361f035d290095c6","source_path":"start/wizard.md","text_hash":"361f035d290095c6a1a00757c6ff6d5208dcb600fd6dd4b130bb42047fe3f08b","text":"18789","translated":"18789","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:51Z"} -{"cache_key":"8dac40cb3bfd86d7cfbe99acdb4641cd63d389ea15bd6bfa948a1c734204e925","segment_id":"index.md:496bcd8a502babde","source_path":"index.md","text_hash":"496bcd8a502babde0470e7105dfed7ba95bbc3193b7c6ba196b3ed0997e84294","text":"Voice notes","translated":"语音消息","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:02:21Z"} -{"cache_key":"8db9b500f11e5390f21a454ab89a4193991966e384e452f49e968afb9e280a69","segment_id":"environment.md:453c14128fbfb5f6","source_path":"environment.md","text_hash":"453c14128fbfb5f6757511557132a1dbb3bcbf243267630bfec49db8518c7780","text":"Env var substitution in config","translated":"配置中的环境变量替换","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:56Z"} -{"cache_key":"8e5f833a1ebf122c23edb718754bcd685bfc77afbbac60eb1a2aff7234b60a27","segment_id":"index.md:a10f6ed8c1ddbc10","source_path":"index.md","text_hash":"a10f6ed8c1ddbc10d3528db7f7b6921c1dd5a5e78aa191ff017bf29ce2d26449","text":"⏱️ ","translated":"⏱️ ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:00Z"} -{"cache_key":"8e641ec66f3ae7edd18dd57ec47a5e61ff6ec0e585e0cbb966f09ebe803ed02f","segment_id":"index.md:ba5ec51d07a4ac0e","source_path":"index.md","text_hash":"ba5ec51d07a4ac0e951608704431d59a02b21a4e951acc10505a8dc407c501ee","text":")","translated":")","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:17Z"} -{"cache_key":"8e67881037945410ab1d9a08a670ff5947dfbd577da1a7c2d5c9fee74987194b","segment_id":"index.md:0eb95fb6244c03f1","source_path":"index.md","text_hash":"0eb95fb6244c03f1ccca696718a06766485c231347bf382424fb273145472355","text":"Quick start","translated":"快速开始","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:06Z"} -{"cache_key":"8e8e8756585cb2edf84845f3f8a7dfe14781b3b4acfe7ed6ef1d635aac3f4fef","segment_id":"start/wizard.md:1afc5c1f69b6ae2d","source_path":"start/wizard.md","text_hash":"1afc5c1f69b6ae2d91519459b548f196ead4eddba5882c0d3eb53032c35deee8","text":" so the Gateway stays up after logout.","translated":" 启用驻留,以便在注销后 Gateway 保持运行。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:45:22Z"} -{"cache_key":"8eb25fbece39afeec23d63e391e40f5e81d561838787d905058492ecc5a8b9df","segment_id":"index.md:15cd10b29ec14516","source_path":"index.md","text_hash":"15cd10b29ec1451670b80eae4b381e26e84fa8bdb3e8bea90ec943532411b189","text":" (@Hyaxia, ","translated":" (@Hyaxia, ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:51Z"} -{"cache_key":"8ebe2d251018b02257f263d2a16eff5974332bc1187abf5526d990777596d622","segment_id":"index.md:cf9f12b2c24ada73","source_path":"index.md","text_hash":"cf9f12b2c24ada73bb0474c0251333f65e6d5d50e56e605bdb264ff32ad0a588","text":"Config lives at ","translated":"配置文件位于 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:03:23Z"} -{"cache_key":"8f284740058a03d3e3f1eb5dce6f13b548a48866fa3b7bba381f06b93bc6fd88","segment_id":"environment.md:c2d7247c8acb83a5","source_path":"environment.md","text_hash":"c2d7247c8acb83a5a020458fa836c2445922b51513dbdbf154ab5f7656cb04e9","text":"; does not override).","translated":";不覆盖已有值)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:17Z"} -{"cache_key":"8f48c119b19172331a14c91c05b056ff50c806eac677b102b4ab6803687c663c","segment_id":"start/wizard.md:a274352ee48cdb04","source_path":"start/wizard.md","text_hash":"a274352ee48cdb048273ff9ca060d9f76b541a3df3e7d07cf07e4e8379475bb5","text":": on macOS the wizard checks Keychain item \"Claude Code-credentials\" (choose \"Always Allow\" so launchd starts don't block); on Linux/Windows it reuses ","translated":":在 macOS 上,向导会检查钥匙串项 \"Claude Code-credentials\"(请选择\"始终允许\"以避免 launchd 启动时被阻止);在 Linux/Windows 上,它会复用 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:57Z"} -{"cache_key":"8f638ba10519facb8bb0ca4a86605815fdb2358aaaca87ffe1e56dd9c59c18f9","segment_id":"start/getting-started.md:de10e3b2385f09a3","source_path":"start/getting-started.md","text_hash":"de10e3b2385f09a36e17e5e94d04d1b40b50fb1ea489a406db4c032d69683001","text":"pairing defaults (secure DMs)","translated":"配对默认设置(安全私信)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:58Z"} -{"cache_key":"8f85617fbbf28b9de5f1702889a5b731fb69ca71be4e7baac5388814f0946226","segment_id":"index.md:297d5c673f5439aa","source_path":"index.md","text_hash":"297d5c673f5439aa31dca3bbc965cb657a89a643803997257defb3baef870f89","text":"Open the dashboard (local Gateway):","translated":"打开仪表盘(本地 Gateway):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:13Z"} -{"cache_key":"8f8728437e28a03d18e6b0dc21669ea86fcfd4ae6b89c60e7442baf1975436b7","segment_id":"index.md:aaa095329e21d86e","source_path":"index.md","text_hash":"aaa095329e21d86e24e8bec91bc001f7983d73a7a04c75646c0256448dac30ef","text":" — The space lobster who demanded a better name","translated":" — 那只要求取个更好名字的太空龙虾","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:44Z"} -{"cache_key":"8fd4298d2a5388956240bc02b51a7b6c227ce0a1397da46538c00af6a564e8c1","segment_id":"index.md:c3af076f92c5ed8d","source_path":"index.md","text_hash":"c3af076f92c5ed8dcb0d0b0d36dd120bc31b68264efea96cf8019ca19f1c13a3","text":"Troubleshooting","translated":"故障排除","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:53:59Z"} -{"cache_key":"9031f7b1b0d90eab21e7d9029bd4eb11f1ed5a9e0c9c5638082744c233c92e43","segment_id":"index.md:83f4fc80f6b452f7","source_path":"index.md","text_hash":"83f4fc80f6b452f7cdf426f6b87f08346d7a2d9c74a0fb62815dce2bfddacf63","text":" — A space lobster, probably","translated":" —— 大概是一只太空龙虾说的","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:52Z"} -{"cache_key":"907c8f6a0763b469cdeb4bb64835922245714239ced9d3ed569f49fe760c3a54","segment_id":"index.md:9adcfa4aa10a4e8b","source_path":"index.md","text_hash":"9adcfa4aa10a4e8b991a72ccc45261cd64f296aed5b257e4caf9c87aff1290a0","text":" — Send and receive images, audio, documents","translated":" — 发送和接收图片、音频、文档","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:02:17Z"} -{"cache_key":"907e9eee8caead29b80ff841b945f1df714df32948bfa54c56cef29685b1bc00","segment_id":"index.md:b5ccaf9b1449291c","source_path":"index.md","text_hash":"b5ccaf9b1449291c92f855b8318aeb2880a9aa1a75272d17f55cf646071b3eae","text":"Gmail hooks (Pub/Sub)","translated":"Gmail 钩子(Pub/Sub)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:05:26Z"} -{"cache_key":"90c8b075eff65b5f916b6ffcb3f8305a95bb6c162e9f8cac12e7fecc3f2409b0","segment_id":"index.md:25d853ca04397b6a","source_path":"index.md","text_hash":"25d853ca04397b6ae248036d4d029d19d94a4981290387e5c29ef61b0eca9021","text":"Media: audio","translated":"媒体:音频","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:53:28Z"} -{"cache_key":"90eac59e70026b85f505d0d2bfe603ba2880721e5abafedd52bdeeaf21def2f5","segment_id":"start/getting-started.md:5ead037957578a63","source_path":"start/getting-started.md","text_hash":"5ead037957578a63002170be037d777c909bad991ab7ea1c606b55ddfa60ccad","text":"Alternative (global install):","translated":"替代方式(全局安装):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:53Z"} -{"cache_key":"917e181e50cd2d2f7596153167295a7294816bb3a66714820a4e205f06859a61","segment_id":"index.md:c0aa8fcb6528510a","source_path":"index.md","text_hash":"c0aa8fcb6528510aea46361e8c871d88340063926a8dfdd4ba849b6190dec713","text":": it is the only process allowed to own the WhatsApp Web session. If you need a rescue bot or strict isolation, run multiple gateways with isolated profiles and ports; see ","translated":":它是唯一被允许拥有 WhatsApp Web 会话 的进程。如果您需要救援机器人或严格隔离,请使用隔离的配置文件和端口运行多个网关;参见 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:33Z"} -{"cache_key":"91c6437ace26aa4f27b7bc4023db93c6cc1db80da1ebc4aea9d791e86fd125b5","segment_id":"start/wizard.md:67b696468610b879","source_path":"start/wizard.md","text_hash":"67b696468610b879ed7f224dbf6b0861f27e39d20454cb9d7af1ec52d3e5eeaa","text":"Dashboard","translated":"仪表盘","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:10Z"} -{"cache_key":"91d1558d4947a913141ec4bc1a247285174da3d016fcc62ed430c690fcad7dd3","segment_id":"index.md:f0e2018271f51504","source_path":"index.md","text_hash":"f0e2018271f515041084c8189f297236abe18f9ec77edad1a61c5413310bbd9e","text":"🖥️ ","translated":"🖥️ ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:00Z"} -{"cache_key":"91ff2d0607cc2fb36dcd28db903c8cd10df497a6ee53085072c1fab662322443","segment_id":"environment.md:f6b2ffe1d0d5f521","source_path":"environment.md","text_hash":"f6b2ffe1d0d5f521b76cabc67d6e96da2b1170eef8086d530558e9906a7f092d","text":"Models overview","translated":"模型 概述","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:36Z"} -{"cache_key":"92f138d40ad656de1f7508a72408aa280eb1010d096114a30af97085d0bfa447","segment_id":"start/wizard.md:42db531f91673e36","source_path":"start/wizard.md","text_hash":"42db531f91673e36e120292f33152cd0e1e53087f5668f4fec8e519809ee8d85","text":"macOS: LaunchAgent","translated":"macOS:LaunchAgent","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:45:10Z"} -{"cache_key":"93114bd8806e7d10e3c22b3415d23eec041357c24c8f6dc651d62cacc41ad375","segment_id":"start/getting-started.md:69c1cae4e20f3b2b","source_path":"start/getting-started.md","text_hash":"69c1cae4e20f3b2b4d3b3dd3ea7636d8faed8460af512aa7a7d3a3c09696f5fc","text":" Bun has known issues with these\nchannels. If you use WhatsApp or Telegram, run the Gateway with ","translated":" Bun 在这些渠道上存在已知问题。如果您使用 WhatsApp 或 Telegram,请使用 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:03Z"} -{"cache_key":"9332e0a6cbeffb7af77e26039be6a3fb42905022a7775699a3ff6aa4cd6bb862","segment_id":"start/wizard.md:5e52bafa51b66711","source_path":"start/wizard.md","text_hash":"5e52bafa51b667115904e942882f5aaf55262059621f3927b0d5699e08512c56","text":"DM security: default is pairing. First DM sends a code; approve via ","translated":"私信安全:默认为配对模式。首次私信会发送一个验证码;通过 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:45:02Z"} -{"cache_key":"93a02264b644d55b3fd01345f4e180207ab2e42e653686393c45e736ef355f86","segment_id":"environment.md:baa5be7f6320780b","source_path":"environment.md","text_hash":"baa5be7f6320780bd7bb7b7ddbb8cd1ffb26ccf7d94d363350668c50aedcf95f","text":" (applied only if missing).","translated":" (仅在缺失时应用)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:27Z"} -{"cache_key":"93e072d0402b8e5c6f32b9aabff58f378e0ceaf8815886e0b5a873fad83f9e36","segment_id":"environment.md:ab5aec4424cf678d","source_path":"environment.md","text_hash":"ab5aec4424cf678dcfb1ad3d2c2929c1e0b2b1ff61b82b961ada48ad033367b4","text":" (dotenv default; does not override).","translated":" (dotenv 默认行为;不会覆盖)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:11Z"} -{"cache_key":"93e5b6f997f3fd1199e507267858a37604727435b4fbbe418b39b953e7102fa6","segment_id":"environment.md:a258b30f88c30650","source_path":"environment.md","text_hash":"a258b30f88c30650e73073d5bdde5cfcc6987100ae62d37789e5c46a0d85b7c6","text":"Global ","translated":"全局 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:13Z"} -{"cache_key":"93ed507f9f7ad50ae11b95d49a6d547ac605a4bb966e1d9800da110bf2f85ff6","segment_id":"index.md:5583785669449fc8","source_path":"index.md","text_hash":"5583785669449fc81a8037458c908c11a8f345c21c28f7f3a95de742bd52199a","text":"Media Support","translated":"媒体支持","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:02:15Z"} -{"cache_key":"93f8819a09c973fae0ec648305d9c7e50ebee3771359b807686c605023b0b705","segment_id":"start/getting-started.md:eba2ed5d6cc0239d","source_path":"start/getting-started.md","text_hash":"eba2ed5d6cc0239dd5d0475d7ea57b120ff06eb1100c67f4cf713c3bb167f0a0","text":": Node (recommended; required for WhatsApp/Telegram). Bun is ","translated":":Node(推荐;WhatsApp/Telegram 必需)。Bun 为 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:19Z"} -{"cache_key":"94142aa44168395437a427ea262b059160a067ce005c11ceedb11f664eeec66e","segment_id":"start/wizard.md:3b0c9c223937ca13","source_path":"start/wizard.md","text_hash":"3b0c9c223937ca1308ceb186bb6cde91e811d0fefedcdf119c47e4d7cf58ec9a","text":"The Gateway exposes the wizard flow over RPC (","translated":"Gateway 通过 RPC 暴露向导流程(","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:47:43Z"} -{"cache_key":"9425ad8ab2d143b8d1558adc989c0b4416bf7144082034f0eb317527934e9936","segment_id":"index.md:d00eca1bae674280","source_path":"index.md","text_hash":"d00eca1bae6742803906ab42a831e8b5396d15b6573ea13c139ec31631208ec1","text":"Getting Started","translated":"快速入门","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:47:44Z"} -{"cache_key":"943aadb2a660dc3c85e9c5e1581741edaf50fd5be23f87f43f509ea1cdf162f0","segment_id":"index.md:add4778f9e60899d","source_path":"index.md","text_hash":"add4778f9e60899d7f44218483498c0baf7a0468154bc593a60747ee769c718c","text":"Android node","translated":"Android 节点","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:15Z"} -{"cache_key":"944265cf5c15fd945a3ceb8d27730e4839e78556bcec52463b9e83467b63df5f","segment_id":"start/wizard.md:d13b8b4ebb7477f9","source_path":"start/wizard.md","text_hash":"d13b8b4ebb7477f96681a90cc723fa7532710b595d8aba6f9a840f47299515fd","text":"macOS app onboarding: ","translated":"macOS 应用上手引导: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:49:02Z"} -{"cache_key":"9481b030bd57d871b28ddf5316096a8cc8fc1fc317bd03e508a5d9239e3d93c5","segment_id":"start/getting-started.md:aeba20c4d03f146e","source_path":"start/getting-started.md","text_hash":"aeba20c4d03f146e967a7b748d8dee3859c34b0de6b6402851edd2ea08f9b09a","text":"5) DM safety (pairing approvals)","translated":"5)私信安全(配对审批)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:36Z"} -{"cache_key":"94a860b1ca3e9303574016027c1e3c170689f08e72bfd49acb315353f38633e8","segment_id":"environment.md:6f59001999ef7b71","source_path":"environment.md","text_hash":"6f59001999ef7b7128bab80d2034c419f3034497e05f69fbdf67f7b655cdc173","text":"Configuration: Env var substitution","translated":"配置:环境变量替换","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:17:05Z"} -{"cache_key":"94dd1cb509ea10b9fce425cbde9d55373457d90dd1ccd06ffe6362643b29cce2","segment_id":"start/wizard.md:4d5278f9b1f0b84c","source_path":"start/wizard.md","text_hash":"4d5278f9b1f0b84c0ad3f87ffbbd6ed35b2d223c2eb2f866682026b9d00e636d","text":"Token if the remote Gateway requires auth (recommended)","translated":"如果远程 Gateway 需要认证,则需提供令牌(推荐)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:46:23Z"} -{"cache_key":"950eae91a2abdbc1062fa1fb78a43a5b2883dda0245c95c5b02bceac0c1bfbc9","segment_id":"start/wizard.md:d6c64db69399b7ae","source_path":"start/wizard.md","text_hash":"d6c64db69399b7ae55bae206d47ae2efa6071a8e49f7cf1cd793d5994b5c2976","text":" to create a separate agent with its own workspace,\nsessions, and auth profiles. Running without ","translated":" 创建一个拥有独立工作区、会话和认证配置的单独智能体。不使用 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:46:50Z"} -{"cache_key":"958b1f38beeaa4e69690d389ff0191ffc0c3a9f97863ccc3c17a11097ec4c512","segment_id":"help/index.md:frontmatter:summary","source_path":"help/index.md:frontmatter:summary","text_hash":"aece82a2d540ab1a9a21c7b038127cae6e9db2149491564bb1856b6f8999f205","text":"Help hub: common fixes, install sanity, and where to look when something breaks","translated":"帮助中心:常见修复方法、安装完整性检查,以及出问题时该去哪里排查","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:44:23Z"} -{"cache_key":"95aad0f0fde6668b0ddea6c8212249c754769fe12739b8338c427f21860c8c7b","segment_id":"start/wizard.md:96192b2485e20320","source_path":"start/wizard.md","text_hash":"96192b2485e203201d62348dde087408b660e53f1df0fe65728759e16fac82bb","text":"Anthropic token (paste setup-token)","translated":"Anthropic 令牌(粘贴 setup-token)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:02Z"} -{"cache_key":"95b902406b2a68302a809d07f80f069bf4bac5d96fec5e55b4d76f4863492faf","segment_id":"environment.md:87e89abb4c1c551f","source_path":"environment.md","text_hash":"87e89abb4c1c551fe08d355d097f18b8de78edca5f556997085681662fce8eed","text":"Config ","translated":"配置 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:22:09Z"} -{"cache_key":"9638dca44bfb62a1f8c5f57d97d7c5636eb72da5567b4aa587b1cfd25592df76","segment_id":"environment.md:5b06ccc0bf4ede1b","source_path":"environment.md","text_hash":"5b06ccc0bf4ede1b00437d274b91d1a22cf7c0dc421b279348d9e333505fd264","text":" shell/daemon).","translated":" shell/守护进程中获得的内容)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:38Z"} -{"cache_key":"96fd19674037838fbf4ae365f247dad43d7d88f1eafecdd40527df1305639695","segment_id":"start/getting-started.md:73fc16837b0a6b13","source_path":"start/getting-started.md","text_hash":"73fc16837b0a6b13c23d4100f65a5e58460aac38cd66f884c5884b74a553f93a","text":"Control UI","translated":"控制界面","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:42Z"} -{"cache_key":"972e8e07b8a59145f0ed3291dc6b3f72f715e8299cd2078abe5588c64819a265","segment_id":"start/wizard.md:cdb4ee2aea69cc6a","source_path":"start/wizard.md","text_hash":"cdb4ee2aea69cc6a83331bbe96dc2caa9a299d21329efb0336fc02a82e1839a8","text":".","translated":"。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:13Z"} -{"cache_key":"975f5db56766c17a2b10af9d74333f67595593ac0a6513b908618c296cc4f605","segment_id":"index.md:3d8fed7c358b2ccf","source_path":"index.md","text_hash":"3d8fed7c358b2ccf225ee16857a0bb9b950fd414319749e0f6fff58c99fa5f22","text":"Subscription auth","translated":"订阅认证","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:51Z"} -{"cache_key":"9767a108ed5a174a4fd54d7d9c6213f6d294afe78f1a08a32f46eb624ee3c424","segment_id":"start/wizard.md:0ba91e19ba6d7b97","source_path":"start/wizard.md","text_hash":"0ba91e19ba6d7b970cdd563b05fd2c5f32751202c010c6c5adf4e40044023ed3","text":"Daemon install","translated":"守护进程安装","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:45:07Z"} -{"cache_key":"97b2e80f9008ad199527a8380466b8cb9e08c9f7bd52256f899ddd77b0c7f060","segment_id":"index.md:d00eca1bae674280","source_path":"index.md","text_hash":"d00eca1bae6742803906ab42a831e8b5396d15b6573ea13c139ec31631208ec1","text":"Getting Started","translated":"入门指南","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:07Z"} -{"cache_key":"97d83391e42ba7d3c2019f295e24a2981299c23dab40af45fab4ebd24ec272d7","segment_id":"environment.md:f15f5f9f4ef4d668","source_path":"environment.md","text_hash":"f15f5f9f4ef4d6688876c894f8eba251ed1db6eaf2209084028d43c9e76a8ba1","text":" (aka ","translated":" (即 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:20Z"} -{"cache_key":"97db9a094700b6722c7d627483ea58cf2263ec4a343062563c166cab96c324ca","segment_id":"index.md:fb87b8dba88b3edc","source_path":"index.md","text_hash":"fb87b8dba88b3edced028edfe2efa5f884ab2639c1b26efa290ccd0469454d25","text":"Slash commands","translated":"斜杠命令","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:29Z"} -{"cache_key":"97e64a162c2ed197b0aabfd9479dfc8f8a2be8f754e8170e70e152327f02fe5e","segment_id":"index.md:ee8b06871d5e335e","source_path":"index.md","text_hash":"ee8b06871d5e335e6e686f4e2ee9c9e6de5d389ece6636e0b5e654e0d4dd5b7e","text":"Control UI (browser)","translated":"控制界面(浏览器)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:04:43Z"} -{"cache_key":"983385317e20206e673531fcf329991718de8cd556d261974454832bf1222781","segment_id":"start/wizard.md:69f2e29c4496ba8d","source_path":"start/wizard.md","text_hash":"69f2e29c4496ba8d72788bdc5326ed5a74751c5b6e67115cd9a641ab49520997","text":" for a machine‑readable summary.","translated":" 以获取机器可读的摘要。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:47:17Z"} -{"cache_key":"986141bb219554b112fbaaa6ab9722f121b126f35d306b6398dae0e0d9d0fbcb","segment_id":"help/index.md:71095a6d42f5d9c2","source_path":"help/index.md","text_hash":"71095a6d42f5d9c2464a8e3f231fc53636d4ce0f9356b645d245874162ec07e2","text":"Gateway troubleshooting","translated":"Gateway 故障排除","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:44:46Z"} -{"cache_key":"9878b9b1f86218e0cf79b700dbb48857de209bbeb665a370642c6f25490ef0a3","segment_id":"start/wizard.md:d143f4078cca268c","source_path":"start/wizard.md","text_hash":"d143f4078cca268c9d6d569cbd06460e7ccc5af0a487c42e655ff1e1587b69fb","text":"Java 21","translated":"Java 21","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:48:12Z"} -{"cache_key":"98946553d70879085d2c248422199de47fecde1138aa7d97301da8415f5dd7a9","segment_id":"index.md:1074116f823ec992","source_path":"index.md","text_hash":"1074116f823ec992e76d7e8be19d3235fec5ddd7020562b06e7242e410174686","text":"Remote use","translated":"远程使用","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:19Z"} -{"cache_key":"98ccfc4d8aa8cbec392810df9c7ec0169da2595e35ee80950d991a26cee1dd8d","segment_id":"index.md:15cd10b29ec14516","source_path":"index.md","text_hash":"15cd10b29ec1451670b80eae4b381e26e84fa8bdb3e8bea90ec943532411b189","text":" (@Hyaxia, ","translated":" (@Hyaxia, ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:06:18Z"} -{"cache_key":"98d3cdf18a2db583a11d3eb9c8159f58997167f3983c6d8d64b80328eddb1b19","segment_id":"environment.md:aac7246f5e97142c","source_path":"environment.md","text_hash":"aac7246f5e97142c3f257b7d8b84976f10c29e1b89804bb9d3eb7c43cc03cb8e","text":"Environment variables","translated":"环境变量","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:49Z"} -{"cache_key":"98d73d2aa5399573ee48d8f16092a00b1d2eadae28493c02ff77524338175f2e","segment_id":"help/index.md:156597e2632411d1","source_path":"help/index.md","text_hash":"156597e2632411d1d5f634db15004072607ba45072a4e17dfa51790a37b6781f","text":"Gateway issues:","translated":"Gateway 问题:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:17Z"} -{"cache_key":"98ea6f91820d8c3481102e31672db08e7244fe1323f120f2fd8e61e89b94335d","segment_id":"index.md:9abe8e9025013e78","source_path":"index.md","text_hash":"9abe8e9025013e78a6bf2913f8c20ee43134ad001ce29ced89e2af9c07096d8f","text":"Media: images","translated":"媒体:图片","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:04:59Z"} -{"cache_key":"99777f2060729ab9a46bd52bd1987164d05761c7d99620992bc4cd4faaf79fdf","segment_id":"start/wizard.md:355a68267542db8b","source_path":"start/wizard.md","text_hash":"355a68267542db8b128049bdf8c3a39dda00fb9534370564874c04752aac8cd4","text":"which stores ","translated":"它会将 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:23Z"} -{"cache_key":"99d81c989d83fd644fbd647a5b6e583ccd7f640ef687e5a62751e2c1da8ba138","segment_id":"environment.md:e8c89c33e900bb9b","source_path":"environment.md","text_hash":"e8c89c33e900bb9b97f9c3b025f349fd3d91202293f3eff66c7fb4de7da892b6","text":" enabled.","translated":" 启用,shell 导入仍会运行。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:27Z"} -{"cache_key":"99ec1731cc9a06b32983cce57635d9b8df9ac1989c84ec9406049fba273998a4","segment_id":"environment.md:b1d6b91b67c2afa5","source_path":"environment.md","text_hash":"b1d6b91b67c2afa5e322988d9462638d354ddf8a1ef79dba987f815c22b4baee","text":" at ","translated":" 位于 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:12Z"} -{"cache_key":"99fddd046201ffe3b168ecf4215f0360e5fd2691e6027266a31bf76b2882ab71","segment_id":"start/wizard.md:a30cb0435098e376","source_path":"start/wizard.md","text_hash":"a30cb0435098e3761bf442f8085eb0abbc96b38de185a291bfc09c2c31540b51","text":"OpenAI Code (Codex) subscription (Codex CLI)","translated":"OpenAI Code (Codex) 订阅 (Codex CLI)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:09Z"} -{"cache_key":"99fe8d690ab356c552c582382dc05f3b5f26bedd3ccc366caa37f9ed80844213","segment_id":"start/wizard.md:a276c16f5217dcae","source_path":"start/wizard.md","text_hash":"a276c16f5217dcaede2670c6683c189989c1ef08d928f3cd563b92bf138a42ea","text":"Primary entrypoint:","translated":"主要入口:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:05Z"} -{"cache_key":"9a064e63d5ae22ffdcaf42bd4bf73604e1a87c082e0195db4c3d382a48d1276c","segment_id":"start/wizard.md:f56c761705123bae","source_path":"start/wizard.md","text_hash":"f56c761705123bae6b46571f53cc1d68b2da4a34b76aaf5c76a47438f42e2d8b","text":"/concepts/oauth","translated":"/concepts/oauth","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:36Z"} -{"cache_key":"9a6e0001bdbf4e254feed1fae82e1c51386ae1721b274ba14a89c4efe47ef794","segment_id":"environment.md:8d076464a84995bc","source_path":"environment.md","text_hash":"8d076464a84995bc095e934b0aa1e4419372f27cd71d033571e4dbba201ee5d8","text":"You can reference env vars directly in config string values using ","translated":"您可以使用以下方式在配置字符串值中直接引用 环境变量 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:18Z"} -{"cache_key":"9a6ff65f8974f826fabad2312ba3e0b54a6288f56782335b2ce21d931fe6b30a","segment_id":"start/getting-started.md:996c32b35f2182a9","source_path":"start/getting-started.md","text_hash":"996c32b35f2182a9c83815395113f92344269ebb4ab3525017c4cafaa3d1a8fd","text":"Providers","translated":"提供商","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:09Z"} -{"cache_key":"9a7478d471c30618239146c8b7adbd3669fd552a2fafba13cc6dc8b51c083243","segment_id":"index.md:a194ca16424ddd17","source_path":"index.md","text_hash":"a194ca16424ddd17dacc45f1cbd7d0e41376d8955a7b6d02bc38c295cedd04e4","text":"RPC adapters","translated":"RPC 适配器","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:04:25Z"} -{"cache_key":"9aaaeb76bc162fe216b19290b0978994ad43023335a81224b65bf7e4849ed5b6","segment_id":"index.md:frontmatter:summary","source_path":"index.md:frontmatter:summary","text_hash":"891b2aa093410f546b89f8cf1aa2b477ba958c2c06d2ae772e126d49786df061","text":"Top-level overview of OpenClaw, features, and purpose","translated":"OpenClaw 的顶层概述、功能和用途","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:47:18Z"} -{"cache_key":"9b0b553b6bb64b97bc340190fc4f10febadb5c4542122d2dea4661534f60b8b6","segment_id":"index.md:a10f6ed8c1ddbc10","source_path":"index.md","text_hash":"a10f6ed8c1ddbc10d3528db7f7b6921c1dd5a5e78aa191ff017bf29ce2d26449","text":"⏱️ ","translated":"⏱️ ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:04Z"} -{"cache_key":"9bb6f5ad39ff9d7aff3bca1fda6f474e19f25c0ffaaffaf3b19c924234d8c03a","segment_id":"index.md:f0d82ba647b4a33d","source_path":"index.md","text_hash":"f0d82ba647b4a33da3008927253f9bed21e380f54eab0608b1136de4cbff1286","text":"OpenClaw bridges WhatsApp (via WhatsApp Web / Baileys), Telegram (Bot API / grammY), Discord (Bot API / channels.discord.js), and iMessage (imsg CLI) to coding agents like ","translated":"OpenClaw 将 WhatsApp(通过 WhatsApp Web / Baileys)、Telegram(Bot API / grammY)、Discord(Bot API / 渠道.discord.js)和 iMessage(imsg CLI)桥接到编程 智能体,例如 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:47:31Z"} -{"cache_key":"9c03abf2c27129fa2698e7640a7b9add5936e84cf6d779d5f189bf9a27940aa6","segment_id":"index.md:310cc8cec6b20a30","source_path":"index.md","text_hash":"310cc8cec6b20a3003ffab12f5aade078a0e7a7d6a27ff166d62ab4c3a1ee23d","text":"If you ","translated":"如果你 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:03:25Z"} -{"cache_key":"9c11b2ec1c922e332f69000a8a937f0a2318b5356faa6278a7580cc49c3526d5","segment_id":"index.md:e47cdb55779aa06a","source_path":"index.md","text_hash":"e47cdb55779aa06a74ae994c998061bd9b7327f5f171c141caf2cf9f626bfe4b","text":"Peter Steinberger","translated":"Peter Steinberger","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:05:52Z"} -{"cache_key":"9c2360243508b8766d5d9813350a4c3153aeb8349b8ddf8f214ba33983b71f50","segment_id":"environment.md:1ec31258a6b45ea9","source_path":"environment.md","text_hash":"1ec31258a6b45ea903cd76f5b0190a99ab56afff6241a04f0681eb12b7a02484","text":"Env var equivalents:","translated":"环境变量 等效项:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:41:21Z"} -{"cache_key":"9c32d4d41cfaa814eacd6b9157f02b4ae0f9824751479280fd755479974d0695","segment_id":"index.md:ba5ec51d07a4ac0e","source_path":"index.md","text_hash":"ba5ec51d07a4ac0e951608704431d59a02b21a4e951acc10505a8dc407c501ee","text":")","translated":")","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:47:53Z"} -{"cache_key":"9c583361a5ae41c801a429bb6666f9a7b2ec6705ff7f1446fcf6281b40f2d5da","segment_id":"index.md:b332c3492d5eb10a","source_path":"index.md","text_hash":"b332c3492d5eb10a118eb6d8b0dcd689bc2477ce2ae16b303753b942b54377bc","text":"Configuration","translated":"配置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:25Z"} -{"cache_key":"9c80e959862fdf2310d9719e9854c2424bb1e2fa55aabcde8b5caf060184bd85","segment_id":"start/wizard.md:197b37e09b318165","source_path":"start/wizard.md","text_hash":"197b37e09b3181655a23576caec90510709eacfecd39d7c55d9dca93cccaac9a","text":"npm / pnpm","translated":"npm / pnpm","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:45:49Z"} -{"cache_key":"9cbdb7ff14fdd8d015b7bcce3b3c0d48b1711e631ff86cae2c699684f8e4d143","segment_id":"start/wizard.md:c4b2896a2081395e","source_path":"start/wizard.md","text_hash":"c4b2896a2081395e282313d6683f07c81e3339ef8b9d2b5a299ea5b626a0998f","text":").","translated":")。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:17Z"} -{"cache_key":"9d44e8f510b7e2cf5ea7b08188a9c606937bc3db8c49e22d903828b34b8b04c1","segment_id":"start/wizard.md:19f53c2ccaf19969","source_path":"start/wizard.md","text_hash":"19f53c2ccaf199696e23d43812941e23fed0625900d2a551533304d6ca1980f6","text":" install or change anything on the remote host.","translated":" 在远程主机上安装或更改任何内容。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:40Z"} -{"cache_key":"9d7b3ce341253f712ecd8b4ca661ae0a6d85b1ee8e8ddf00b1ec02ca13d67237","segment_id":"help/index.md:569ca49f4aaf7846","source_path":"help/index.md","text_hash":"569ca49f4aaf7846e952c1d4aeca72febd0b79fa1c4f9db08fd3127551218572","text":"Install","translated":"安装","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:24:41Z"} -{"cache_key":"9db03f9dc7b789dbc3b4115e9b644cd22de2a63adeed02eb3b403a223d96b819","segment_id":"index.md:2b402c90e9b15d9c","source_path":"index.md","text_hash":"2b402c90e9b15d9c3ef65c432c4111108f54ee544cda5424db46f6ac974928e4","text":"🔐 ","translated":"🔐 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:14Z"} -{"cache_key":"9e0b7ed9895b612971d582145c837e95bfec8b051c6bccddd008d56dff778711","segment_id":"start/wizard.md:28d03596d24eeb4e","source_path":"start/wizard.md","text_hash":"28d03596d24eeb4eab2d6fe21ca1cb95be7cb1fa6f92933db05e2cc4f4cdfa06","text":"Skip","translated":"跳过","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:16Z"} -{"cache_key":"9e3a338fc3d6bce679ff4711d74e67c66877245b6ebd2c2a08f182a3a788dae6","segment_id":"start/getting-started.md:fd82e54418ec23cd","source_path":"start/getting-started.md","text_hash":"fd82e54418ec23cda00219878eaf76c3b37337b3dcb7560a941db6a0d2ec249e","text":": background install (launchd/systemd; WSL2 uses systemd)","translated":":后台安装(launchd/systemd;WSL2 使用 systemd)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:15Z"} -{"cache_key":"9e9a7f1005f6c8fc07bbbcded4f31d4f5564a378e2c4af541dbe1c1315165fa2","segment_id":"environment.md:b1d6b91b67c2afa5","source_path":"environment.md","text_hash":"b1d6b91b67c2afa5e322988d9462638d354ddf8a1ef79dba987f815c22b4baee","text":" at ","translated":" 位于 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:17Z"} -{"cache_key":"9f18072e77601b529d2c7b3ccba29effcace5e2ff848e7dc253434f6bbc94d39","segment_id":"start/getting-started.md:aa7fc908228260b4","source_path":"start/getting-started.md","text_hash":"aa7fc908228260b49b7837767419fdb1ab6be7f1a6930175fd00795cb1bd19fc","text":"Daemon","translated":"守护进程","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:13Z"} -{"cache_key":"9f321a29940495419d67ad4ba9b74534941c03957df80c8ddd22d40e2ed71d9c","segment_id":"environment.md:907940a35852447a","source_path":"environment.md","text_hash":"907940a35852447aad5f21c5a180d993ff31cfd5807b1352ed0c24eabe183465","text":"never override existing values","translated":"永远不覆盖已有的值","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:24Z"} -{"cache_key":"9f8debe489928579a649aee67a82d66af48bb993e545843a1ba939323fd52594","segment_id":"index.md:frontmatter:read_when:0","source_path":"index.md:frontmatter:read_when:0","text_hash":"08965a8ab25e66157009d1617fc167bcc2404fa0c0ca50b1e5e5750957be3b10","text":"Introducing OpenClaw to newcomers","translated":"向新用户介绍 OpenClaw","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:45Z"} -{"cache_key":"9f97e722bb08309f9f0490ef497ed3b8e9b5b00071c59dde29a3dd9471da6389","segment_id":"start/wizard.md:1bf470ef04c760ee","source_path":"start/wizard.md","text_hash":"1bf470ef04c760eeab30f680b75729f851e0045bd0c63a9f5fc56a8e3562b193","text":"Requires a logged-in user session; for headless, use a custom LaunchDaemon (not shipped).","translated":"需要已登录的用户会话;对于无头模式,请使用自定义 LaunchDaemon(未随附)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:45:14Z"} -{"cache_key":"9fd51e3ee4b19d2de868d2b4e8811d44509bdc07ae4fc5c9ad3f9cdffff41b4f","segment_id":"start/wizard.md:483a226d3bf316d4","source_path":"start/wizard.md","text_hash":"483a226d3bf316d46abacada3304da39fddb44f53ff4eb0cb627061a9ab44cab","text":" so launchd can read it.","translated":" 以便 launchd 可以读取。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:30Z"} -{"cache_key":"9fe10747da6ed5a4362c668166c1501624c52fc26255cde686f999a17e6186ca","segment_id":"environment.md:cda454f61dfcac70","source_path":"environment.md","text_hash":"cda454f61dfcac7007a9edc538f9f58cf38caa0652e253975979308162bccc53","text":"Gateway configuration","translated":"Gateway 配置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:32Z"} -{"cache_key":"9fe3f448ea4b66ae71aaa710f4684b854e1de585336fa81f594ab40d91843b3c","segment_id":"help/index.md:bfc5930cc2660330","source_path":"help/index.md","text_hash":"bfc5930cc2660330260afd407e98d86adaec0af48dd72b88dc33ef8e9066e2c9","text":"Install sanity (Node/npm/PATH):","translated":"安装完整性检查(Node/npm/PATH):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:14Z"} -{"cache_key":"9ff4e3a77b7395b11a7ccb909093b21c475fe55afff74e5f7e5d2d8e6122b424","segment_id":"index.md:8fdfb6437318756c","source_path":"index.md","text_hash":"8fdfb6437318756c950bf2261538f06236e36040986891fa7b43452b987fb9f3","text":" — an AI, probably high on tokens","translated":" — 大概是一个嗑多了 token 的 AI 说的","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:25Z"} -{"cache_key":"9ff80a7969b1f50607f2046588db0ff9bfa745245e27cd65bcd5f3f5a7181354","segment_id":"start/wizard.md:6ea5cd459d660a33","source_path":"start/wizard.md","text_hash":"6ea5cd459d660a33a88276c5483ca067aaefa500b8b349067ed7eaeda6d871a8","text":"No remote installs or daemon changes are performed.","translated":"不会执行远程安装或守护进程更改。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:46:29Z"} -{"cache_key":"a00706550adc72d0953bfca3d2d9ba92c66c2462d8110da48a062d7618ab3092","segment_id":"index.md:10bf8b343a32f7dc","source_path":"index.md","text_hash":"10bf8b343a32f7dc01276fc8ae5cf8082e1b39c61c12d0de8ec9b596e115c981","text":"WebChat","translated":"WebChat","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:53:08Z"} -{"cache_key":"a05d1b3ace09d73190450de5094411e34c68a30679d27f7485cd5077e6eb93b4","segment_id":"environment.md:frontmatter:summary","source_path":"environment.md:frontmatter:summary","text_hash":"78351223e7068721146d2de022fdf440c2866b2ee02fbbb50bf64369b999820b","text":"Where OpenClaw loads environment variables and the precedence order","translated":"OpenClaw 加载环境变量的位置及优先级顺序","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:07Z"} -{"cache_key":"a066cc68d6f3b2d3eb59c1a8859348223e884c87eb512c19cde3cb5e14ebc7ca","segment_id":"start/wizard.md:ab744fe26b887abd","source_path":"start/wizard.md","text_hash":"ab744fe26b887abdb3558472d5bfe074f2716bbd88c8fab2b86bc745cbe7cf52","text":"Tip: ","translated":"提示: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:45Z"} -{"cache_key":"a08b0f8129a90b28e13de7f9610a1f2d9421d75eed227b3d4036c3bfb91b06c5","segment_id":"start/wizard.md:fbb0f1b48888c121","source_path":"start/wizard.md","text_hash":"fbb0f1b48888c1213ed6d214e58b88f98b885fde7be5ea69b81caa8d32ffce29","text":"Sets ","translated":"设置 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:20Z"} -{"cache_key":"a09638c50f961a7ca5d6f411261c7dbc4a1c70677b9b54dd69f7c19300035a18","segment_id":"environment.md:baa5be7f6320780b","source_path":"environment.md","text_hash":"baa5be7f6320780bd7bb7b7ddbb8cd1ffb26ccf7d94d363350668c50aedcf95f","text":" (applied only if missing).","translated":" (仅在缺失时应用)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:53Z"} -{"cache_key":"a09a1449f338df66eb814dfd44c4ba2fb803af25fdb880365d9656fd10e68896","segment_id":"index.md:1eb6926214b56b39","source_path":"index.md","text_hash":"1eb6926214b56b396336f22c22a6f8a4c360cfe7109c8be0f9869655b9ff6235","text":"Pairing (DM + nodes)","translated":"配对(私聊 + 节点)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:07Z"} -{"cache_key":"a09eb80d6a469c1f8c38b2f519e5563d3e70b0c6d437c1379f9a1218996f56cb","segment_id":"index.md:frontmatter:read_when:0","source_path":"index.md:frontmatter:read_when:0","text_hash":"08965a8ab25e66157009d1617fc167bcc2404fa0c0ca50b1e5e5750957be3b10","text":"Introducing OpenClaw to newcomers","translated":"向新用户介绍 OpenClaw","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:27:26Z"} -{"cache_key":"a0a0b7d915a1d0f6cdedf629867e973881d7354388fd9ce112d4863e6d5e8e2f","segment_id":"start/wizard.md:656458ef5481a088","source_path":"start/wizard.md","text_hash":"656458ef5481a0885762810b02f1a4c75c6f6ffa968fd85028b9e810f5e1219f","text":"Re-running the wizard does ","translated":"重新运行向导 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:10Z"} -{"cache_key":"a0ba382a0fbf8fd57a0f05d2058dbf6147bcd4387a60e8b082c2009fc31db28b","segment_id":"help/index.md:3c33340bd23b8db8","source_path":"help/index.md","text_hash":"3c33340bd23b8db89f18fe7d05a954738c0dd5ba9623cf6bdb7bb5d1a3729cfc","text":"FAQ (concepts)","translated":"常见问题(概念)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:38Z"} -{"cache_key":"a0c0d04dc411248ead0dc8669af49162ca2857cc967670a1db53f5350ef36c7a","segment_id":"help/index.md:8ddb7fc8a87904de","source_path":"help/index.md","text_hash":"8ddb7fc8a87904dedc2afc16400fbe4e78582b302e01c30b1319c8a465d04684","text":"Troubleshooting:","translated":"故障排除:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:56:20Z"} -{"cache_key":"a0d2cd21a3b93f857394aa3ed248a36130e8edfcf329e3cf57411efb04382e5a","segment_id":"environment.md:f7e239a42b7cd986","source_path":"environment.md","text_hash":"f7e239a42b7cd986a1558fed234e975ed2e96e9d37cf0a93f381778c461c89dd","text":"OpenClaw pulls environment variables from multiple sources. The rule is ","translated":"OpenClaw 从多个来源获取环境变量。规则是 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:17Z"} -{"cache_key":"a0e99af5ca5e84733312e288abcca135768e88eccf093eceeb670be82e40d41f","segment_id":"help/index.md:24669ff48290c187","source_path":"help/index.md","text_hash":"24669ff48290c1875d8067bbd241e8a55444839747bffb8ab99f3a34ef248436","text":"Doctor","translated":"诊断工具","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:35Z"} -{"cache_key":"a21eca32ff057c4ce091d2964d7860ed8ec2edc05aa6c20fefc81f158d396755","segment_id":"help/index.md:729bc562eec2658b","source_path":"help/index.md","text_hash":"729bc562eec2658bd11ffdd522fe5277177dc73e86eaca7baac0b472a4d8f8b2","text":"If you’re looking for conceptual questions (not “something broke”):","translated":"如果你在寻找概念性问题(而不是\"出了问题\"):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:01Z"} -{"cache_key":"a235aca76de620b9ed0805727dc5f142a660dc6dac3254a01531acad96cb084d","segment_id":"index.md:d53b75d922286041","source_path":"index.md","text_hash":"d53b75d9222860417f783b0829023b450905d982011d35f0e71de8eed93d90fc","text":"New install from zero:","translated":"从零开始全新安装:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:05Z"} -{"cache_key":"a28528856eac855eaf431dc468f5d1a9b3918df6dc73a9bb54c488aa7c23faad","segment_id":"start/getting-started.md:387847437e10c06c","source_path":"start/getting-started.md","text_hash":"387847437e10c06cae87567a6579b38e71849aea9c2355eba4a8d090418360b9","text":"The wizard can write tokens/config for you. If you prefer manual config, start with:","translated":"向导可以为您写入令牌/配置。如果您更喜欢手动配置,请从以下内容开始:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:19Z"} -{"cache_key":"a28d9fd85bfd4afc9a62b3cfe12607c86001b32a9a97d72eeb6cd50993fb51ee","segment_id":"index.md:c6e91f3b51641b1c","source_path":"index.md","text_hash":"c6e91f3b51641b1c43d297281ee782b40d9b3a0bdd7afc144ba86ba329d5f95f","text":"OpenClaw = CLAW + TARDIS","translated":"OpenClaw = CLAW + TARDIS","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:04Z"} -{"cache_key":"a2c462e51d228b070aba2a14a09d41aa54e0962d795724d5a090c71c7e242dfe","segment_id":"start/getting-started.md:acdd1e734125f341","source_path":"start/getting-started.md","text_hash":"acdd1e734125f341604c0efbabdcc4c4b0597e8f6235d66c2445edd1812838c1","text":"Telegram","translated":"Telegram","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:22Z"} -{"cache_key":"a2f08193fbeb8a9400b75d96157bbbf488ab3aa51d50658094d00bb841646217","segment_id":"help/index.md:2adc964c084749b1","source_path":"help/index.md","text_hash":"2adc964c084749b1f2d8aef24030988b667dbda2e38a6a1699556c93e07c1cea","text":"Start here","translated":"从这里开始","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:44:37Z"} -{"cache_key":"a32d46351380765e1ec38639781fc9e5abaccdf74240eee7ab685f570551f487","segment_id":"index.md:7d8b3819c6a9fb72","source_path":"index.md","text_hash":"7d8b3819c6a9fb726f40c191f606079b473f6f72d4080c13bf3b99063a736187","text":"Ops and safety:","translated":"运维与安全:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:04Z"} -{"cache_key":"a33cc9039329637ba985cef1ca2948d9f26eb2445653d3b7530bec79b97f550e","segment_id":"index.md:774f1d6b2910de20","source_path":"index.md","text_hash":"774f1d6b2910de200115afec1bd87fe1ea6b0bc2142ac729e121e10a45df4b5d","text":" ← ","translated":" ← ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:20Z"} -{"cache_key":"a34a85b676726b7a90c88b91c5bb2a67ef320ebcac8bd9eabe626eefb3e8dee1","segment_id":"environment.md:62d66b8c36a6c9aa","source_path":"environment.md","text_hash":"62d66b8c36a6c9aa7134c8f9fe5912435cb0b3bfce3172712646a187954e7040","text":"See [Configuration: Env var substitution](/gateway/configuration#env-var-substitution-in-config) for full details.","translated":"详见 [配置:环境变量替换](/gateway/configuration#env-var-substitution-in-config)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:19:47Z"} -{"cache_key":"a34be228f3b2eda3844fb225eb35e1ebb8875ee64a19a2bba1e88f5c21146ec3","segment_id":"start/getting-started.md:6ae8b12a4b2d056a","source_path":"start/getting-started.md","text_hash":"6ae8b12a4b2d056ab9e19350d8bbffea9178d4fe1aad54e7cb6805578e75a34d","text":": OpenAI Code (Codex) subscription (OAuth) or API keys. For Anthropic we recommend an API key; ","translated":":OpenAI Code (Codex) 订阅(OAuth)或 API 密钥。对于 Anthropic,我们推荐使用 API 密钥; ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:06Z"} -{"cache_key":"a3909a297d0e74a4cb418a7a549f495f6eed24048ebf8f12f448eff8d7a20c50","segment_id":"environment.md:1ec31258a6b45ea9","source_path":"environment.md","text_hash":"1ec31258a6b45ea903cd76f5b0190a99ab56afff6241a04f0681eb12b7a02484","text":"Env var equivalents:","translated":"等效的环境变量:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:26:18Z"} -{"cache_key":"a3e59ee4578bdb5fd68940692f78e9389e163da63e350ba9f0689ffbc980d4a5","segment_id":"environment.md:28b1103adde15a9d","source_path":"environment.md","text_hash":"28b1103adde15a9ddd8fc71f0c57dc155395ade46a0564865ccb5135b01c99b7","text":"OpenClaw pulls environment variables from multiple sources. The rule is **never override existing values**.","translated":"OpenClaw 从多个来源拉取环境变量。规则是**永远不覆盖已有的值**。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:19:23Z"} -{"cache_key":"a4384986e5ce06eca0118051e6a851ac0fd3d922d4d1f31b60000687962a2288","segment_id":"start/wizard.md:ec1a3a5d6d6f0bac","source_path":"start/wizard.md","text_hash":"ec1a3a5d6d6f0baca7805bf1ea17fc7b02042416f02f80bc1970ad8c710abd89","text":"Flow details (local)","translated":"流程详情(本地)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:56Z"} -{"cache_key":"a46b3daf9b1e1045e72e437a283e8377ec9b4820cde181d05a24a9a582cbf914","segment_id":"start/wizard.md:12754931af777521","source_path":"start/wizard.md","text_hash":"12754931af777521bcb6a904d2a7d342d0d77e6c4f1f2eb1b8b3753d25a1ab4a","text":"If the Control UI assets are missing, the wizard attempts to build them; fallback is ","translated":"如果 Control UI 资源文件缺失,向导会尝试构建它们;后备方案是 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:46:06Z"} -{"cache_key":"a4a009f8c9411234d5dd3ef4a71fdf292ec59e29a2b74d197acea1c789825536","segment_id":"help/index.md:6cb77499abdccd9a","source_path":"help/index.md","text_hash":"6cb77499abdccd9a2dbb7c93a4d31eed01613dda06302933057970df9ecdeb54","text":"Logs:","translated":"日志:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:24:46Z"} -{"cache_key":"a4b963e5c58f681343b2e7b98ade4df71e3a328906ed382ffc8c0e4853fdf162","segment_id":"environment.md:b1d6b91b67c2afa5","source_path":"environment.md","text_hash":"b1d6b91b67c2afa5e322988d9462638d354ddf8a1ef79dba987f815c22b4baee","text":" at ","translated":" 位于 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:39Z"} -{"cache_key":"a4cca9ee9c91e2df4fbfddb735c879510d4ef8e808b15a6b2697d94e08e08696","segment_id":"index.md:233cfad76c3aa9dd","source_path":"index.md","text_hash":"233cfad76c3aa9dd5cc0566746af197eac457a88c1e300ae788a8ada7f96b383","text":"From source (development):","translated":"从源码安装(开发):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:03:06Z"} -{"cache_key":"a4f4e3c0c2201e9d7bb71be5c98cfd3035febf5faea9901a446d2acfabaf119f","segment_id":"start/wizard.md:35dbeb1dcbaf6ec1","source_path":"start/wizard.md","text_hash":"35dbeb1dcbaf6ec104ff612596126f8f6eb79bca9e75e88e93021b57b1c3590b","text":"Providers: ","translated":"提供商: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:49:13Z"} -{"cache_key":"a501788647b1bdfef85962c5f388a3813fb838cf35407849bbce0d5f5090622d","segment_id":"environment.md:d942f64886578d87","source_path":"environment.md","text_hash":"d942f64886578d8747312e368ed92d9f6b2a8d45556f0f924e2444fe911d15af","text":" import","translated":" 导入","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:37Z"} -{"cache_key":"a52a1dde459a24de35447cda1771491fefcb09e9c555e0bbf08ee1a315353a2f","segment_id":"start/wizard.md:4fc4905e7b9c21f7","source_path":"start/wizard.md","text_hash":"4fc4905e7b9c21f7b34ec04b677a7f443624c0f724849ef2ca258da070ac35ca","text":" install + account config.","translated":" 安装 + 账户配置。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:44:51Z"} -{"cache_key":"a53c70efce0e16817f30acfd99d7db48bac27a7ec5d2c6235d65c8d97f59d781","segment_id":"start/wizard.md:daee7606b339f3c3","source_path":"start/wizard.md","text_hash":"daee7606b339f3c339076fe2c9f372a3ff40c8ee896005d829c7481b64ca5303","text":"Reset","translated":"重置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:13Z"} -{"cache_key":"a5767baee89195aa9db45c28cde3149e24b750a0e2e80d3730e1b61daec207e6","segment_id":"start/wizard.md:5c462b6b373504d5","source_path":"start/wizard.md","text_hash":"5c462b6b373504d54bc3262921f4a1a0cf666b8653e4122b418630d3f35f3ed3","text":" launches the wizard.","translated":" 运行会启动向导。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:46:52Z"} -{"cache_key":"a58f3ba9f36e7098f425445110c616f706c428aa8cd60c3e31c7d027229fd02e","segment_id":"help/index.md:frontmatter:summary","source_path":"help/index.md:frontmatter:summary","text_hash":"aece82a2d540ab1a9a21c7b038127cae6e9db2149491564bb1856b6f8999f205","text":"Help hub: common fixes, install sanity, and where to look when something breaks","translated":"帮助中心:常见修复方法、安装完整性检查,以及出现问题时的排查方向","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:06Z"} -{"cache_key":"a5b98e5a231f8db1b639acf7d415ecc749f34a640c80228784de562431a620af","segment_id":"start/wizard.md:6b09602d76f9ec29","source_path":"start/wizard.md","text_hash":"6b09602d76f9ec29755127ad2eb6a286fc47675e58b2df4cd1749a5dc4e19376","text":") and offers scopes:","translated":")并提供作用域:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:29Z"} -{"cache_key":"a5ce1d689305d466562771f1be3de56b5a492ced09caf35aaaa25b35c0a314eb","segment_id":"index.md:0eb95fb6244c03f1","source_path":"index.md","text_hash":"0eb95fb6244c03f1ccca696718a06766485c231347bf382424fb273145472355","text":"Quick start","translated":"快速开始","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:02:49Z"} -{"cache_key":"a5f308741639ce5bbd185e1ebe60322316c02afc8eb8caf44b469ee2041fded0","segment_id":"start/getting-started.md:d03502c43d74a30b","source_path":"start/getting-started.md","text_hash":"d03502c43d74a30b936740a9517dc4ea2b2ad7168caa0a774cefe793ce0b33e7","text":", ","translated":", ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:09Z"} -{"cache_key":"a626e7fe04bc58aa97f7363efbdaa14d5804691b203594e954e7373d26bc5bbb","segment_id":"start/getting-started.md:f68f6c2d3e9114cf","source_path":"start/getting-started.md","text_hash":"f68f6c2d3e9114cfec906d6a20cd048091e580c6e1d00a8066165dba188f9b3e","text":"channels (WhatsApp/Telegram/Discord/Mattermost (plugin)/...)","translated":"渠道(WhatsApp/Telegram/Discord/Mattermost(插件)/...)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:56Z"} -{"cache_key":"a6765fa54adfb2c44e2c668f9e03bb6668ee81809487078ceafc3e25ab776985","segment_id":"index.md:ded906ea94d05152","source_path":"index.md","text_hash":"ded906ea94d0515249f0bcab1ba63835b5968c142e9c7ea0cb6925317444d98c","text":"Configuration examples","translated":"配置示例","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:04:00Z"} -{"cache_key":"a696427cc9f77535e0a437bc4ced6dbbed14ef7d40f617ee28ff6c96b03b3888","segment_id":"start/getting-started.md:8ed8fc3de6f7cb89","source_path":"start/getting-started.md","text_hash":"8ed8fc3de6f7cb899073925b4e51ad2ce2d41fc97493347125c0f501f96ae205","text":"workspace bootstrap + skills","translated":"工作区引导 + 技能","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:00Z"} -{"cache_key":"a6e1f8b003a9aa3df1fc6040ef393aff9f02788a25d88903604584ac44a7cfde","segment_id":"index.md:65fd6e65268ff905","source_path":"index.md","text_hash":"65fd6e65268ff9057a49d832cccfcd5a376e46a908a2129be5b43f945fa8d8ca","text":": Gateway WS defaults to ","translated":":Gateway WS 默认为 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:40Z"} -{"cache_key":"a708335602471087cfca37672f53ab2f79c69ddf48fdb3d9f18a79065b57d68c","segment_id":"index.md:6201111b83a0cb5b","source_path":"index.md","text_hash":"6201111b83a0cb5b0922cb37cc442b9a40e24e3b1ce100a4bb204f4c63fd2ac0","text":" and ","translated":" 和 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:38Z"} -{"cache_key":"a70d2c258834cd52f862bddbf79987e31a906cb42a011a4b01c5833810163e67","segment_id":"help/index.md:d3ef01b4a9c99103","source_path":"help/index.md","text_hash":"d3ef01b4a9c9910364c9b26b2499c8787a0461d2d24ab80376fff736a288b34c","text":"Logging","translated":"日志记录","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:28Z"} -{"cache_key":"a7acef28bba8cdb6a32f047b98acad22efeb347de55a39db88b2191da5e2b0d7","segment_id":"index.md:93c89511a7a5dda3","source_path":"index.md","text_hash":"93c89511a7a5dda3b3f36253d17caee1e31f905813449d475bc6fed1a61f1430","text":"common fixes + troubleshooting","translated":"常见修复方案 + 故障排除","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:58Z"} -{"cache_key":"a7ba9dcc031859590f1c52cf8ee0e6243302b15838ac61a0513bcdef5ad90138","segment_id":"help/index.md:bfc5930cc2660330","source_path":"help/index.md","text_hash":"bfc5930cc2660330260afd407e98d86adaec0af48dd72b88dc33ef8e9066e2c9","text":"Install sanity (Node/npm/PATH):","translated":"安装完整性检查(Node/npm/PATH):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:56:23Z"} -{"cache_key":"a86f676c046c31e9ec14194f2cd6b154bad22422ff1e0cd75504746b2e3ff3e9","segment_id":"index.md:2f1626425f985d9a","source_path":"index.md","text_hash":"2f1626425f985d9ad8c124ea8ccb606e404ae5f43c58bd16b6c109d6d2694083","text":"Most operations flow through the ","translated":"大多数操作通过 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:21Z"} -{"cache_key":"a8956cdeec536a6d374d68798de5d28d4415bd3929c6129b678f86333a476663","segment_id":"index.md:0d3a30eb74e2166c","source_path":"index.md","text_hash":"0d3a30eb74e2166c1fc51b99b180841f808f384be53fe1392cecb67fdc9363c4","text":" (default ","translated":" (默认 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:24Z"} -{"cache_key":"a8b62b93b0c0bf52adc8e6428cf65abd66a23a669fc4902297be8ac01330e248","segment_id":"environment.md:9e471951a1b4106e","source_path":"environment.md","text_hash":"9e471951a1b4106e54be128a21112b02914fe98cc79b2c92b49ee80c5464487c","text":"Environment","translated":"环境","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:17Z"} -{"cache_key":"a8c116397b4632fb63df875275cd7a20e4eb7bcccf5f1015140f94df02c46874","segment_id":"index.md:86e2bbbc305c31aa","source_path":"index.md","text_hash":"86e2bbbc305c31aa988751196a1e207da68801a48798c48b90485c11578443a0","text":"Providers and UX:","translated":"提供商与用户体验:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:30Z"} -{"cache_key":"a8c2c86f1c2602cf80227b2f202b054928d4713c034b77d5bffa32f45a43f662","segment_id":"help/index.md:8ddb7fc8a87904de","source_path":"help/index.md","text_hash":"8ddb7fc8a87904dedc2afc16400fbe4e78582b302e01c30b1319c8a465d04684","text":"Troubleshooting:","translated":"故障排除:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:44:35Z"} -{"cache_key":"a93199a15f18e1ac6b70e21111f3bcce4117105f7e56633e0ec5653e45402bd6","segment_id":"index.md:0c67abfaa5415391","source_path":"index.md","text_hash":"0c67abfaa5415391a31cf3a4624746b6b212b5ae66364be28ee2d131f014e0c6","text":"🧩 ","translated":"🧩 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:45Z"} -{"cache_key":"a935bca4180982ba3ca63187d99531e61543ace3acdb5664f583de4dadebb841","segment_id":"index.md:3fc5f55ea5862824","source_path":"index.md","text_hash":"3fc5f55ea5862824fc266d26cd39fb5da22cc56670c11905d5743adac10bc9ef","text":"Mattermost Bot (plugin)","translated":"Mattermost 机器人(插件)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:11Z"} -{"cache_key":"a95002f09359a779a93f9b9c36001885ec2e7db3ab63c978bcfe94052728248d","segment_id":"start/wizard.md:9f088dbebd6c3c70","source_path":"start/wizard.md","text_hash":"9f088dbebd6c3c70a5ddbc2c943b11e4ca9acea5757b0b4f2b32479f0dbb747e","text":"Advanced","translated":"高级","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:39Z"} -{"cache_key":"a9c30fa450ed436cb03bc256b3075761a9215bd99bcd7bd2891cf15317ffd34f","segment_id":"environment.md:d08a8493f686363a","source_path":"environment.md","text_hash":"d08a8493f686363a78b913d45ebfbd87a3768d1c77b70f23b1fdade3c066e481","text":"Shell env import","translated":"Shell 环境导入","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:47Z"} -{"cache_key":"aa80cfc76e76409c5ba7bf331e4fb8aadf72703ead80d203c94e74209da993f9","segment_id":"index.md:310cc8cec6b20a30","source_path":"index.md","text_hash":"310cc8cec6b20a3003ffab12f5aade078a0e7a7d6a27ff166d62ab4c3a1ee23d","text":"If you ","translated":"如果你 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:31Z"} -{"cache_key":"aaa5becdcd694b68de2e61f6a13bd932c3f80f8b0b5a959a054a61ad5911beef","segment_id":"index.md:81a1c0449ea684aa","source_path":"index.md","text_hash":"81a1c0449ea684aadad54a7f8575061ddc5bfa713b6ca3eb8a0228843d2a3ea1","text":"Nodes (iOS/Android)","translated":"节点(iOS/Android)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:22Z"} -{"cache_key":"aacffcbc2a97abf1a5eccd00e5893be1125e364251fa27f3e0c88ef2db2b0248","segment_id":"index.md:acdd1e734125f341","source_path":"index.md","text_hash":"acdd1e734125f341604c0efbabdcc4c4b0597e8f6235d66c2445edd1812838c1","text":"Telegram","translated":"Telegram","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:36Z"} -{"cache_key":"aad00bc21098071ff9c86ff467cb7f5c65d3467ce4bf7d707f560479783e9eaa","segment_id":"index.md:b79cac926e0b2e34","source_path":"index.md","text_hash":"b79cac926e0b2e347e72cc91d5174037c9e17ae7733fd7bdb570f71b10cd7bfc","text":"Help","translated":"帮助","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:51Z"} -{"cache_key":"aae01909516ef373ddb2e4996f9016675f297208f7f075a68490f1f48eb0c87f","segment_id":"environment.md:6a26e1694d9e8520","source_path":"environment.md","text_hash":"6a26e1694d9e852038e5a472ed6b54cc023b4ace8ac10d745cad426d5dc057f3","text":" details.","translated":" 详情。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:47:11Z"} -{"cache_key":"aae4e71d06b01c462919dcb88e06b6e65c9edf88f774847e6397e907b81af99b","segment_id":"environment.md:7175517a370b5cd2","source_path":"environment.md","text_hash":"7175517a370b5cd2e664e3fd29c4ea9db5ce17058eb9772fe090a5485e49dad6","text":" or ","translated":" 或 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:41:03Z"} -{"cache_key":"aaf2e5a5c90fbf43eb61201449ef2794c5a272f1262285178a51a22890816101","segment_id":"environment.md:d4a67341570f4656","source_path":"environment.md","text_hash":"d4a67341570f4656784c5f8fe1bfb48a738ace57b52544977431d50e2b718099","text":"FAQ: env vars and .env loading","translated":"常见问题:环境变量与 `.env` 加载","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:13:14Z"} -{"cache_key":"ab19c27dcd5a1799b5d41ad95ccd7cc9a8ec1e685e7b7bcbc6f620a57ba64c73","segment_id":"index.md:39bbb719fa2b9d22","source_path":"index.md","text_hash":"39bbb719fa2b9d2251039cbf2cd072e1120a414278263e2f11d99af0236c4262","text":"Groups","translated":"群组","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:42Z"} -{"cache_key":"ab2362ccd249b707169072e9b3e0030307eca102e4795d4252be21f596247a95","segment_id":"start/getting-started.md:624f09022ea974b9","source_path":"start/getting-started.md","text_hash":"624f09022ea974b98abb7e922576072ca4467f4f6cce62d39b5591207fca4232","text":" (Ubuntu recommended). WSL2 is strongly recommended; native Windows is untested, more problematic, and has poorer tool compatibility. Install WSL2 first, then run the Linux steps inside WSL. See ","translated":" (推荐 Ubuntu)。强烈推荐使用 WSL2;原生 Windows 未经测试,问题较多,且工具兼容性较差。请先安装 WSL2,然后在 WSL 内执行 Linux 步骤。参见 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:42Z"} -{"cache_key":"ab5a661b139f2271cc3da6eb98afbd8c56c9a47b1bfa2570aba46677a28bb509","segment_id":"index.md:6d6577cb1c128ac1","source_path":"index.md","text_hash":"6d6577cb1c128ac18a286d3c352755d1a265b1e3a03eded8885532c3f36e32ed","text":"Mario Zechner","translated":"Mario Zechner","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:06:00Z"} -{"cache_key":"abafe9669ff562150a4e76ad066e4ad761bb391e29ce4416a9b58e1583e500be","segment_id":"environment.md:7175517a370b5cd2","source_path":"environment.md","text_hash":"7175517a370b5cd2e664e3fd29c4ea9db5ce17058eb9772fe090a5485e49dad6","text":" or ","translated":" 或 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:55Z"} -{"cache_key":"abc5cfa176d8a536bccc8bdf09aa69c56c08c41f519d5e050384ecf88670ce2d","segment_id":"help/index.md:8cd501e1124c3047","source_path":"help/index.md","text_hash":"8cd501e1124c30473473c06e536a2d145e2a14a6d7dc1b99028ce818e14442e2","text":"Repairs:","translated":"修复:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:33Z"} -{"cache_key":"abdba3de87eed812fa8b91c34ca0a00364c0d432e6dd6229b58ca9ab81f3828a","segment_id":"index.md:316cd41f595f3095","source_path":"index.md","text_hash":"316cd41f595f3095f149f98af70f77ab85404307a1505467ee45a26b316a9984","text":"Guided setup (recommended):","translated":"引导式设置(推荐):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:47:46Z"} -{"cache_key":"abf5a32f0d0613c45205a09d8a62ba4454c5a1e6342938a841eb266f169648fa","segment_id":"environment.md:496aca80e4d8f29f","source_path":"environment.md","text_hash":"496aca80e4d8f29fb8e8cd816c3afb48d3f103970b3a2ee1600c08ca67326dee","text":" block","translated":" 块","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:22Z"} -{"cache_key":"ac1c676f8b0fc38c55da8beae422685700924821fc4a22af902f4028e6b6b1b4","segment_id":"start/getting-started.md:b97a7337efe8076b","source_path":"start/getting-started.md","text_hash":"b97a7337efe8076beea41f887d7fb1006d383c094728e3ddfe3e6228e47ca095","text":"macOS remote","translated":"macOS 远程","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:44Z"} -{"cache_key":"ac7c1c475e44053caaa8f0aad4a4c7cf61d349b95857ea7b44ac1e48836f9783","segment_id":"environment.md:6863067eb0a2c749","source_path":"environment.md","text_hash":"6863067eb0a2c7499425c6c189b2c88bac55ca754285a6ab1ef37b75b4cfad4d","text":"See ","translated":"参见 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:13:03Z"} -{"cache_key":"ad1eb4b87dcff4153a93d9aa9f3adb2be423b8f3eb61c8c69e79cc843b9b06dc","segment_id":"start/getting-started.md:7843665e87c6ef82","source_path":"start/getting-started.md","text_hash":"7843665e87c6ef82a8995362c43cacaf9aac743f9737aae4130de8fb3548e37b","text":").\n See ","translated":")。\n 参见 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:34Z"} -{"cache_key":"ad534581940aa1b636a88890801421659be78fa961141a10a595506ad9413584","segment_id":"index.md:3fc5f55ea5862824","source_path":"index.md","text_hash":"3fc5f55ea5862824fc266d26cd39fb5da22cc56670c11905d5743adac10bc9ef","text":"Mattermost Bot (plugin)","translated":"Mattermost 机器人(插件)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:47Z"} -{"cache_key":"ad6b8f87fd0971ae528bf36026dd7d1d1aecace6621ef3bfe00bc4f0195deece","segment_id":"start/wizard.md:325f237dda4ec247","source_path":"start/wizard.md","text_hash":"325f237dda4ec24753c4b157abd9645efd361ae1adf64a5a97f023c8bef7baff","text":"What the wizard does","translated":"向导的功能","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:11Z"} -{"cache_key":"ade480827c0ce46d4dfc9141efcaf7ff0afac9c4895ae48a4824049c1b079791","segment_id":"start/wizard.md:f3f51d88046314e4","source_path":"start/wizard.md","text_hash":"f3f51d88046314e4f0fb9e0e6d84a21ffd8ffeb7f8643f282c928a6176f84196","text":"The wizard starts with ","translated":"向导以 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:32Z"} -{"cache_key":"adfb3af54146b47b4e744815d9ccc0855ba7030eb0580a74b0bc2fc25be8825f","segment_id":"index.md:0b7e778664921066","source_path":"index.md","text_hash":"0b7e77866492106632e98e7718a8e1e89e8cb0ee3f44c1572dfd9e54845023de","text":"/concepts/streaming","translated":"/concepts/streaming","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:38Z"} -{"cache_key":"ae362832194711d0f893594a03e3bb80106c5f270cf53505aa8d85909cf18d1b","segment_id":"help/index.md:71095a6d42f5d9c2","source_path":"help/index.md","text_hash":"71095a6d42f5d9c2464a8e3f231fc53636d4ce0f9356b645d245874162ec07e2","text":"Gateway troubleshooting","translated":"Gateway 故障排除","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:24:44Z"} -{"cache_key":"ae38697f064f10b478a11c227a88eb0a8649159a6488fe8d31acc2cec8ad05fa","segment_id":"index.md:6e0f6eca4ff17d33","source_path":"index.md","text_hash":"6e0f6eca4ff17d3377c1c3e8e1f73457553ad3b9cfcd5e4f2b94cfb1028b6234","text":"iOS app","translated":"iOS 应用","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:05:08Z"} -{"cache_key":"ae6374b547927202ad7b2766b4b93d614453d51af2667ce8e8c4c50a1788ccda","segment_id":"index.md:79a482cf546c23b0","source_path":"index.md","text_hash":"79a482cf546c23b04cd48a33d4ca8411f62e5b7dc8c3a8f30165e28e747f263a","text":"iMessage","translated":"iMessage","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:18Z"} -{"cache_key":"ae7043304208a45c9727b207699b4a24db4fe776eee16a1c8f1bed9d9fcd7c5c","segment_id":"index.md:bf084dc7b82e1e62","source_path":"index.md","text_hash":"bf084dc7b82e1e62c63727b13451d1eba2269860e27db290d2d5908d7ade0529","text":" — Pairs as a node and exposes Canvas + Chat + Camera","translated":" — 作为节点配对并提供 Canvas + 聊天 + 相机","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:02Z"} -{"cache_key":"ae7343dadbee931e1ac99fcf3a1bdc0745e6960c0e075482401e7dc615439225","segment_id":"environment.md:46ab081177a452aa","source_path":"environment.md","text_hash":"46ab081177a452aa62354b581730f4675cb03e58cde8282071da30cabe18fb2e","text":"Optional login-shell import","translated":"可选的登录 shell 导入","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:50Z"} -{"cache_key":"ae96b8aee2f9be9d9843ec8c1f0c693d9d64a220bb3b226e904be86c041e5af4","segment_id":"index.md:41ed52921661c7f0","source_path":"index.md","text_hash":"41ed52921661c7f0d68d92511589cc9d7aaeab2b5db49fb27f0be336cbfdb7df","text":"Gateway","translated":"Gateway","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:34Z"} -{"cache_key":"aeac09e385428be1a6afe9d98844b4f45ffa5f9690937b11572543441dfbe93e","segment_id":"start/getting-started.md:frontmatter:read_when:0","source_path":"start/getting-started.md:frontmatter:read_when:0","text_hash":"1cbb4fd6536838366360092615465643e07ae65489e0d0a68f9b7500a7ac6c96","text":"First time setup from zero","translated":"从零开始的首次设置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:17Z"} -{"cache_key":"aeb7007c273f0c7bca86dbf2cd6cd544ca79abb504054d08244ad9f11abd4fa5","segment_id":"index.md:b0d125182029e6c5","source_path":"index.md","text_hash":"b0d125182029e6c500cbcc81011341df77de8fe24d9e80190c32be390c916ec2","text":"🤖 ","translated":"🤖 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:55Z"} -{"cache_key":"af003c0a076e77417f3b2415efeeb038bf57f2a1eed124f692238fcdb66119e8","segment_id":"start/wizard.md:1f66d361f1307d4e","source_path":"start/wizard.md","text_hash":"1f66d361f1307d4e66676bb21e36b6bc6be07759ca8cd0b1c73561821e298188","text":"Discovery hints:","translated":"发现提示:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:46:34Z"} -{"cache_key":"af2c767d10d616dd189bb9ed963e45f036beb388e91afbaa60bf62be6ef35d1e","segment_id":"index.md:075a4a45c3999f34","source_path":"index.md","text_hash":"075a4a45c3999f340be8487cd7c0dd2ed77ced931054d75e95e5e24d5539b45b","text":" — Pi (RPC mode) with tool streaming","translated":" —— Pi(RPC 模式),支持 工具 流式传输","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:02Z"} -{"cache_key":"af2f58bcf5bdd60d1c98dcbc846239117cef3e202bea91afc78f0147c45c3a60","segment_id":"index.md:255ce77b7a6a015f","source_path":"index.md","text_hash":"255ce77b7a6a015f8595868a524b67c134e8fb405f4584fdac020e57f4ccd5f6","text":"Loopback-first","translated":"回环优先","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:37Z"} -{"cache_key":"af3c614067406b2bfae3faa3dc5c74b9ad7de00832ef2213f1d208a39e4eae92","segment_id":"index.md:3c064c83b8d244fe","source_path":"index.md","text_hash":"3c064c83b8d244fef61e5fd8ce5f070b857a3578a71745e61eea02892788c020","text":" — Anthropic (Claude Pro/Max) + OpenAI (ChatGPT/Codex) via OAuth","translated":" — 通过 OAuth 支持 Anthropic(Claude Pro/Max)+ OpenAI(ChatGPT/Codex)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:20Z"} -{"cache_key":"af41fffb606a61d612d3709f3732fc9cddca09ff369ed0bf469af9c994fcc648","segment_id":"environment.md:8d076464a84995bc","source_path":"environment.md","text_hash":"8d076464a84995bc095e934b0aa1e4419372f27cd71d033571e4dbba201ee5d8","text":"You can reference env vars directly in config string values using ","translated":"你可以使用以下方式在配置的字符串值中直接引用环境变量 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:22:32Z"} -{"cache_key":"af52d0343a217e1ebc960bf8e847f48d24146c9a5f695eb4d0cfb1c13bd92e1c","segment_id":"start/getting-started.md:b482e45229e19f5f","source_path":"start/getting-started.md","text_hash":"b482e45229e19f5f7ba590b5ac81bdb25d5d24116ed961bfa0eb1a23c20a204c","text":" (or ","translated":" (或 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:11Z"} -{"cache_key":"af7a992a13d7295a28b94032d28c8cc7ae177dba2b4f2fbb2008c3de7a74c3dc","segment_id":"start/wizard.md:a6c7a84baa6750fc","source_path":"start/wizard.md","text_hash":"a6c7a84baa6750fce33f7512acd6793e53def1d228b5f2efb8074b42648424fc","text":"Finish","translated":"完成","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:45:58Z"} -{"cache_key":"af9372d7088143330cee32dde6ee4ea2058a314debffdfacbf5343da8e95da7b","segment_id":"environment.md:ffa63583dfa6706b","source_path":"environment.md","text_hash":"ffa63583dfa6706b87d284b86b0d693a161e4840aad2c5cf6b5d27c3b9621f7d","text":"missing","translated":"缺失的","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:41:16Z"} -{"cache_key":"afb8249d9b9d237120a860c3f9c70470fc1ba2125f5b94110e50b3b0073032c5","segment_id":"environment.md:cda454f61dfcac70","source_path":"environment.md","text_hash":"cda454f61dfcac7007a9edc538f9f58cf38caa0652e253975979308162bccc53","text":"Gateway configuration","translated":"Gateway 配置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:47:16Z"} -{"cache_key":"afba4d250aee5bbd63f27e2e64fdb895b043fdda06ee9b89a277422664d39428","segment_id":"environment.md:6863067eb0a2c749","source_path":"environment.md","text_hash":"6863067eb0a2c7499425c6c189b2c88bac55ca754285a6ab1ef37b75b4cfad4d","text":"See ","translated":"参见 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:47:05Z"} -{"cache_key":"afca6ce610f4888a3cfb0237a69f5700b984c656c5b829646fe19b2e61b8a190","segment_id":"start/wizard.md:316877bf8e401701","source_path":"start/wizard.md","text_hash":"316877bf8e401701c9ac95fdb7dee63577480e090eb586b6eb7cf7b36fa24cbf","text":"Google Chat","translated":"Google Chat","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:44:35Z"} -{"cache_key":"b004008c93e0b1ea2852beb2c430beae131fc3e19a69b11c5c9f2a24cda8590b","segment_id":"index.md:4818a3f84331b702","source_path":"index.md","text_hash":"4818a3f84331b702815c94b4402067e09e9e2d27ebc1a79258df8315f2c8600b","text":"📎 ","translated":"📎 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:35Z"} -{"cache_key":"b006bf9903fff3583e0a70cd9c332cdc44d30e5432e47628924d2b8d3f704444","segment_id":"index.md:053bc65874ad6098","source_path":"index.md","text_hash":"053bc65874ad6098e58c41c57b378a2f36b0220e5e0b46722245e6c2f796818c","text":"Discord","translated":"Discord","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:04:48Z"} -{"cache_key":"b0b8109bdac59602c326a82adc11b20713a0c0c2ad6595be6894fb0a3a489dc9","segment_id":"index.md:f0b349e90cb60b2f","source_path":"index.md","text_hash":"f0b349e90cb60b2f96222d0be1ff6532185f385f4909a19dd269ea3e9e77a04d","text":" (default); groups are isolated","translated":" (默认);群组为隔离","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:27Z"} -{"cache_key":"b0fcfd73b064dce0675db3e53661b400af1cfed802373334f865c27a3eda6303","segment_id":"help/index.md:frontmatter:summary","source_path":"help/index.md:frontmatter:summary","text_hash":"aece82a2d540ab1a9a21c7b038127cae6e9db2149491564bb1856b6f8999f205","text":"Help hub: common fixes, install sanity, and where to look when something breaks","translated":"帮助中心:常见修复方法、安装完整性检查,以及出现问题时的排查方向","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:18:54Z"} -{"cache_key":"b1248cc34d9a7c8ecfaa5612bfffbdaf26305acc8a6db269255ae6f591b4a841","segment_id":"start/getting-started.md:e16e5747158aac73","source_path":"start/getting-started.md","text_hash":"e16e5747158aac73e7f9e2ddb7c99efda2431fa25bb3effe93102c55fc7dbe77","text":": the wizard generates one by default (even on loopback) and stores it in ","translated":":向导默认会生成一个(即使在回环地址上)并将其存储在 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:25Z"} -{"cache_key":"b15acb5c7418f2e49045d730674b2f6470f73699aa97b03c7ada099d55cd53e8","segment_id":"environment.md:frontmatter:read_when:2","source_path":"environment.md:frontmatter:read_when:2","text_hash":"822b3d74ce16c1be19059fad4ca5bf7ae9327f58fa1ff4e75e78d5afa75c038f","text":"You are documenting provider auth or deployment environments","translated":"你正在编写提供商认证或部署环境的文档","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:19:18Z"} -{"cache_key":"b1a0214973416cbfb4dcac01605c51911f412a6b7d862a6b8aed7db6364bb93a","segment_id":"start/wizard.md:1a0f5fc7ca6e8a74","source_path":"start/wizard.md","text_hash":"1a0f5fc7ca6e8a74bc099d9c397a23564b55eca50c3b2e33c472acb7032a6f3b","text":" (if Minimax chosen)","translated":" (如果选择了 Minimax)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:48:35Z"} -{"cache_key":"b1babe6ce88663854adf02aa4a23f21c9a98e036c72bf36dbe4b518d5d025d8b","segment_id":"environment.md:8d076464a84995bc","source_path":"environment.md","text_hash":"8d076464a84995bc095e934b0aa1e4419372f27cd71d033571e4dbba201ee5d8","text":"You can reference env vars directly in config string values using ","translated":"您可以使用以下方式在配置字符串值中直接引用 环境变量 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:41:25Z"} -{"cache_key":"b1bfed2a2039ffc6f83d8201645caf18d6b942a8e5efbe2a28ca24978f750aa7","segment_id":"index.md:a97c0f391117ef55","source_path":"index.md","text_hash":"a97c0f391117ef554586ed43255ab3ff0e15adcfc1829c62b6d359672c0bec93","text":" — Mention-based by default; owner can toggle ","translated":" — 默认基于提及;所有者可切换 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:02:09Z"} -{"cache_key":"b1e93b43d06bcf0651c4bee0920f356e1f38bceca29db1936d449b4be99e77d2","segment_id":"index.md:8f6fb4eb7f42c0e2","source_path":"index.md","text_hash":"8f6fb4eb7f42c0e245e29e63f5b82cc3ba19852681d1ed9aed291f59cf75ec0e","text":"Security","translated":"安全","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:53:56Z"} -{"cache_key":"b212246fea49637bc0db899bd39dff2b1762ecf0d8cac3ec6160a8cd4c4da860","segment_id":"start/wizard.md:1f01936efef6e09c","source_path":"start/wizard.md","text_hash":"1f01936efef6e09cd29c9b1a9b6a64c1fcdb35682c9cf25db02dfde331f83fa7","text":" if present or prompts for a key, then saves it to ","translated":" (如果存在)或提示输入密钥,然后保存到 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:29Z"} -{"cache_key":"b240cb7927de51aca09fb318798ffd79fe597965722be259f799a2002cbe0f43","segment_id":"start/getting-started.md:4ea5ee68fea05586","source_path":"start/getting-started.md","text_hash":"4ea5ee68fea05586106890ded5733820bb77d919cda27bc4b8139b7cd33b8889","text":" gateway","translated":" Gateway","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:02Z"} -{"cache_key":"b27a4eb21eb3ee61916c2db4b356e29106524ae9d8e48aeb3f68f690c6cfb8f7","segment_id":"start/wizard.md:97f068362253059c","source_path":"start/wizard.md","text_hash":"97f068362253059c26de02d1c75c972c102f2ca201fca6015153c8077cfdbdd7","text":" way to set up OpenClaw on macOS,\nLinux, or Windows (via WSL2; strongly recommended).\nIt configures a local Gateway or a remote Gateway connection, plus channels, skills,\nand workspace defaults in one guided flow.","translated":" 在 macOS、Linux 或 Windows(通过 WSL2;强烈推荐)上设置 OpenClaw 的方式。它通过一个引导式流程配置本地 Gateway 或远程 Gateway 连接,以及渠道、技能和工作区默认设置。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:03Z"} -{"cache_key":"b2d36a6219cd6ef9fa18da47d2583999f398895d209ec3595c2c1f3789ded3f2","segment_id":"index.md:b79cac926e0b2e34","source_path":"index.md","text_hash":"b79cac926e0b2e347e72cc91d5174037c9e17ae7733fd7bdb570f71b10cd7bfc","text":"Help","translated":"帮助","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:17Z"} -{"cache_key":"b324a4a080cbe3b8cd7ae6ea1f8812027eeee42cdbd1db38d84f4240371db0ba","segment_id":"help/index.md:frontmatter:read_when:1","source_path":"help/index.md:frontmatter:read_when:1","text_hash":"857eafc389d179e83e21e46c10527fec40894fe064c63847ba06b946b7d5eb73","text":"Something broke and you want the fastest path to a fix","translated":"出了问题,你想要最快的修复方法","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:44:27Z"} -{"cache_key":"b36d09f6dceced206ef224552875840995ff1ad070c158298f356c7a308c4401","segment_id":"start/getting-started.md:f9194e73f9e9459e","source_path":"start/getting-started.md","text_hash":"f9194e73f9e9459e3450ea10a179cdf77aafa695beecd3b9344a98d111622243","text":"zero","translated":"零开始","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:26Z"} -{"cache_key":"b38f8218a329aa459516734a74c0141efdd0901ffc65900b9b5e3ffc338cb49d","segment_id":"start/getting-started.md:6201111b83a0cb5b","source_path":"start/getting-started.md","text_hash":"6201111b83a0cb5b0922cb37cc442b9a40e24e3b1ce100a4bb204f4c63fd2ac0","text":" and ","translated":" 和 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:40Z"} -{"cache_key":"b3eb30fbc137a10687841225ce40db87439bcd2052ede47102f01f5a3da81d12","segment_id":"environment.md:582967534d0f909d","source_path":"environment.md","text_hash":"582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf","text":" in ","translated":" 在 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:25Z"} -{"cache_key":"b3f38013bdfa47cf7e56f9f97e5f0c56d9ceb3fdede7720d31afe1aa3ed90d47","segment_id":"start/wizard.md:acde1b96aeebd08f","source_path":"start/wizard.md","text_hash":"acde1b96aeebd08fade2a26e1979ff55edee9a7e5b3b8d8bc7dd03b024ace1d0","text":"Skills (recommended)","translated":"技能(推荐)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:32Z"} -{"cache_key":"b3fd77464fffaf86fd7c4db02054abe4ad46b8da5cd9a6338a6a164a559039fb","segment_id":"index.md:1cce617e15b49dca","source_path":"index.md","text_hash":"1cce617e15b49dca89b212bb5290edfcfee010ef2eeef369b36af78c53756e1c","text":" — Optional transcription hook","translated":" — 可选的转录钩子","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:02:25Z"} -{"cache_key":"b42df969bf0af88635c8889e57849a3ae5110eab05a4f8e10b1c753221608cdb","segment_id":"environment.md:83848a0a1c101b44","source_path":"environment.md","text_hash":"83848a0a1c101b44035abecc16764b51778799d9824facbfaea7ac1f20205160","text":" missing).","translated":" 缺失时应用)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:09Z"} -{"cache_key":"b4368e7921aef9e2b39ca194a48d47f8f2f748e7fc40db1eaf6a96299c60c035","segment_id":"environment.md:frontmatter:summary","source_path":"environment.md:frontmatter:summary","text_hash":"78351223e7068721146d2de022fdf440c2866b2ee02fbbb50bf64369b999820b","text":"Where OpenClaw loads environment variables and the precedence order","translated":"OpenClaw 加载环境变量的位置及优先级顺序","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:42Z"} -{"cache_key":"b45cf341beae5b0925d7ae30c7cfb491da5599a692818f25de942e5f6d44fd5f","segment_id":"help/index.md:3c33340bd23b8db8","source_path":"help/index.md","text_hash":"3c33340bd23b8db89f18fe7d05a954738c0dd5ba9623cf6bdb7bb5d1a3729cfc","text":"FAQ (concepts)","translated":"常见问题(概念)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:03Z"} -{"cache_key":"b49a5c75c4eda0ec2bb03b48bc5f8fb35df49f92e48f750d30803e61536712db","segment_id":"environment.md:7af0b3e47c35820f","source_path":"environment.md","text_hash":"7af0b3e47c35820fabef69cc542392bd2d0f6e37c349851728f0c683013563ce","text":" variables","translated":" 变量","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:19Z"} -{"cache_key":"b49cd3645127938e9fa70191b75226ab757511ee636cdd90fd4dc9ef40062aac","segment_id":"index.md:a7a19d4f14d001a5","source_path":"index.md","text_hash":"a7a19d4f14d001a56c27f68a13ff267859a407c7a9ab457c0945693c9067dd1c","text":"Configuration (optional)","translated":"配置(可选)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:26Z"} -{"cache_key":"b4a0896a2b31bdc227d4c1aca7b2e0ff76155083208928f489c597b2ea6ec83d","segment_id":"start/getting-started.md:ab201ddd7ab330d0","source_path":"start/getting-started.md","text_hash":"ab201ddd7ab330d04be364c0ac14ce68c52073a0ee8d164a98c3034e91ce1848","text":" from the repo.","translated":" (从仓库中)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:49Z"} -{"cache_key":"b4fb8e7bfdb8c5557d0ae1e567ebe8d168cf15239a265bfc4f64adb97ce03bcf","segment_id":"environment.md:d08a8493f686363a","source_path":"environment.md","text_hash":"d08a8493f686363a78b913d45ebfbd87a3768d1c77b70f23b1fdade3c066e481","text":"Shell env import","translated":"Shell 环境导入","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:19:35Z"} -{"cache_key":"b51ede64ac884a3ba6ed593bb845e2b3e70fa2bcda693b30c537cde875c51011","segment_id":"index.md:9c870aa6e5e93270","source_path":"index.md","text_hash":"9c870aa6e5e93270170d5a81277ad3e623afe8d4efd186d3e28f3d2b646d52e6","text":"How it works","translated":"工作原理","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:30Z"} -{"cache_key":"b52208d557116bde692639f735198f71a925dc90223bf31e0b71e9ac7b5bf86d","segment_id":"help/index.md:24669ff48290c187","source_path":"help/index.md","text_hash":"24669ff48290c1875d8067bbd241e8a55444839747bffb8ab99f3a34ef248436","text":"Doctor","translated":"诊断工具","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:24:54Z"} -{"cache_key":"b5687bd5a0443bd1ccaa45996bbe3a784f66fa059e4aa68048a14712f853d56e","segment_id":"start/wizard.md:5f6a8991209034d4","source_path":"start/wizard.md","text_hash":"5f6a8991209034d4d6473c75e2f74dc3df90cc6cde2723d7d25085dbfc3fad24","text":"Providers (Telegram, WhatsApp, Discord, Google Chat, Mattermost (plugin), Signal)","translated":"提供商(Telegram、WhatsApp、Discord、Google Chat、Mattermost(插件)、Signal)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:26Z"} -{"cache_key":"b576ef2b8e071c57934d6ae354dfaa261e4f7db4bf4b3b56f33219032da96187","segment_id":"index.md:74926756385b8442","source_path":"index.md","text_hash":"74926756385b844294a215b2830576e3b2e93b84c5a8c8112b3816c5960f3022","text":" — DMs + guild channels via channels.discord.js","translated":" — 通过 channels.discord.js 支持私信和服务器 渠道","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:07Z"} -{"cache_key":"b5bd5c17c88739060e3c2a4e7a8f55897a310a69c59782ab65ef312c4d191057","segment_id":"environment.md:baa5be7f6320780b","source_path":"environment.md","text_hash":"baa5be7f6320780bd7bb7b7ddbb8cd1ffb26ccf7d94d363350668c50aedcf95f","text":" (applied only if missing).","translated":" (仅在缺失时应用)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:48Z"} -{"cache_key":"b5c57e3a1f3580ad70993c4901523fe0625b4b6b817da47743f3294dd6cf756e","segment_id":"environment.md:f0442e6e05ccca16","source_path":"environment.md","text_hash":"f0442e6e05ccca160d17de0e7d509891b91b921366b2202b2b5c80435824e140","text":"Two equivalent ways to set inline env vars (both are non-overriding):","translated":"设置内联环境变量的两种等效方式(均为不覆盖模式):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:43Z"} -{"cache_key":"b5d2ae67c5041c7e1d1c9eee9352714412cb0f7e25d70400ede3ec30640d3481","segment_id":"start/getting-started.md:0fe1f092dca5c0a5","source_path":"start/getting-started.md","text_hash":"0fe1f092dca5c0a52a3225794df21faacf2c8aecbb58e4b35256494e611b88bd","text":" your first DM returns a pairing code. Approve it (see next step) or the bot won’t respond.","translated":" 您的第一条私信会返回一个配对码。请批准它(参见下一步),否则机器人将不会响应。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:35Z"} -{"cache_key":"b634da14ec3675bd8c43260adb814ce2e1991550d8eec3a159a73a19bcae0a9a","segment_id":"environment.md:b1d6b91b67c2afa5","source_path":"environment.md","text_hash":"b1d6b91b67c2afa5e322988d9462638d354ddf8a1ef79dba987f815c22b4baee","text":" at ","translated":" 位于 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:41Z"} -{"cache_key":"b6ab46af0248d53e3135ec04e8fdf33e79acec2a08cc8870fdc18ceca6b5b032","segment_id":"start/wizard.md:16f0ee47f993d627","source_path":"start/wizard.md","text_hash":"16f0ee47f993d6270c9059450473eea493ca8ae037f8877782ae2bc176f24d18","text":"API key","translated":"API 密钥","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:43Z"} -{"cache_key":"b6acf6603c3288ff678824fbc05208f2ffb9265ef1bd538af6b719f3bd0a3117","segment_id":"index.md:2f1626425f985d9a","source_path":"index.md","text_hash":"2f1626425f985d9ad8c124ea8ccb606e404ae5f43c58bd16b6c109d6d2694083","text":"Most operations flow through the ","translated":"大多数操作通过 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:45Z"} -{"cache_key":"b728d99548c47aac6f8b5df5cba915a124aa44c07b51c9bc7a298f73f98caf13","segment_id":"start/wizard.md:1e9806e4227ba3b9","source_path":"start/wizard.md","text_hash":"1e9806e4227ba3b9a986732f1b09a21fd6b96043d12e5a4334a326ec5ad39842","text":"Signal","translated":"Signal","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:44:46Z"} -{"cache_key":"b74d2e77f6dff2d670948e7bc471317b3d93cdcbd69be8b2a1c8b1c1e29fa6e7","segment_id":"index.md:1cce617e15b49dca","source_path":"index.md","text_hash":"1cce617e15b49dca89b212bb5290edfcfee010ef2eeef369b36af78c53756e1c","text":" — Optional transcription hook","translated":" —— 可选的转录钩子","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:58Z"} -{"cache_key":"b798dd1056c4bde2b213da50c0deaf67f6fa43b67ba57c7e8608a4ba80573de8","segment_id":"index.md:c011d6097bfbc8e9","source_path":"index.md","text_hash":"c011d6097bfbc8e936280addcf2e3e7d06ea2223ffd596973191b800a7035c32","text":"License","translated":"许可证","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:04Z"} -{"cache_key":"b7b8bda0e930aa53d189e38c5844ac805547a37ca102751746c8e425c06a684c","segment_id":"index.md:0d3a30eb74e2166c","source_path":"index.md","text_hash":"0d3a30eb74e2166c1fc51b99b180841f808f384be53fe1392cecb67fdc9363c4","text":" (default ","translated":" (默认 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:09Z"} -{"cache_key":"b7c642921d34922bbb25206e04a52428c8707414d90f0aa9bbc07366d3165e09","segment_id":"start/getting-started.md:73526fff31f4fa0a","source_path":"start/getting-started.md","text_hash":"73526fff31f4fa0a98e4e135e0610652867bd8842a6abeb821e02ee87842bb96","text":"Telegram DM tip:","translated":"Telegram 私信提示:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:33Z"} -{"cache_key":"b7ef55ac0b21abd132744ee6daa0d8aebba830cf42b99105a8aa15035f636f7c","segment_id":"help/index.md:8cd501e1124c3047","source_path":"help/index.md","text_hash":"8cd501e1124c30473473c06e536a2d145e2a14a6d7dc1b99028ce818e14442e2","text":"Repairs:","translated":"修复:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:44:56Z"} -{"cache_key":"b842ea6173ee701821bd377af17913bb92cafb54dc487075c302ab3d329c88cc","segment_id":"index.md:723784fa2b6a0876","source_path":"index.md","text_hash":"723784fa2b6a0876540a92223ee1019f24603499d335d6d82afbc520ef5b5d57","text":") — Creator, lobster whisperer","translated":")— 创作者,龙虾低语者","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:34Z"} -{"cache_key":"b879fc6c7bf9bcf2521829ee80839cc6b64fa033303e0d3ad8f4c14519022dd7","segment_id":"index.md:b332c3492d5eb10a","source_path":"index.md","text_hash":"b332c3492d5eb10a118eb6d8b0dcd689bc2477ce2ae16b303753b942b54377bc","text":"Configuration","translated":"配置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:03:58Z"} -{"cache_key":"b8d882b2664af754e0a9242db46afe45a00690cb9294ebf818b517be4eb004fd","segment_id":"index.md:a10f6ed8c1ddbc10","source_path":"index.md","text_hash":"a10f6ed8c1ddbc10d3528db7f7b6921c1dd5a5e78aa191ff017bf29ce2d26449","text":"⏱️ ","translated":"⏱️ ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:31Z"} -{"cache_key":"b8d9c5b6ac9e5a115d60a75c55a842231d71850c2d69bfb8c20b79e3e7744b35","segment_id":"environment.md:d4a67341570f4656","source_path":"environment.md","text_hash":"d4a67341570f4656784c5f8fe1bfb48a738ace57b52544977431d50e2b718099","text":"FAQ: env vars and .env loading","translated":"常见问题:环境变量和 .env 加载","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:47:18Z"} -{"cache_key":"b8efaaee77774922e208bb819be2e16edb0632860d03d901df8701e7582bec11","segment_id":"index.md:8816c52bc5877a2b","source_path":"index.md","text_hash":"8816c52bc5877a2b24e3a2f4ae7313d29cf4eba0ca568a36f2d00616cfe721d0","text":"Wizard","translated":"向导","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:47:48Z"} -{"cache_key":"b90215fad5e3df7edc635820365a97567dc5fed769e90812e8444decb4691cc5","segment_id":"start/getting-started.md:45e6d69dbe995a36","source_path":"start/getting-started.md","text_hash":"45e6d69dbe995a36f7bc20755eff4eb4d2afaaedbcac4668ab62540c57219f32","text":"macOS app","translated":"macOS 应用","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:23Z"} -{"cache_key":"b9140801ceed17bc6beff66df05f3fb6f825ffb03c25525672a9ed9d37cc8bef","segment_id":"index.md:be48ae89c73a75da","source_path":"index.md","text_hash":"be48ae89c73a75da3454d565526d777938c20664618905a9bc77d6a0a21a689d","text":"\"EXFOLIATE! EXFOLIATE!\"","translated":"\"EXFOLIATE! EXFOLIATE!\"","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:27:51Z"} -{"cache_key":"b91b95d70281a4d1d45bd8c853fa8bfa893d10fa36509361b58b83df1111b31b","segment_id":"help/index.md:cad44fbae951d379","source_path":"help/index.md","text_hash":"cad44fbae951d3791565b0cee788c01c3bd10e0176167acb691b8dba0f7895f8","text":"Gateway logging","translated":"Gateway 日志记录","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:44:54Z"} -{"cache_key":"b9b11fe51f278fc05b76b9e48d84a6b796c35bd940491457befd53ac08255496","segment_id":"help/index.md:b79cac926e0b2e34","source_path":"help/index.md","text_hash":"b79cac926e0b2e347e72cc91d5174037c9e17ae7733fd7bdb570f71b10cd7bfc","text":"Help","translated":"帮助","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:39:31Z"} -{"cache_key":"b9c7cee99b82c57ac554d288a0b5aee19b5ca5fc10cdd6f59b31a4fc7450c3a9","segment_id":"index.md:22159a426e4f2635","source_path":"index.md","text_hash":"22159a426e4f26356382cc3ac9b2e7af5123c1309250332f5dcbbc6e6f952b0e","text":"Network model","translated":"网络模型","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:38Z"} -{"cache_key":"b9cc5f90d0c6e7deedd6ec40f46f56ce1c36844b849a3acbd488724173d8b7f4","segment_id":"start/wizard.md:254a5988b52ecb17","source_path":"start/wizard.md","text_hash":"254a5988b52ecb1730f5ab74e7998f0789c62c194e32d6a29c9500129905438d","text":"More detail: ","translated":"更多详情: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:50Z"} -{"cache_key":"ba73a727d35cc4ad3a5a48130b91107a13324a115d536a8b936ca4b56d0b8ebf","segment_id":"start/wizard.md:b248f2e01881f536","source_path":"start/wizard.md","text_hash":"b248f2e01881f536176ab4f5c76d6c067348339e0ddd2be6d2b0b0435c09f614","text":"MiniMax","translated":"MiniMax","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:00Z"} -{"cache_key":"ba7cd0c5865f73af1ced8609de573bce503046cc0135f10edf71d69ac7bed742","segment_id":"index.md:45808d75bf8911fa","source_path":"index.md","text_hash":"45808d75bf8911fa21637f9dd3f0dace1877748211976b5d61fcc5c15db594d0","text":"Webhooks","translated":"Webhooks","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:53:51Z"} -{"cache_key":"ba881a89787827ca73c2b6efade0f1b148a3093729931f54bcedd6516714ef9a","segment_id":"environment.md:3fe738a7ee6aaff5","source_path":"environment.md","text_hash":"3fe738a7ee6aaff51f099d9a8314510c99ced6a568eb38c67642cd43bb54eec0","text":" in the current working directory","translated":" 在当前工作目录中","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:25Z"} -{"cache_key":"bab136853746e7adb4f3d6a9085f276c4b3b60b32935bf0abee97c4b8b0847d2","segment_id":"index.md:frontmatter:read_when:0","source_path":"index.md:frontmatter:read_when:0","text_hash":"08965a8ab25e66157009d1617fc167bcc2404fa0c0ca50b1e5e5750957be3b10","text":"Introducing OpenClaw to newcomers","translated":"向新用户介绍 OpenClaw","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:47:20Z"} -{"cache_key":"bab5f315b0b714729442371eeede15ca920f42aa5f8a6a5bbf4f2831cec6bab7","segment_id":"start/getting-started.md:1e3abf61a37e3cad","source_path":"start/getting-started.md","text_hash":"1e3abf61a37e3cad36b11b459b1cc39e76feb6a0c369fe5270957468288dcc5c","text":"If ","translated":"如果 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:00Z"} -{"cache_key":"bb01273ae2008ef3e65dac6325f0912e3297b1445007151a0eb13c637d664344","segment_id":"environment.md:907940a35852447a","source_path":"environment.md","text_hash":"907940a35852447aad5f21c5a180d993ff31cfd5807b1352ed0c24eabe183465","text":"never override existing values","translated":"永远不覆盖已有的值","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:19Z"} -{"cache_key":"bb01eace88e3c0c55a9f90dcd2ef4db17d3ef428c9c3f0cbbc533816b3673889","segment_id":"start/getting-started.md:5ca32046e4b3e547","source_path":"start/getting-started.md","text_hash":"5ca32046e4b3e5476abcfc30f1d5abfcc42cf2cb6ad8b42b35ed51f62cddaead","text":"). It sets up:","translated":")。它会设置:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:51Z"} -{"cache_key":"bb8fe17d51b04ff11d3cdd2b428662d48746db111cb4bc5cb91f4c30ab33c86e","segment_id":"start/wizard.md:c10c181a3b7e8440","source_path":"start/wizard.md","text_hash":"c10c181a3b7e84404d307e21cf48264c7ff7e0d4a04ee15af969b08ebe47d7a3","text":" (and ","translated":" (以及 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:52Z"} -{"cache_key":"bbae60d9c55f0a4c17edd70724bf025a80c357507af18bc456b69d8e22351dd3","segment_id":"environment.md:d08a8493f686363a","source_path":"environment.md","text_hash":"d08a8493f686363a78b913d45ebfbd87a3768d1c77b70f23b1fdade3c066e481","text":"Shell env import","translated":"Shell 环境导入","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:26:10Z"} -{"cache_key":"bbd317ed227cca52a63156dec7f92240d0a532979467fb3bb2f12481519aa3a6","segment_id":"index.md:5583785669449fc8","source_path":"index.md","text_hash":"5583785669449fc81a8037458c908c11a8f345c21c28f7f3a95de742bd52199a","text":"Media Support","translated":"媒体支持","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:36Z"} -{"cache_key":"bbe1dd74f66fb83dcdd47e77fb4ce919331298e2a8b6bb3fc8b3d0ee940a031a","segment_id":"index.md:f0a7f9d068cb7a14","source_path":"index.md","text_hash":"f0a7f9d068cb7a146d0bb89b3703688d690ed0b92734b78bcdb909aace617dbf","text":"WhatsApp group messages","translated":"WhatsApp 群消息","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:53:23Z"} -{"cache_key":"bc2419d59f866ec8c3f5529c5f2e87039a9e0ec7403f6fa82664b7ef9af23d47","segment_id":"start/getting-started.md:b1c8a72bb57dc747","source_path":"start/getting-started.md","text_hash":"b1c8a72bb57dc747671a456250fab49db53d0fef744eae4b959a66a4abb7aba9","text":"exe.dev","translated":"exe.dev","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:39Z"} -{"cache_key":"bc2967e4d37bce4abb8008d556e2894e97049fdfe54c4a2d6b6bdf8639a1cfd3","segment_id":"environment.md:c2d7247c8acb83a5","source_path":"environment.md","text_hash":"c2d7247c8acb83a5a020458fa836c2445922b51513dbdbf154ab5f7656cb04e9","text":"; does not override).","translated":";不会覆盖)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:22Z"} -{"cache_key":"bc6f614c30433e6b3bff168a2080525f05fc94e339dc42f43f2e189e3a0b226e","segment_id":"index.md:329f3c913c0a1636","source_path":"index.md","text_hash":"329f3c913c0a16363949eb8ee7eb0cda7e81137a3851108019f33e5d18b57d8f","text":"Switching between npm and git installs later is easy: install the other flavor and run ","translated":"之后在 npm 和 git 安装之间切换很简单:安装另一种方式并运行 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:03:00Z"} -{"cache_key":"bcaa9af5387d4c16acfcf673ef371654f20d3f5740f64c92747435d166d53bee","segment_id":"start/wizard.md:d65be5fbfc8f6bc9","source_path":"start/wizard.md","text_hash":"d65be5fbfc8f6bc9316db63dff758f2a5758d3fa4ddde8562b89a9baa35c0b9d","text":"Starts the Gateway (if needed) and runs ","translated":"启动 Gateway(如需)并运行 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:45:38Z"} -{"cache_key":"bcc6f5f4ada16ba9c99157f111747d22c499aab86af420e947d68797df7d0dc2","segment_id":"environment.md:a258b30f88c30650","source_path":"environment.md","text_hash":"a258b30f88c30650e73073d5bdde5cfcc6987100ae62d37789e5c46a0d85b7c6","text":"Global ","translated":"全局 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:09Z"} -{"cache_key":"bd0afd9947ca223c780705636e9fd81efec6d821d54ead3dd5755b82ca6cabbb","segment_id":"index.md:86e2bbbc305c31aa","source_path":"index.md","text_hash":"86e2bbbc305c31aa988751196a1e207da68801a48798c48b90485c11578443a0","text":"Providers and UX:","translated":"提供商 和用户体验:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:53:04Z"} -{"cache_key":"bd1a787c9d8cd0ad83cfd8fd6de5a4da5fdb050d4b594904e623a1d17c5b8c21","segment_id":"index.md:c7a5e268ddd8545e","source_path":"index.md","text_hash":"c7a5e268ddd8545e5a59a58ef1365189862f802cc7b61d4a3212c70565e2dff1","text":"WhatsApp Integration","translated":"WhatsApp 集成","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:30Z"} -{"cache_key":"bde9f3ebeb2359b3b7aedd826d0a1d12e084a4a61310d0f5bd394d8eb5a120ba","segment_id":"index.md:39bbb719fa2b9d22","source_path":"index.md","text_hash":"39bbb719fa2b9d2251039cbf2cd072e1120a414278263e2f11d99af0236c4262","text":"Groups","translated":"群组","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:04:53Z"} -{"cache_key":"bdecbc1be817872a0692411e78c70677191fe2da6e081c369fb09de0ef2601cf","segment_id":"start/getting-started.md:618240b69ec6c809","source_path":"start/getting-started.md","text_hash":"618240b69ec6c8090801f0a1c0298939ec16e6c30607b1117173bd5e4770f27e","text":"first working chat","translated":"第一次成功聊天","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:29Z"} -{"cache_key":"bdf975c1288d74f830e912ea439f34bd12327414e67a0e3b0031b20daee8fa90","segment_id":"environment.md:a5839747a1cd90df","source_path":"environment.md","text_hash":"a5839747a1cd90df1cb7dbb6df6d1dddba552865d54e3e2fa0c6b87e6616c666","text":"; does not","translated":";不会","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:54Z"} -{"cache_key":"bdfbc7a0fd631f051f7b46e21b996d7aa66ab700fe12e4153d61fb8cccd72b43","segment_id":"environment.md:32ebb1abcc1c601c","source_path":"environment.md","text_hash":"32ebb1abcc1c601ceb9c4e3c4faba0caa5b85bb98c4f1e6612c40faa528a91c9","text":" (","translated":" (","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:15Z"} -{"cache_key":"be43620abdc44274f5a6124fe94af02680937d7b3c843471640e6d3cfdbcb11b","segment_id":"index.md:81a1c0449ea684aa","source_path":"index.md","text_hash":"81a1c0449ea684aadad54a7f8575061ddc5bfa713b6ca3eb8a0228843d2a3ea1","text":"Nodes (iOS/Android)","translated":"节点(iOS/Android)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:04:30Z"} -{"cache_key":"be853f7b692e34fd9acbac3fc2a4beaeffb4fccfc645083457d04704ce7e80a6","segment_id":"start/getting-started.md:32ebb1abcc1c601c","source_path":"start/getting-started.md","text_hash":"32ebb1abcc1c601ceb9c4e3c4faba0caa5b85bb98c4f1e6612c40faa528a91c9","text":" (","translated":" (","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:49Z"} -{"cache_key":"be9ef45489c42d85ef02ddbdc619e8f571efb5ad273236b11af6b087a73aac32","segment_id":"start/wizard.md:d03502c43d74a30b","source_path":"start/wizard.md","text_hash":"d03502c43d74a30b936740a9517dc4ea2b2ad7168caa0a774cefe793ce0b33e7","text":", ","translated":", ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:47:09Z"} -{"cache_key":"bed2a7f7ebfcaa0b5e9c08db15a562558ebb609b6ad450b19a160511fd76f36d","segment_id":"start/getting-started.md:569ca49f4aaf7846","source_path":"start/getting-started.md","text_hash":"569ca49f4aaf7846e952c1d4aeca72febd0b79fa1c4f9db08fd3127551218572","text":"Install","translated":"安装","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:50Z"} -{"cache_key":"bed8e880f819b1664d27c979ee19546883dc77b25b3f4c2bca3bb320cdb7a997","segment_id":"index.md:9bd86b0bbc71de88","source_path":"index.md","text_hash":"9bd86b0bbc71de88337aa8ca00f0365c1333c43613b77aaa46394c431cb9afd8","text":"Maxim Vovshin","translated":"Maxim Vovshin","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:41Z"} -{"cache_key":"bedbf38b79db3a7e2c68181e1c39bb9dbb0ec7872bd05c86a18d5a2cea9ff52d","segment_id":"environment.md:3fe738a7ee6aaff5","source_path":"environment.md","text_hash":"3fe738a7ee6aaff51f099d9a8314510c99ced6a568eb38c67642cd43bb54eec0","text":" in the current working directory","translated":" 在当前工作目录中","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:35Z"} -{"cache_key":"bf1804a981e692a3e488d95ec6501ae0a175844faed4b62050b2c407110d73e9","segment_id":"environment.md:e234227b0e001687","source_path":"environment.md","text_hash":"e234227b0e001687821541fac3af38fc6be293ec6e13910c6826b9afc8ca33be","text":" syntax:","translated":" 语法:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:41:28Z"} -{"cache_key":"bf2db6ac9b982594da3a3e3dd13d6ca4e223ff16e13a95d31ffb072ab1d32c8e","segment_id":"start/getting-started.md:883c79fabfe68ee2","source_path":"start/getting-started.md","text_hash":"883c79fabfe68ee271a7635815ea9c87295a436a075926633e8865ec60c4303e","text":" (optional; recommended if you build from source)","translated":" (可选;如果从源码构建则推荐安装)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:26Z"} -{"cache_key":"bf37699805bcf078c1b1ce444bf6d1198e99667a6db48d7eb7e641c41262087b","segment_id":"start/getting-started.md:76dfd9f9a399a76a","source_path":"start/getting-started.md","text_hash":"76dfd9f9a399a76a13b092e0ce512519b8fc0cfef720142556a8350f70a040ab","text":"Pairing","translated":"配对","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:12Z"} -{"cache_key":"bf6afd51b6d116b7f7aac3bb45cc7db66e823c2fc1abd26e91d2f29989e56a53","segment_id":"index.md:da22b9d6584e1d8a","source_path":"index.md","text_hash":"da22b9d6584e1d8aa709165be214e0f9bdf2be428816e9ce1c4506bf86218cb4","text":"Core Contributors","translated":"核心贡献者","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:38Z"} -{"cache_key":"bf6c745f2cf524d912a0e53b92bb7278771b97f3974e15bf7d7d5c21d2cb2bb7","segment_id":"start/wizard.md:fd42bd9065e9791f","source_path":"start/wizard.md","text_hash":"fd42bd9065e9791f5e6a611205a54d922d1b8046f78d72cb2b35a156a2ee379a","text":"WhatsApp credentials go under ","translated":"WhatsApp 凭据存储在 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:48:51Z"} -{"cache_key":"bf825adb6efc12b0b76cb65939a149b13d9affa681ea8c41f0ff54043e15afc1","segment_id":"environment.md:7175517a370b5cd2","source_path":"environment.md","text_hash":"7175517a370b5cd2e664e3fd29c4ea9db5ce17058eb9772fe090a5485e49dad6","text":" or ","translated":" 或 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:35Z"} -{"cache_key":"c01e11953c6ba2efa9bec09338b3e7fcbdc647a92bf09fd08678e0c6e1ee9598","segment_id":"index.md:ec05222b3777fd7f","source_path":"index.md","text_hash":"ec05222b3777fd7f91a2964132f05e3cfc75777eaeec6f06a9a5c9c34a8fc3e9","text":"Nix mode","translated":"Nix 模式","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:10Z"} -{"cache_key":"c0282f2e4f7da80d51262220226e41d0c83df835b9e776ed420a3fe11663d5b2","segment_id":"start/wizard.md:6301b8b1517facda","source_path":"start/wizard.md","text_hash":"6301b8b1517facda1ab48a0af2e5ed47f68867711466089050b20180cfc22433","text":"Synthetic example:","translated":"Synthetic 示例:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:47:31Z"} -{"cache_key":"c09d5cb253479a62ae433edd398f06b46aff64efd80ab44a984de33922120de6","segment_id":"start/getting-started.md:160d9109519d8d17","source_path":"start/getting-started.md","text_hash":"160d9109519d8d17b25b1d2f8202aaab71eafe0a21aa1384978dc89d2679d370","text":"From source (development)","translated":"从源码安装(开发)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:43Z"} -{"cache_key":"c100ce5c5170c043a021982a580ebd78cad6232e67057fb8d0d55dfa3fe1e8d3","segment_id":"environment.md:ffa63583dfa6706b","source_path":"environment.md","text_hash":"ffa63583dfa6706b87d284b86b0d693a161e4840aad2c5cf6b5d27c3b9621f7d","text":"missing","translated":"缺失的","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:22:23Z"} -{"cache_key":"c11f020ea3afe93aee794662658476af49988cea0ddc160f7f8c27b1b245076a","segment_id":"environment.md:9c85ab59cb358b12","source_path":"environment.md","text_hash":"9c85ab59cb358b1299c623e16f52f3aee204a81fb6d1c956e37607a220d13b08","text":"You can reference env vars directly in config string values using `${VAR_NAME}` syntax:","translated":"你可以在配置字符串值中使用 `${VAR_NAME}` 语法直接引用环境变量:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:19:44Z"} -{"cache_key":"c1300944d87f5d93e003235afb1a2a255806cb0ca7ca73081c0bda9081c00781","segment_id":"index.md:4d4d75c23a2982e1","source_path":"index.md","text_hash":"4d4d75c23a2982e184011f79e62190533f93cdad41ba760046419678fa68d430","text":"Runtime requirement: ","translated":"运行时要求: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:25Z"} -{"cache_key":"c1ed30ab3d008a94d1201ceb1b0681fb09d05d747adddc2cd9bd9ec64544cddf","segment_id":"start/wizard.md:cb773b9bc6fc5373","source_path":"start/wizard.md","text_hash":"cb773b9bc6fc5373e0b338fbcb709df301cd8e11f0699de40cb0c1c4bf3def77","text":"Existing config detection","translated":"现有配置检测","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:58Z"} -{"cache_key":"c2188cce98f83b4b4240fddcdd99a6504e9b9e044a40f429257a85d2f2485f22","segment_id":"help/index.md:71095a6d42f5d9c2","source_path":"help/index.md","text_hash":"71095a6d42f5d9c2464a8e3f231fc53636d4ce0f9356b645d245874162ec07e2","text":"Gateway troubleshooting","translated":"Gateway 故障排除","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:23Z"} -{"cache_key":"c226a7b155f9acc3489810036a9112a8b4d498f14a983ecad4c72d8b48925751","segment_id":"index.md:63a3abfa879299dd","source_path":"index.md","text_hash":"63a3abfa879299ddcc03558012bfd6075cbd72f7a175b739095bf979700297f7","text":"Multi-instance quickstart (optional):","translated":"多实例快速开始(可选):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:03:15Z"} -{"cache_key":"c2802148a29fff6480dd7c4126df1d7787f83156807ce1f6e0abb05d2e0a7863","segment_id":"index.md:6e0f6eca4ff17d33","source_path":"index.md","text_hash":"6e0f6eca4ff17d3377c1c3e8e1f73457553ad3b9cfcd5e4f2b94cfb1028b6234","text":"iOS app","translated":"iOS 应用","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:53:36Z"} -{"cache_key":"c2acf62bea34b4557cbab8b7ceadd55c5cf37516c124b93afc1b8e9f08d62ab0","segment_id":"index.md:39bbb719fa2b9d22","source_path":"index.md","text_hash":"39bbb719fa2b9d2251039cbf2cd072e1120a414278263e2f11d99af0236c4262","text":"Groups","translated":"群组","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:53:21Z"} -{"cache_key":"c2e74d237df6614199282b8822741be509ff03e31b7319f3184bb2537860e8a9","segment_id":"index.md:bf084dc7b82e1e62","source_path":"index.md","text_hash":"bf084dc7b82e1e62c63727b13451d1eba2269860e27db290d2d5908d7ade0529","text":" — Pairs as a node and exposes Canvas + Chat + Camera","translated":" — 作为节点配对并提供 Canvas + 聊天 + 相机","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:02:43Z"} -{"cache_key":"c335a0e455574c0e23a45c10a55511400b6168c38aa7d8e43521b1c8650e58f9","segment_id":"environment.md:frontmatter:read_when:1","source_path":"environment.md:frontmatter:read_when:1","text_hash":"a3a2d99a99de98220c8e0296d6f4e4b2a34024916bd2379d1b3b9179c8fae46f","text":"You are debugging missing API keys in the Gateway","translated":"您正在调试 Gateway 中缺失的 API 密钥","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:15Z"} -{"cache_key":"c34f893f16dcd3b37a3752585df805b44212829550f3d82cb5f539fdb50a5a50","segment_id":"environment.md:87e89abb4c1c551f","source_path":"environment.md","text_hash":"87e89abb4c1c551fe08d355d097f18b8de78edca5f556997085681662fce8eed","text":"Config ","translated":"配置 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:46Z"} -{"cache_key":"c359a69d5e0e9e6470f36436f1b27a946ef28ef1069e7b7d59e0ea3132f6003c","segment_id":"start/wizard.md:4cd440e57b28aba7","source_path":"start/wizard.md","text_hash":"4cd440e57b28aba7f789ba11d0bb5837f09937ba45bab9a80b9a6a980894250e","text":"Follow‑up reconfiguration:","translated":"后续重新配置:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:15Z"} -{"cache_key":"c360b15d624bad75d881fff636c494f57b21345481b98d674df5baa6a31c7b06","segment_id":"index.md:cdb4ee2aea69cc6a","source_path":"index.md","text_hash":"cdb4ee2aea69cc6a83331bbe96dc2caa9a299d21329efb0336fc02a82e1839a8","text":".","translated":"。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:02Z"} -{"cache_key":"c363b2aa05942d39fd0ddcddc9b63daca312937a794a7bc8027a049c9befb2bb","segment_id":"environment.md:61115f6649792387","source_path":"environment.md","text_hash":"61115f664979238731a390e84433a818965b7eaf1d38fa5b4b1507c33ef28c91","text":"Precedence (highest → lowest)","translated":"优先级(从高到低)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:11:40Z"} -{"cache_key":"c3c32ca9a6e0b7331bd674903379664ef8c5ab9f675dbb531062af512452343e","segment_id":"index.md:acdd1e734125f341","source_path":"index.md","text_hash":"acdd1e734125f341604c0efbabdcc4c4b0597e8f6235d66c2445edd1812838c1","text":"Telegram","translated":"Telegram","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:04:46Z"} -{"cache_key":"c3f6ef9654ecec9e668759d52d4b3b337eb11cfc8c41c6c29afbd4c7a6b1a3aa","segment_id":"index.md:f0b349e90cb60b2f","source_path":"index.md","text_hash":"f0b349e90cb60b2f96222d0be1ff6532185f385f4909a19dd269ea3e9e77a04d","text":" (default); groups are isolated","translated":" (默认);群组是隔离的","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:35Z"} -{"cache_key":"c459652c41ab2b7b00625ccdcbb406c410e20c6427b9c7db02f6fdd47ba6f749","segment_id":"help/index.md:156597e2632411d1","source_path":"help/index.md","text_hash":"156597e2632411d1d5f634db15004072607ba45072a4e17dfa51790a37b6781f","text":"Gateway issues:","translated":"Gateway 问题:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:21Z"} -{"cache_key":"c483b6ba1c94a31f76c8e7312a407d38c30bce0f4712658564a6f18c1216a82d","segment_id":"environment.md:frontmatter:read_when:1","source_path":"environment.md:frontmatter:read_when:1","text_hash":"a3a2d99a99de98220c8e0296d6f4e4b2a34024916bd2379d1b3b9179c8fae46f","text":"You are debugging missing API keys in the Gateway","translated":"您正在调试 Gateway 中缺失的 API 密钥","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:04Z"} -{"cache_key":"c492c9a161bdd51ea2c2cdd14a9b9bb5db1cd52cf0c29fb37109d054b7ee9a0d","segment_id":"help/index.md:frontmatter:summary","source_path":"help/index.md:frontmatter:summary","text_hash":"aece82a2d540ab1a9a21c7b038127cae6e9db2149491564bb1856b6f8999f205","text":"Help hub: common fixes, install sanity, and where to look when something breaks","translated":"帮助中心:常见修复方法、安装健全性检查,以及出问题时该去哪里排查","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:21:29Z"} -{"cache_key":"c4cdc8fbd5869ac2ecac6d2aedef557b386f308d0e2819293e3c743d3cc6ae86","segment_id":"help/index.md:3c33340bd23b8db8","source_path":"help/index.md","text_hash":"3c33340bd23b8db89f18fe7d05a954738c0dd5ba9623cf6bdb7bb5d1a3729cfc","text":"FAQ (concepts)","translated":"常见问题(概念)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:56:50Z"} -{"cache_key":"c504cdf411edd24aafa9f9af4a1d9555dd4813e7717812dd30f12f6ce0f36335","segment_id":"start/wizard.md:14290e1d06812977","source_path":"start/wizard.md","text_hash":"14290e1d0681297772dedd7ea7e78b2d2492a46382251c6f8f49a2977978ece1","text":"Health check","translated":"健康检查","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:30Z"} -{"cache_key":"c50cf8a23b65ef73b5bfb717f8d28d8e2e13435175b38a9b94a6a92fd79c241a","segment_id":"start/wizard.md:2addbbaf06856d61","source_path":"start/wizard.md","text_hash":"2addbbaf06856d61875d46a98c898d3985a48f1028e2e5f1f8b68022902f5879","text":"Kimi Coding","translated":"Kimi Coding","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:10Z"} -{"cache_key":"c5341e93cca2bf9b412fba71811b5c75affd70642d5cac522c20f656fce8c171","segment_id":"start/getting-started.md:85ed1b061af844c7","source_path":"start/getting-started.md","text_hash":"85ed1b061af844c761d40a5328177c10aea1be3a6eb49e3ef2aad5e9724c5edc","text":"Always-on / VPN setups: ","translated":"常驻运行 / VPN 设置: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:38Z"} -{"cache_key":"c547a034bcb14649348b839344981ab2abe4d278dd058e299ee088aca6d1cbb2","segment_id":"index.md:19525ac5e5b9c476","source_path":"index.md","text_hash":"19525ac5e5b9c476b36a38c5697063e37e8fe2fae8ef6611f620def69430cf74","text":"Canvas host","translated":"Canvas 主机","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:55Z"} -{"cache_key":"c577961fb1dd2981c632731703b6fa32ce458c2a1d22f624053d893601313a69","segment_id":"index.md:9fc31bacba5cb332","source_path":"index.md","text_hash":"9fc31bacba5cb33207804b9e6a8775a3f9521c9a653133fd06e5d14206103e48","text":"Streaming + chunking","translated":"流式传输与分块","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:02Z"} -{"cache_key":"c59753265e4fde2eba581fac96edc31fac666f999016b10be79673bb9f8fff01","segment_id":"index.md:f3047ab42a6a5bbf","source_path":"index.md","text_hash":"f3047ab42a6a5bbf164106356fa823ecada895064120c4e5a30e1f632741cc5f","text":"Web surfaces","translated":"Web 界面","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:25Z"} -{"cache_key":"c5a0c89316164529f7023f5315efd593449709ea51025067e3e3ac600c2b8955","segment_id":"index.md:f1e3b32c8eb0df8e","source_path":"index.md","text_hash":"f1e3b32c8eb0df8ea105f043edf614005742c15581e2cebc5a9c3bafb0b90303","text":"Multi-agent routing","translated":"多智能体路由","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:10Z"} -{"cache_key":"c5aa6ee094793c8175cf46e51a84ccfa7bfb96483511447ee39bffc5c5d621a6","segment_id":"index.md:f9b8279bc46e847b","source_path":"index.md","text_hash":"f9b8279bc46e847bfcc47b8701fd5c5dc27baa304d5add8278a7f97925c3ec13","text":"Mattermost (plugin)","translated":"Mattermost(插件)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:04:51Z"} -{"cache_key":"c600fc61e6150bfb212aae76377cc9c818199be5b646524cacdc83e1c8548e4c","segment_id":"help/index.md:2adc964c084749b1","source_path":"help/index.md","text_hash":"2adc964c084749b1f2d8aef24030988b667dbda2e38a6a1699556c93e07c1cea","text":"Start here","translated":"从这里开始","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:56:22Z"} -{"cache_key":"c63aa51793c779b2a349df7ffac1628bb2cc332f86766a178ca09f0d1ab6b9ef","segment_id":"environment.md:d08a8493f686363a","source_path":"environment.md","text_hash":"d08a8493f686363a78b913d45ebfbd87a3768d1c77b70f23b1fdade3c066e481","text":"Shell env import","translated":"Shell 环境导入","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:45Z"} -{"cache_key":"c6579c041588ea1bb181e9a8deb7415e62a84d1bd20b12e4570bfbd9c2ade3d8","segment_id":"index.md:233cfad76c3aa9dd","source_path":"index.md","text_hash":"233cfad76c3aa9dd5cc0566746af197eac457a88c1e300ae788a8ada7f96b383","text":"From source (development):","translated":"从源码安装(开发):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:17Z"} -{"cache_key":"c68def9780e982378b5c6b30c5c52340f6495cfc16ebe6378fa8655b7df12662","segment_id":"start/wizard.md:663ea1bfffe5038f","source_path":"start/wizard.md","text_hash":"663ea1bfffe5038f3f0cf667f14c4257eff52d77ce7f2a218f72e9286616ea39","text":" to ","translated":" 为 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:22Z"} -{"cache_key":"c6ca6417d36b17f38103f8c80bf1974f694de7f8e5cf6c75e2df8722898afc33","segment_id":"environment.md:frontmatter:read_when:0","source_path":"environment.md:frontmatter:read_when:0","text_hash":"90fc0487bff88009979cff1061c1a882df8c3b1baa9c43538331d9d5dab15479","text":"You need to know which env vars are loaded, and in what order","translated":"您需要了解加载了哪些 环境变量,以及加载顺序","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:12Z"} -{"cache_key":"c6f804812e9ae46bd893fabd31bc85463705d5a761157ef2dccfdc6f8a278d20","segment_id":"index.md:da22b9d6584e1d8a","source_path":"index.md","text_hash":"da22b9d6584e1d8aa709165be214e0f9bdf2be428816e9ce1c4506bf86218cb4","text":"Core Contributors","translated":"核心贡献者","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:06:12Z"} -{"cache_key":"c6fafa0a56fb2daa3b5eb1ab12bcde96e81c8b5eb8c495ac27c999aa7ece81f0","segment_id":"index.md:66354a1d3225edbf","source_path":"index.md","text_hash":"66354a1d3225edbf01146504d06aaea1242dcf50424054c3001fc6fa2ddece0f","text":"Remote access","translated":"远程访问","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:41Z"} -{"cache_key":"c749935b054cdee1215d5c7bc80ccadc89b5251b7b720e58f1fc750832c291cc","segment_id":"start/getting-started.md:f940dae2228542bc","source_path":"start/getting-started.md","text_hash":"f940dae2228542bc51f88220681f263413d5d91c47a84b411600abc82294299a","text":"),\nso group/channel sessions are sandboxed. If you want the main agent to always\nrun on host, set an explicit per-agent override:","translated":"),因此群组/渠道会话是沙箱化的。如果您希望主智能体始终在主机上运行,请设置显式的逐智能体覆盖:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:21Z"} -{"cache_key":"c7938f197a6a0913e762962c7a145a194fb20261b6366796749cfff9bec325f1","segment_id":"help/index.md:cad44fbae951d379","source_path":"help/index.md","text_hash":"cad44fbae951d3791565b0cee788c01c3bd10e0176167acb691b8dba0f7895f8","text":"Gateway logging","translated":"Gateway 日志记录","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:31Z"} -{"cache_key":"c7d8295ce2f5f373b188cd04e782c94c0d1c45ee5dfcf10d220f7a24629104a4","segment_id":"start/getting-started.md:8f6fb4eb7f42c0e2","source_path":"start/getting-started.md","text_hash":"8f6fb4eb7f42c0e245e29e63f5b82cc3ba19852681d1ed9aed291f59cf75ec0e","text":"Security","translated":"安全","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:14Z"} -{"cache_key":"c7f525205b3a6feadb47fbfcbcbfc68f82fe9ae13af1a5c16ac3d52b9c9bf288","segment_id":"index.md:2a6b24ad28722034","source_path":"index.md","text_hash":"2a6b24ad287220345e96eb8021fe29d42b0785766c8df658827e7251da2d36dc","text":"Credits","translated":"致谢","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:15Z"} -{"cache_key":"c804bb5b5895281827002da2fcf801becaeb7680046827908a93ec9b050d971b","segment_id":"index.md:03279877bfe1de07","source_path":"index.md","text_hash":"03279877bfe1de0766393b51e69853dec7e95c287ef887d65d91c8bbe84ff9ff","text":"WebChat + macOS app","translated":"WebChat + macOS 应用","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:02Z"} -{"cache_key":"c8226a707aea96b4c38666b0e128055b91ef72929100106d9e62985f5d0727bc","segment_id":"environment.md:a258b30f88c30650","source_path":"environment.md","text_hash":"a258b30f88c30650e73073d5bdde5cfcc6987100ae62d37789e5c46a0d85b7c6","text":"Global ","translated":"全局 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:39Z"} -{"cache_key":"c839449ed2f2e2c13f4b4732789e52a7884ced2ccc0f4f285709a62f52005527","segment_id":"index.md:6fa3cbf451b2a1d5","source_path":"index.md","text_hash":"6fa3cbf451b2a1d54159d42c3ea5ab8725b0c8620d831f8c1602676b38ab00e6","text":"Sessions","translated":"会话","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:56Z"} -{"cache_key":"c85ec585240e224ad62f0cde143c6625d9eb6e2dfc1a425098b24975e4aa43bf","segment_id":"index.md:856302569e24c4d6","source_path":"index.md","text_hash":"856302569e24c4d64997e2ec5c37729f852bcccf333ba1e2f71e189c9d172e6d","text":": SSH tunnel or tailnet/VPN; see ","translated":":SSH 隧道或 tailnet/VPN;参见 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:38Z"} -{"cache_key":"c8ced90adeff8e91c3f5418bdc11abd60378688097157d3e12c7b51e9841ca2c","segment_id":"environment.md:cdb4ee2aea69cc6a","source_path":"environment.md","text_hash":"cdb4ee2aea69cc6a83331bbe96dc2caa9a299d21329efb0336fc02a82e1839a8","text":".","translated":"。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:58Z"} -{"cache_key":"c982edd40183708dbf5bc791228db4bfd5b4b33d5a623e1173ee48a697e31c6f","segment_id":"index.md:f12242785ecda793","source_path":"index.md","text_hash":"f12242785ecda7935ded50cd48418357d32d3bac290f7a199bc9f0c7fbd13123","text":") — Location parsing (Telegram + WhatsApp)","translated":")—— 位置解析(Telegram + WhatsApp)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:56Z"} -{"cache_key":"c98b98cde5f7adf29bada7169968b0e7c20763589cdef21766c06460d88f0f22","segment_id":"index.md:0c67abfaa5415391","source_path":"index.md","text_hash":"0c67abfaa5415391a31cf3a4624746b6b212b5ae66364be28ee2d131f014e0c6","text":"🧩 ","translated":"🧩 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:44Z"} -{"cache_key":"c9939001c16700c5d35daa87cee1e92d3290b1c7987abc44df7af44cb0549c21","segment_id":"help/index.md:frontmatter:read_when:0","source_path":"help/index.md:frontmatter:read_when:0","text_hash":"ee0615553374970664b58ebd8e5d0ebc9bc8a5f03387671afbfd0096b390aa9b","text":"You’re new and want the “what do I click/run” guide","translated":"你是新手,想要一份\"该点击什么/运行什么\"的指南","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:39:27Z"} -{"cache_key":"c9dab76bf88e0e641fc671ad2fbd902a1ae1db96eb22db04db9410d8a5ce0a79","segment_id":"index.md:63a3abfa879299dd","source_path":"index.md","text_hash":"63a3abfa879299ddcc03558012bfd6075cbd72f7a175b739095bf979700297f7","text":"Multi-instance quickstart (optional):","translated":"多实例快速开始(可选):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:23Z"} -{"cache_key":"ca3d654d1f779e0df22c1f09273aac145e550253cf972adfbc28d2751bbce6c5","segment_id":"index.md:1e37e607483201e2","source_path":"index.md","text_hash":"1e37e607483201e2152d2e9c68874dd4027648efdd9cfccb7bf8c9837398d143","text":"), serving ","translated":"),提供 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:01Z"} -{"cache_key":"ca81625ad797b914689b25dc7631b7d3b910d56f40d3f807c8b9253cdfd4d17f","segment_id":"index.md:f0e2018271f51504","source_path":"index.md","text_hash":"f0e2018271f515041084c8189f297236abe18f9ec77edad1a61c5413310bbd9e","text":"🖥️ ","translated":"🖥️ ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:49Z"} -{"cache_key":"caf51be0c1458b52f94033eb1b629dba33d1d3a372efd533cd0b13846db8c4d0","segment_id":"index.md:4d87941d681ca4e8","source_path":"index.md","text_hash":"4d87941d681ca4e89ca303d033b7d383d3acfbb6d9d9616bd88d7c19cf92c3dd","text":"Pi","translated":"Pi","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:27:56Z"} -{"cache_key":"cb6c11ef1460261e35016f0eaa5966553e6f8f20982b69d042a4f62515d65ad7","segment_id":"help/index.md:frontmatter:read_when:0","source_path":"help/index.md:frontmatter:read_when:0","text_hash":"ee0615553374970664b58ebd8e5d0ebc9bc8a5f03387671afbfd0096b390aa9b","text":"You’re new and want the “what do I click/run” guide","translated":"你是新手,想要一份\"该点什么/该运行什么\"的指南","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:56:12Z"} -{"cache_key":"cb7224509e3500bfd50fd737857395338c005b21a5cb2142a81af37ebe5204ad","segment_id":"environment.md:frontmatter:read_when:2","source_path":"environment.md:frontmatter:read_when:2","text_hash":"822b3d74ce16c1be19059fad4ca5bf7ae9327f58fa1ff4e75e78d5afa75c038f","text":"You are documenting provider auth or deployment environments","translated":"您正在记录 提供商 的认证或部署环境","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:17Z"} -{"cache_key":"cbc65efaa2c9304b41332d4d4b06ec60e7b2eaf66b98f9c7de9db4ada5b50007","segment_id":"help/index.md:frontmatter:read_when:0","source_path":"help/index.md:frontmatter:read_when:0","text_hash":"ee0615553374970664b58ebd8e5d0ebc9bc8a5f03387671afbfd0096b390aa9b","text":"You’re new and want the “what do I click/run” guide","translated":"你是新手,想要一份\"我该点击/运行什么\"的指南","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:21:32Z"} -{"cache_key":"cbccccc9ef3c5b2bdfc9137d40fcc79548902f77addaa40d473cf39ed46d1658","segment_id":"index.md:255ce77b7a6a015f","source_path":"index.md","text_hash":"255ce77b7a6a015f8595868a524b67c134e8fb405f4584fdac020e57f4ccd5f6","text":"Loopback-first","translated":"优先回环","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:48Z"} -{"cache_key":"cbff4c4140b6a285569765e9905785ee009781edd57d605ffb9171aff34c2d79","segment_id":"index.md:6b3f22c979b9e6f8","source_path":"index.md","text_hash":"6b3f22c979b9e6f8622031a6b638ec5f730c32de646d013e616078e03f5a6149","text":"iOS node","translated":"iOS 节点","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:08Z"} -{"cache_key":"cc06ade0909671964a2ea7220e8ac6cbb33aaa9dffe47a13da27bea6d2d9a0d3","segment_id":"index.md:d08cec54f66c140c","source_path":"index.md","text_hash":"d08cec54f66c140c655a1631f6d629927c7c38b9c8bfa91c875df9bd3ad3c559","text":"OpenClaw assistant setup","translated":"OpenClaw 助手设置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:04:14Z"} -{"cache_key":"cc58238acf407fd16eca091f737e3d7e588e27b1cad3453883c342c3c0e8e9b4","segment_id":"environment.md:cdb4ee2aea69cc6a","source_path":"environment.md","text_hash":"cdb4ee2aea69cc6a83331bbe96dc2caa9a299d21329efb0336fc02a82e1839a8","text":".","translated":".","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:26Z"} -{"cache_key":"cc63b18c7aa9315b943c74483a99d77ec5c26a9ca9a1120637ac7e346b98fc4d","segment_id":"start/getting-started.md:fa6eee60553a165b","source_path":"start/getting-started.md","text_hash":"fa6eee60553a165b731e236a48d54169a31fa39cccbc1967e13fba9e4cc38868","text":"Pairing doc: ","translated":"配对文档: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:41Z"} -{"cache_key":"cc8f5dcfbe51a4638b375d367381be97b79d012b56b2c7eadd2e38d164cdd177","segment_id":"start/wizard.md:e18251a039a6b735","source_path":"start/wizard.md","text_hash":"e18251a039a6b7353675decc475898bfdb91d3bd9d37e83c8447d0359b8711c3","text":"Non-interactive flags: ","translated":"非交互标志: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:47:05Z"} -{"cache_key":"cc906618700533ea8dd9d752b8e2ef28ffb8707654a557d7cef1b867cdd57f1a","segment_id":"index.md:ceee4f2088b9d5ba","source_path":"index.md","text_hash":"ceee4f2088b9d5ba7d417bac7395003acfbcef576fd4cc1dd3063972f038218a","text":"The name","translated":"名称","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:01Z"} -{"cache_key":"cc93bf5458542a509cb8460472bf3269d769fe1cdee6201ab736c4b5460d64d5","segment_id":"start/wizard.md:4bba41aa0148ebb4","source_path":"start/wizard.md","text_hash":"4bba41aa0148ebb49b33763f1b38a983af7c0a4dd22fff07d3cf94fdcb96ecd3","text":"Linux (and Windows via WSL2): systemd user unit","translated":"Linux(以及通过 WSL2 的 Windows):systemd 用户单元","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:45:17Z"} -{"cache_key":"cd2d7cce6f1c10e008e8efe49ecf02b6ac401d686667986409f7e6796e9f1140","segment_id":"environment.md:45ca56d179d4788c","source_path":"environment.md","text_hash":"45ca56d179d4788c55ba9f7653b376d62e7faa738e92259e3d4f6f5c1b554f28","text":"Related","translated":"相关内容","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:22:44Z"} -{"cache_key":"cd4cdcf85e185ce70df30cbda64fb2d77baa6a6c989e67cde3f80315c06b3839","segment_id":"index.md:45e6d69dbe995a36","source_path":"index.md","text_hash":"45e6d69dbe995a36f7bc20755eff4eb4d2afaaedbcac4668ab62540c57219f32","text":"macOS app","translated":"macOS 应用","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:53:33Z"} -{"cache_key":"cd82c395857efd6e374fec3ad86de5dd8989415770d38a86d8a1980cd372b7f5","segment_id":"start/wizard.md:c4e77a12a2c0b664","source_path":"start/wizard.md","text_hash":"c4e77a12a2c0b664f398de857da71528f66ffb4a70e65769897dcc7147167b2c","text":" or use allowlists.","translated":" 批准,或使用允许名单。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:45:05Z"} -{"cache_key":"cd9743cfc03baed1ac0aba354dec17a69f9204d0f64f1c71e9c137298bff5141","segment_id":"help/index.md:b79cac926e0b2e34","source_path":"help/index.md","text_hash":"b79cac926e0b2e347e72cc91d5174037c9e17ae7733fd7bdb570f71b10cd7bfc","text":"Help","translated":"帮助","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:56:16Z"} -{"cache_key":"cdb2a2bfea264785bf8cb89785edd4df2b7de3adf29db9507ad953dcbdd6d939","segment_id":"help/index.md:b79cac926e0b2e34","source_path":"help/index.md","text_hash":"b79cac926e0b2e347e72cc91d5174037c9e17ae7733fd7bdb570f71b10cd7bfc","text":"Help","translated":"帮助","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:21:35Z"} -{"cache_key":"cdd968f07504f0d2da9c8620421deda0bfb9153636d6be92a239eb6adcd9f2b9","segment_id":"environment.md:f0442e6e05ccca16","source_path":"environment.md","text_hash":"f0442e6e05ccca160d17de0e7d509891b91b921366b2202b2b5c80435824e140","text":"Two equivalent ways to set inline env vars (both are non-overriding):","translated":"两种等效的内联设置 环境变量 的方式(均为非覆盖):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:02Z"} -{"cache_key":"ce171e0ce019a7a095f4e7aaa27de6784ee9bb99d4353b3b3b9719eff6509d30","segment_id":"index.md:856302569e24c4d6","source_path":"index.md","text_hash":"856302569e24c4d64997e2ec5c37729f852bcccf333ba1e2f71e189c9d172e6d","text":": SSH tunnel or tailnet/VPN; see ","translated":":SSH 隧道或 Tailnet/VPN;参见 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:16Z"} -{"cache_key":"ce26a64b93065c2ad2be924884f77346c4578db84e4df79e49d5ee43b3ccb617","segment_id":"index.md:9fc31bacba5cb332","source_path":"index.md","text_hash":"9fc31bacba5cb33207804b9e6a8775a3f9521c9a653133fd06e5d14206103e48","text":"Streaming + chunking","translated":"流式传输 + 分块","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:06Z"} -{"cache_key":"ce31f98c669ba131d564edefa106a53c0d099661680c8872048ae0636dfbe73c","segment_id":"environment.md:c2d7247c8acb83a5","source_path":"environment.md","text_hash":"c2d7247c8acb83a5a020458fa836c2445922b51513dbdbf154ab5f7656cb04e9","text":"; does not override).","translated":";不覆盖)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:37Z"} -{"cache_key":"ce3c2713f373fff6ebab9c70141debe3262d0a7ff6214fd146fa277b67c1ab3e","segment_id":"start/wizard.md:bd8a6e0ff884f51d","source_path":"start/wizard.md","text_hash":"bd8a6e0ff884f51d6a4a9b70f4680033876871936c72cf8af5df4e4b2836c75c","text":"Wizard runs a model check and warns if the configured model is unknown or missing auth.","translated":"向导会运行模型检查,如果配置的模型未知或缺少认证则发出警告。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:24Z"} -{"cache_key":"ce618de323766f3aa222b534fb69a1502c03699a6b57e801e6f1a1b3c32d3431","segment_id":"index.md:9abe8e9025013e78","source_path":"index.md","text_hash":"9abe8e9025013e78a6bf2913f8c20ee43134ad001ce29ced89e2af9c07096d8f","text":"Media: images","translated":"媒体:图片","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:53:25Z"} -{"cache_key":"ce62c5006939b21f7a2d236f9cdb545ce653778800504e85668fe99075067cbf","segment_id":"environment.md:6db0742daaf9f191","source_path":"environment.md","text_hash":"6db0742daaf9f191ab7816d2c9d317b1ea1693453a8c63b95af8b01477e0f5bb","text":" runs your login shell and imports only ","translated":" 运行你的登录 shell,并仅导入 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:47Z"} -{"cache_key":"cf001b0403d7ae959797460c96aa4da24818c662362595f2da0be349caeb6a09","segment_id":"index.md:cda454f61dfcac70","source_path":"index.md","text_hash":"cda454f61dfcac7007a9edc538f9f58cf38caa0652e253975979308162bccc53","text":"Gateway configuration","translated":"Gateway 配置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:31Z"} -{"cache_key":"cf9fc66b44905a0c47ca04f98d6e6507821789844f1e97ca2026f7df6e5b1451","segment_id":"environment.md:f7e239a42b7cd986","source_path":"environment.md","text_hash":"f7e239a42b7cd986a1558fed234e975ed2e96e9d37cf0a93f381778c461c89dd","text":"OpenClaw pulls environment variables from multiple sources. The rule is ","translated":"OpenClaw 从多个来源拉取 环境变量。规则是 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:11Z"} -{"cache_key":"cfc26997d872d590a2aba69f0aba6f704354d3aea9aa3bd433693ca7182cacdc","segment_id":"start/getting-started.md:1093115897879aa3","source_path":"start/getting-started.md","text_hash":"1093115897879aa3ad9511a1dc2850929cfb60ba45ec741605f69f5d20203472","text":"Runtime","translated":"运行时","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:17Z"} -{"cache_key":"d0594bae529c9774fa42aa68b86c4e1cb876bee2ffe9173b4d9f5a5f8325cae0","segment_id":"start/wizard.md:cac2e1b207fdd700","source_path":"start/wizard.md","text_hash":"cac2e1b207fdd700258939f1e7977375609e4b2e26785c93c230da25bc0cbd82","text":").\nClients (macOS app, Control UI) can render steps without re‑implementing onboarding logic.","translated":")。客户端(macOS 应用、Control UI)可以渲染步骤而无需重新实现上手引导逻辑。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:47:46Z"} -{"cache_key":"d076be47cee695839a6d7e0cd10b0c8b2a7da5ae5d222273b89c28de425b741e","segment_id":"environment.md:f6b2ffe1d0d5f521","source_path":"environment.md","text_hash":"f6b2ffe1d0d5f521b76cabc67d6e96da2b1170eef8086d530558e9906a7f092d","text":"Models overview","translated":"模型概览","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:47:21Z"} -{"cache_key":"d08787ed2ed706d9bd6e4f7296e7330177093a07d1b129a0487e2e0e151eb63e","segment_id":"start/getting-started.md:ea8c0ae0a9156b3b","source_path":"start/getting-started.md","text_hash":"ea8c0ae0a9156b3bf89fa7572f685a4d9fd24e89a7326fc7f41fc7e85f139b80","text":"WSL2","translated":"WSL2","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:39Z"} -{"cache_key":"d09b7c0117a630c96ed0f5f9c262caa47d5273ff6d51a8d46c0ca45721eaebe2","segment_id":"environment.md:3fe738a7ee6aaff5","source_path":"environment.md","text_hash":"3fe738a7ee6aaff51f099d9a8314510c99ced6a568eb38c67642cd43bb54eec0","text":" in the current working directory","translated":" 在当前工作目录中","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:04Z"} -{"cache_key":"d0d44c0cc0a3150ea2571f5ecd32d65671470df6b9b093decacc0852597b2201","segment_id":"start/wizard.md:5a5902a06688a396","source_path":"start/wizard.md","text_hash":"5a5902a06688a39618ade9c26292a6e3b13124cee42cc028d35943ccc1e21a5c","text":" (full control).","translated":" (完全控制)模式开始。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:41Z"} -{"cache_key":"d0f76abf14b1216bff9974f7e507a3c2a43f331f1ebd805279843692ae78f662","segment_id":"index.md:5cf9ea2e20780551","source_path":"index.md","text_hash":"5cf9ea2e2078055129b38cfbc394142ca6ca41556bd6e31cbd527425647c1d1e","text":"One Gateway per host (recommended)","translated":"每台主机一个 Gateway(推荐)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:30Z"} -{"cache_key":"d12af03e20c20a4ebdcdbf4c32f52081339c0aa7bd1bb44b311875547bb39918","segment_id":"start/wizard.md:14a01a1b76ad6311","source_path":"start/wizard.md","text_hash":"14a01a1b76ad63111eb126c1d124a893abcb5cc90fe893825a9c96362112ab4f","text":" adds gateway health probes to status output (requires a reachable gateway).","translated":" 将 Gateway 健康探测添加到状态输出中(需要可达的 Gateway)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:45:41Z"} -{"cache_key":"d1818c531bc4e1cca14e64f751cf8698cb0701a745fb3da03b37b4fd7129c18b","segment_id":"start/wizard.md:6d0323ac97e5a313","source_path":"start/wizard.md","text_hash":"6d0323ac97e5a3136bae41278bfd46f5985969ee57dea5f25d7faa78bb01c87e","text":" when model is unset or ","translated":" (当模型未设置或为 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:24Z"} -{"cache_key":"d1a349d8c1859f2d1c00367b86704fa95d4168c8615ada60834a6890215d1f58","segment_id":"index.md:3c064c83b8d244fe","source_path":"index.md","text_hash":"3c064c83b8d244fef61e5fd8ce5f070b857a3578a71745e61eea02892788c020","text":" — Anthropic (Claude Pro/Max) + OpenAI (ChatGPT/Codex) via OAuth","translated":" —— 通过 OAuth 支持 Anthropic(Claude Pro/Max)+ OpenAI(ChatGPT/Codex)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:28Z"} -{"cache_key":"d1d30ee69fb8519a966ebbb5cb51d2be029399b2951ef296b23f96d3fea4bc3a","segment_id":"start/wizard.md:3fad3d2e2c01a9ea","source_path":"start/wizard.md","text_hash":"3fad3d2e2c01a9ea3a66cbcb1b05a0d5982e3665cf0e1ec6dee0e031e83137e1","text":"Reads the available skills and checks requirements.","translated":"读取可用技能并检查依赖条件。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:45:43Z"} -{"cache_key":"d234d82b06f65337a5ab45e775d0f0abda696d4e04e6115c6a042853b3b11ca4","segment_id":"index.md:084514e91f37c3ce","source_path":"index.md","text_hash":"084514e91f37c3ce85360e26c70b77fdc95f0d3551ce309db96fbcf956a53b01","text":"Dashboard (browser Control UI)","translated":"仪表板(浏览器控制界面)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:04Z"} -{"cache_key":"d29dfffbf5c42410939bbb88504ae09e8009835fc6ba11b0bd27ae0da0839aee","segment_id":"environment.md:45ca56d179d4788c","source_path":"environment.md","text_hash":"45ca56d179d4788c55ba9f7653b376d62e7faa738e92259e3d4f6f5c1b554f28","text":"Related","translated":"相关内容","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:30Z"} -{"cache_key":"d2daa68c34089a85125ae39af1770f4ec07070bbe5b06c0d0c2d84ea0d10a6ec","segment_id":"index.md:ded906ea94d05152","source_path":"index.md","text_hash":"ded906ea94d0515249f0bcab1ba63835b5968c142e9c7ea0cb6925317444d98c","text":"Configuration examples","translated":"配置示例","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:27Z"} -{"cache_key":"d2daf9c0748530a05031c851236072d2d247919151adeb5afc085b3c1df0a5d2","segment_id":"index.md:b214cd10585678ca","source_path":"index.md","text_hash":"b214cd10585678ca1250ce1ae1a50ad4001de4577a10e36be396a3409314e442","text":"@badlogicc","translated":"@badlogicc","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:27Z"} -{"cache_key":"d2eeaf2250e691f5598d218f5ab0a4086d57b68635b5d91718b8895e00fd80e6","segment_id":"environment.md:61115f6649792387","source_path":"environment.md","text_hash":"61115f664979238731a390e84433a818965b7eaf1d38fa5b4b1507c33ef28c91","text":"Precedence (highest → lowest)","translated":"优先级(从高到低)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:19:25Z"} -{"cache_key":"d304bb8482d72d9a36276fe206308ad11314fae096c08348d76048bc1593c708","segment_id":"start/getting-started.md:d00eca1bae674280","source_path":"start/getting-started.md","text_hash":"d00eca1bae6742803906ab42a831e8b5396d15b6573ea13c139ec31631208ec1","text":"Getting Started","translated":"快速入门","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:21Z"} -{"cache_key":"d308117273fcffa99031b6168d0430801d743429421c4ebbc45aedace958b061","segment_id":"index.md:31365ab9453d6a1e","source_path":"index.md","text_hash":"31365ab9453d6a1ec03731622803d3b44f345b6afad08040d7f3e97290c77913","text":"do nothing","translated":"不做任何操作","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:03:30Z"} -{"cache_key":"d30d12f7e78eb693ff2d7b58b572be7efd8f8787f98a3ccad0b04752af019ce5","segment_id":"environment.md:b1d6b91b67c2afa5","source_path":"environment.md","text_hash":"b1d6b91b67c2afa5e322988d9462638d354ddf8a1ef79dba987f815c22b4baee","text":" at ","translated":" 位于 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:49Z"} -{"cache_key":"d41535413a3b4c62091cb7682dab05259a63ac65d34ea5b3463c5808ccb28960","segment_id":"index.md:268ebcd6be28e8d8","source_path":"index.md","text_hash":"268ebcd6be28e8d853ace3a6e28f269fbda1343b53e3f0de97ea3d5bf1a0e33e","text":"Clawd","translated":"Clawd","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:32Z"} -{"cache_key":"d43575ea070a82b8c1685440526dc44dd9aed79bc448b5192134b0fa0c008749","segment_id":"index.md:ee8b06871d5e335e","source_path":"index.md","text_hash":"ee8b06871d5e335e6e686f4e2ee9c9e6de5d389ece6636e0b5e654e0d4dd5b7e","text":"Control UI (browser)","translated":"控制界面(浏览器)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:53:10Z"} -{"cache_key":"d4735a7a8ac59df4f41d36c7c08984885356d88053b7708e6855dbd446102081","segment_id":"index.md:042c75df73389c8a","source_path":"index.md","text_hash":"042c75df73389c8a7c0871d2a451bd20431d24e908e2c192827a54022df95005","text":"Nacho Iacovino","translated":"Nacho Iacovino","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:55Z"} -{"cache_key":"d490073217e575e01f8f2e93e3101b423f269eba9ce72829891ee9b89843212e","segment_id":"index.md:0b60fe04b3c5c3c7","source_path":"index.md","text_hash":"0b60fe04b3c5c3c76371b6eca8b19c8e09a0e54c9010711ff87e782d87d2190b","text":"Android app","translated":"Android 应用","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:53:38Z"} -{"cache_key":"d49ac0479b4e2121af227b4a3bdcebe1d4a0d610b35baa6782dafb7fbf4fc4a6","segment_id":"environment.md:8d076464a84995bc","source_path":"environment.md","text_hash":"8d076464a84995bc095e934b0aa1e4419372f27cd71d033571e4dbba201ee5d8","text":"You can reference env vars directly in config string values using ","translated":"你可以使用以下方式在配置字符串值中直接引用环境变量 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:47:01Z"} -{"cache_key":"d4d0c17af1fe72f822af0009148f75c60a1ed6451e748c2b3df85d55e7124987","segment_id":"start/getting-started.md:ebaef508acb6f7b6","source_path":"start/getting-started.md","text_hash":"ebaef508acb6f7b6bb2a0a4342b2aafd862c3694450fe11789070419c1591681","text":"iOS/Android nodes (Canvas/camera/voice): ","translated":"iOS/Android 节点(Canvas/相机/语音): ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:25Z"} -{"cache_key":"d4f41acdb842e7c1c8bfec5ad3ab1dab8d98a4792e99dd535877f4201a21a031","segment_id":"start/wizard.md:9db982e2d3194ff1","source_path":"start/wizard.md","text_hash":"9db982e2d3194ff10f91d59646b6193c1b3d36f86f8d4da50b3d1bf8a5ae2ac6","text":": bot token.","translated":":机器人令牌。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:44:30Z"} -{"cache_key":"d4f4558ec6bd856ca63ddc3f050e7f129c76188a898fa7765d990b8e1ca6fdcd","segment_id":"environment.md:496aca80e4d8f29f","source_path":"environment.md","text_hash":"496aca80e4d8f29fb8e8cd816c3afb48d3f103970b3a2ee1600c08ca67326dee","text":" block","translated":" 块","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:51Z"} -{"cache_key":"d4f9bd5e931f08626a42d41967e2597390d16854993c968eeb9cc8720374a1a0","segment_id":"start/wizard.md:9fd728c66c9a256b","source_path":"start/wizard.md","text_hash":"9fd728c66c9a256b121472dabf32a34317aed01d8427d70ec830289cf23a7cc8","text":"Add ","translated":"添加 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:47:00Z"} -{"cache_key":"d5381f750f50864e130866c293987087c17d023cec62188df764f7e91dc7606a","segment_id":"index.md:e1b33cfa2a781bde","source_path":"index.md","text_hash":"e1b33cfa2a781bde9ef6c1d08bf95993c62f780a6664f5c5b92e3d3633e1fcf8","text":" (@nachoiacovino, ","translated":" (@nachoiacovino, ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:00Z"} -{"cache_key":"d5c1ce3309dbb00f67e9ff21a4f6dbef5f531ee3781b33f5fc1be91b6fd46196","segment_id":"start/wizard.md:5aa55e363e93c8bc","source_path":"start/wizard.md","text_hash":"5aa55e363e93c8bc3623dcb97e318cfc0784b4fb24e287f600192488208fd8f1","text":"Local mode (default)","translated":"本地模式(默认)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:13Z"} -{"cache_key":"d61140d8a641f1f6316535bc25bdb629b4508cb21951f549a6908b0e8c75b303","segment_id":"environment.md:a9d9b94d02c2f6ab","source_path":"environment.md","text_hash":"a9d9b94d02c2f6ab616036cab13ba821053514d384f064c56d338d748050ba7c","text":" lowest)","translated":" 最低)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:31Z"} -{"cache_key":"d62921e75336cfb2d915a837e650bc5d8690441848c19f2d5a57ecbf0247c33b","segment_id":"start/getting-started.md:88d90e2eef3374ce","source_path":"start/getting-started.md","text_hash":"88d90e2eef3374ce1a7b5e7fbd3b1159364b26a8ceb2493d6e546d4444b03cda","text":"Tailscale","translated":"Tailscale","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:34Z"} -{"cache_key":"d6390c8e7e97434033a209c981093a19cabd19baa33feab5462c9cbfe94ed51d","segment_id":"start/getting-started.md:8eb3ea9bbde63159","source_path":"start/getting-started.md","text_hash":"8eb3ea9bbde631592dfac3150044fabe4678c820a107c026035c13bf0c8ba9d7","text":"Auth","translated":"认证","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:03Z"} -{"cache_key":"d6402ced9e7963b9ac7e01b7552846636e06afd06ad8433345d9a108f4360fab","segment_id":"environment.md:453c14128fbfb5f6","source_path":"environment.md","text_hash":"453c14128fbfb5f6757511557132a1dbb3bcbf243267630bfec49db8518c7780","text":"Env var substitution in config","translated":"配置中的环境变量替换","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:26:21Z"} -{"cache_key":"d6cb6405997baeadc37aefa302a5594766dc76d757bdb0224e706a196265ab60","segment_id":"index.md:66d0f523a379b2de","source_path":"index.md","text_hash":"66d0f523a379b2de6f8d5fba3a817ebc395f7bcaa54cc132ca9dfa665d1e9378","text":"Skills","translated":"技能","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:13Z"} -{"cache_key":"d73268cbf726ddfd975878dfbe6a3b4d5418e1d7568bcb23d5745eea13b014b7","segment_id":"environment.md:frontmatter:read_when:0","source_path":"environment.md:frontmatter:read_when:0","text_hash":"90fc0487bff88009979cff1061c1a882df8c3b1baa9c43538331d9d5dab15479","text":"You need to know which env vars are loaded, and in what order","translated":"你需要了解加载了哪些环境变量,以及它们的加载顺序","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:19:14Z"} -{"cache_key":"d771dee3183c3dde95a035d4dd963966fff7f9d7d0d35eb1d66e26e34e6e0746","segment_id":"help/index.md:frontmatter:read_when:1","source_path":"help/index.md:frontmatter:read_when:1","text_hash":"857eafc389d179e83e21e46c10527fec40894fe064c63847ba06b946b7d5eb73","text":"Something broke and you want the fastest path to a fix","translated":"出了问题,你想找到最快的修复方法","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:39:29Z"} -{"cache_key":"d78b68adf70db59ac77fac9cfe5e338025bf15b23845ec12fa109dffffd26525","segment_id":"environment.md:6db0742daaf9f191","source_path":"environment.md","text_hash":"6db0742daaf9f191ab7816d2c9d317b1ea1693453a8c63b95af8b01477e0f5bb","text":" runs your login shell and imports only ","translated":" 运行您的登录 shell 并仅导入 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:41:14Z"} -{"cache_key":"d791df1af8af8b787e124642b683bf3a90723f32075b0da41ba134fab01e7b16","segment_id":"index.md:42071940eb773f4d","source_path":"index.md","text_hash":"42071940eb773f4dcb7111f0626b4a7a823fc44098e143ff425db8a03528609d","text":" — because every space lobster needs a time-and-space machine.","translated":" — 因为每只太空龙虾都需要一台时空机器。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:20Z"} -{"cache_key":"d798cc1cc5fcd0af14bb92521474c72168a3812ac48cc219e3c0757169d2f2b3","segment_id":"environment.md:1ec31258a6b45ea9","source_path":"environment.md","text_hash":"1ec31258a6b45ea903cd76f5b0190a99ab56afff6241a04f0681eb12b7a02484","text":"Env var equivalents:","translated":"等效的环境变量:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:22:27Z"} -{"cache_key":"d7efd30a0122aa5514cc6d7fb73d6279b2d1eee879e4ec731d2873142860e82b","segment_id":"index.md:723784fa2b6a0876","source_path":"index.md","text_hash":"723784fa2b6a0876540a92223ee1019f24603499d335d6d82afbc520ef5b5d57","text":") — Creator, lobster whisperer","translated":")—— 创建者,龙虾低语者","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:22Z"} -{"cache_key":"d82d08bf8b5d5245c698d1341d95dd2cbe797404269dffbb948000cab390fc3f","segment_id":"start/wizard.md:765dd901deb1679d","source_path":"start/wizard.md","text_hash":"765dd901deb1679d2fa08bebd5e5ca8a998e8c33b6203053cb18fd352ce22330","text":"Non‑interactive mode","translated":"非交互模式","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:47:11Z"} -{"cache_key":"d844ae7cf5ac1af1c8e77c093dc0a5b087dbe111241c75fcf0d68c38966fc760","segment_id":"environment.md:a258b30f88c30650","source_path":"environment.md","text_hash":"a258b30f88c30650e73073d5bdde5cfcc6987100ae62d37789e5c46a0d85b7c6","text":"Global ","translated":"全局 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:47Z"} -{"cache_key":"d89eb1af6a6780d9f17aa4ab63b9ea6fb426a6458811cc4898df06d14464d7cb","segment_id":"start/getting-started.md:7412cf3ea50ad037","source_path":"start/getting-started.md","text_hash":"7412cf3ea50ad0377e8450ef19d397a4b62fc2a44c9ab7f02cc012f80df90199","text":" (stores ","translated":" (存储 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:32Z"} -{"cache_key":"d8ad10373e0be1e5e296d2955307d55e6dca0e4e355d46968d5baed7c6914c70","segment_id":"environment.md:cda454f61dfcac70","source_path":"environment.md","text_hash":"cda454f61dfcac7007a9edc538f9f58cf38caa0652e253975979308162bccc53","text":"Gateway configuration","translated":"Gateway 配置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:17:12Z"} -{"cache_key":"d8cc06094a692bfc0650f92c245909ce4308fcc945faabdc2b7bad4f9a1b9998","segment_id":"start/wizard.md:576ed4fd7e0e5fcd","source_path":"start/wizard.md","text_hash":"576ed4fd7e0e5fcd52f1a92c0b5a8df3ed8f33c4c280c9d15e53955d15633796","text":" (you’ll be prompted for your phone number)","translated":" (系统会提示您输入手机号码)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:07Z"} -{"cache_key":"d8fe9f40df201863d43f4937a52bac7d14019fae82150f1191fe4bb66819d827","segment_id":"help/index.md:3c33340bd23b8db8","source_path":"help/index.md","text_hash":"3c33340bd23b8db89f18fe7d05a954738c0dd5ba9623cf6bdb7bb5d1a3729cfc","text":"FAQ (concepts)","translated":"常见问题(概念)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:34Z"} -{"cache_key":"d93001811d4774893fac9a800d8e9c14259b90fc5ed85a3e5e6d381bfb591846","segment_id":"index.md:32ebb1abcc1c601c","source_path":"index.md","text_hash":"32ebb1abcc1c601ceb9c4e3c4faba0caa5b85bb98c4f1e6612c40faa528a91c9","text":" (","translated":" (","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:10Z"} -{"cache_key":"d952c24b47cb7a9f69823c976f2f5e103fdc731a8bd74cae1436d86f420022df","segment_id":"environment.md:frontmatter:read_when:1","source_path":"environment.md:frontmatter:read_when:1","text_hash":"a3a2d99a99de98220c8e0296d6f4e4b2a34024916bd2379d1b3b9179c8fae46f","text":"You are debugging missing API keys in the Gateway","translated":"你正在调试 Gateway 中缺失的 API 密钥","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:21:50Z"} -{"cache_key":"d972ebc19ef87492ca8c11159fd6342cced6b4e19743d79d81ae33fafe35bbd8","segment_id":"environment.md:f7e239a42b7cd986","source_path":"environment.md","text_hash":"f7e239a42b7cd986a1558fed234e975ed2e96e9d37cf0a93f381778c461c89dd","text":"OpenClaw pulls environment variables from multiple sources. The rule is ","translated":"OpenClaw 从多个来源获取环境变量。规则是 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:21:57Z"} -{"cache_key":"d9923f60f9531ccaaefa870fa682febfe862bf9a38ced5baa99ea8637d7fc5ae","segment_id":"start/getting-started.md:63d3b285bad7d501","source_path":"start/getting-started.md","text_hash":"63d3b285bad7d5015cea4d6e62f972e83221dfce48c6919bd536c5e894a6607d","text":" set an API key (wizard can store it for service use). ","translated":" 设置 API 密钥(向导可以将其存储以供服务使用)。 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:32Z"} -{"cache_key":"d9b22590788b6c0abf9a15102d23d2aeb6608cf4acc0339e69be4e52ae38af48","segment_id":"index.md:f9b8279bc46e847b","source_path":"index.md","text_hash":"f9b8279bc46e847bfcc47b8701fd5c5dc27baa304d5add8278a7f97925c3ec13","text":"Mattermost (plugin)","translated":"Mattermost(插件)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:53:18Z"} -{"cache_key":"da18bab9968b574835d3ac2fa578c4d9484bd549584abe26d6dd6ef900786186","segment_id":"start/wizard.md:b3903e5fd7656678","source_path":"start/wizard.md","text_hash":"b3903e5fd7656678464dd2a865aaddae81c1a9967b2b28de65963482c18101a4","text":", get it at ","translated":",请在 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:39Z"} -{"cache_key":"da2e517a094d1b2ea1a3ef7068f6a9d51fdfdf0a022f7219b7cee208042f347e","segment_id":"environment.md:cdb4ee2aea69cc6a","source_path":"environment.md","text_hash":"cdb4ee2aea69cc6a83331bbe96dc2caa9a299d21329efb0336fc02a82e1839a8","text":".","translated":"。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:22Z"} -{"cache_key":"da6fd0546d605ddbff40ee5eeab7a9dba889d06f55b7668b2ea364b8d13db5b0","segment_id":"start/getting-started.md:8026e8b07f2541e0","source_path":"start/getting-started.md","text_hash":"8026e8b07f2541e05438c325c641d6c725179032c826ab3d788f1d7f6ee6cc48","text":"gateway settings","translated":"Gateway 设置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:54Z"} -{"cache_key":"da93b7ddfcae6217e6d6986b9ce70bb9a1a2d9cfad63f48bfad0bf32de42231f","segment_id":"environment.md:7175517a370b5cd2","source_path":"environment.md","text_hash":"7175517a370b5cd2e664e3fd29c4ea9db5ce17058eb9772fe090a5485e49dad6","text":" or ","translated":" 或 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:17Z"} -{"cache_key":"daa769cecb2f8416182d068699a32d5eb21c0317b3290a243cdecd970d5962a8","segment_id":"index.md:0d517afa83f91ec3","source_path":"index.md","text_hash":"0d517afa83f91ec33ee74f756c400a43b11ad2824719e518f8ca791659679ef4","text":"Web surfaces (Control UI)","translated":"Web 界面(控制界面)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:26Z"} -{"cache_key":"dab106a105f2b823c007205705cad6e89b432c5ca1ef47eabc0f310d8efc383c","segment_id":"environment.md:6863067eb0a2c749","source_path":"environment.md","text_hash":"6863067eb0a2c7499425c6c189b2c88bac55ca754285a6ab1ef37b75b4cfad4d","text":"See ","translated":"参见 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:23Z"} -{"cache_key":"dac6075e2d2a3911099dba69ad509d84086bcd1b1c736fee0152408194e15e11","segment_id":"start/getting-started.md:6dd923776874c55b","source_path":"start/getting-started.md","text_hash":"6dd923776874c55bce97640e624fb7a344d86ed45b1c54be63346b52026a1652","text":"Auth profiles (OAuth + API keys): ","translated":"认证配置文件(OAuth + API 密钥): ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:38Z"} -{"cache_key":"db301ad112142ff90fb1b8331377445ca0dd7eae4b68bba7cc6930841d303d06","segment_id":"start/wizard.md:0ed32a8e95d8664d","source_path":"start/wizard.md","text_hash":"0ed32a8e95d8664d39b5e673327e225f72eb6d6733b764db17d1bbc0536a2880","text":"Windows uses WSL2; signal-cli install follows the Linux flow inside WSL.","translated":"Windows 使用 WSL2;signal-cli 安装遵循 WSL 内的 Linux 流程。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:48:18Z"} -{"cache_key":"dbd450b11463a9da9dd0c640abc716c08a4705dd68c1b0a4c25b354b9311d439","segment_id":"environment.md:f6b2ffe1d0d5f521","source_path":"environment.md","text_hash":"f6b2ffe1d0d5f521b76cabc67d6e96da2b1170eef8086d530558e9906a7f092d","text":"Models overview","translated":"模型 概述","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:41:44Z"} -{"cache_key":"dbec24d595565c4c294a91f556c491976ccdeb4f7976d9258e6420af47259608","segment_id":"help/index.md:24669ff48290c187","source_path":"help/index.md","text_hash":"24669ff48290c1875d8067bbd241e8a55444839747bffb8ab99f3a34ef248436","text":"Doctor","translated":"诊断","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:29Z"} -{"cache_key":"dbeeb5b2ad003e4152107ceade1290b2001163df5f2fb93a792c8c9d94cec345","segment_id":"start/getting-started.md:922f3f28b57bdd14","source_path":"start/getting-started.md","text_hash":"922f3f28b57bdd146b8892adf494a28a0969d5eaf21333bfdb314db2eb6c8da8","text":"Installer options (install method, non-interactive, from GitHub): ","translated":"安装选项(安装方式、非交互式、从 GitHub 安装): ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:48Z"} -{"cache_key":"dbf5bae2a9b91c346475334bdb1294ace20ee07ca1e471c488c5311579ef37ab","segment_id":"index.md:b0d125182029e6c5","source_path":"index.md","text_hash":"b0d125182029e6c500cbcc81011341df77de8fe24d9e80190c32be390c916ec2","text":"🤖 ","translated":"🤖 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:58Z"} -{"cache_key":"dc745b075f86ec95e5a22fbb2ba14c5a6f2c00911dfa570cbe2f5123627e887d","segment_id":"environment.md:f15f5f9f4ef4d668","source_path":"environment.md","text_hash":"f15f5f9f4ef4d6688876c894f8eba251ed1db6eaf2209084028d43c9e76a8ba1","text":" (aka ","translated":" (即 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:44Z"} -{"cache_key":"dc8c80f84e5339af07824daa81e39f2801c9d6beb851b21e632b3eb6ddf79749","segment_id":"start/wizard.md:4b2a013a2a09958e","source_path":"start/wizard.md","text_hash":"4b2a013a2a09958e251e8998bdfa5fd89cc1c69abb1273fe2c1522cf54363cc6","text":"JVM builds require ","translated":"JVM 构建需要 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:48:09Z"} -{"cache_key":"dcb357452715d4a3fee760c79dfdee6719f235e48d176456a053646ffae10f44","segment_id":"environment.md:d08a8493f686363a","source_path":"environment.md","text_hash":"d08a8493f686363a78b913d45ebfbd87a3768d1c77b70f23b1fdade3c066e481","text":"Shell env import","translated":"Shell 环境导入","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:04Z"} -{"cache_key":"dcde0de1d52251a80249b1dfaee7ed01776cefba6298068afc3f6c3d9cc5588a","segment_id":"index.md:9dea37e7f1ff0e24","source_path":"index.md","text_hash":"9dea37e7f1ff0e24f7daecf6ea9cc38a58194f11fbeab1d3cfaa3a5645099ef4","text":"Updating / rollback","translated":"更新 / 回滚","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:05Z"} -{"cache_key":"dd09aaae7520593f0b225738900febfd800584c0d3739ac738ad25471bbebd96","segment_id":"environment.md:32ebb1abcc1c601c","source_path":"environment.md","text_hash":"32ebb1abcc1c601ceb9c4e3c4faba0caa5b85bb98c4f1e6612c40faa528a91c9","text":" (","translated":" (","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:33Z"} -{"cache_key":"dd2638564931b358d794aeef59c89f44ebfb1a77fcb1cd80b46b517854fc66c5","segment_id":"environment.md:f15f5f9f4ef4d668","source_path":"environment.md","text_hash":"f15f5f9f4ef4d6688876c894f8eba251ed1db6eaf2209084028d43c9e76a8ba1","text":" (aka ","translated":" (即 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:12:15Z"} -{"cache_key":"dd36df20c6faba4d8a51480a0d3230e61b4dea629b8457271019bd76b56796bc","segment_id":"index.md:9182ff69cf35cb47","source_path":"index.md","text_hash":"9182ff69cf35cb477c02452600d23b52a49db7bd7c9833a9a8bc1dcd90c25812","text":"Node ≥ 22","translated":"Node ≥ 22","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:27Z"} -{"cache_key":"dd92326da2311615e4319e5c3a8fdb740de38c95fabe4004d5464423cc665458","segment_id":"index.md:4d87941d681ca4e8","source_path":"index.md","text_hash":"4d87941d681ca4e89ca303d033b7d383d3acfbb6d9d9616bd88d7c19cf92c3dd","text":"Pi","translated":"Pi","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:47:33Z"} -{"cache_key":"de23354a5644ee88dd6cda719c74f7e42f04f3b92a74eae6a035e39e3836505b","segment_id":"start/wizard.md:211b0693ae6d4a20","source_path":"start/wizard.md","text_hash":"211b0693ae6d4a20d6c1dc31c560b94a9c12096f0711c9c3a114f7be1eb2c606","text":"Installs optional dependencies (some use Homebrew on macOS).","translated":"安装可选依赖项(部分在 macOS 上使用 Homebrew)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:45:54Z"} -{"cache_key":"de45cbfead4c307b1c63c8e70a26ffd33d21776ae05b33f924b12b5f28ee26c6","segment_id":"environment.md:ffa63583dfa6706b","source_path":"environment.md","text_hash":"ffa63583dfa6706b87d284b86b0d693a161e4840aad2c5cf6b5d27c3b9621f7d","text":"missing","translated":"缺失的","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:26:14Z"} -{"cache_key":"de5171e4493a39e50904a36b6951113b6d2301d68f06d7baac75051365bf6e21","segment_id":"index.md:frontmatter:summary","source_path":"index.md:frontmatter:summary","text_hash":"891b2aa093410f546b89f8cf1aa2b477ba958c2c06d2ae772e126d49786df061","text":"Top-level overview of OpenClaw, features, and purpose","translated":"OpenClaw 的顶层概述、功能和用途","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:43Z"} -{"cache_key":"de705dea3105826091973569de591048ac987d5a188374ba4aa8fcb94ea10a10","segment_id":"index.md:65fd6e65268ff905","source_path":"index.md","text_hash":"65fd6e65268ff9057a49d832cccfcd5a376e46a908a2129be5b43f945fa8d8ca","text":": Gateway WS defaults to ","translated":":Gateway WS 默认为 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:03Z"} -{"cache_key":"deab7aa2d56c6fe242f6f04eef414a3fed9e1ac64374fcba6ed245d7b2733f6b","segment_id":"start/getting-started.md:e0626242c2ea510e","source_path":"start/getting-started.md","text_hash":"e0626242c2ea510e9457d6fb1b2848fe7091b10201c13d28c9774e6450ad28b2","text":": WhatsApp QR login, Telegram/Discord bot tokens, Mattermost plugin tokens, etc.","translated":":WhatsApp 二维码登录、Telegram/Discord 机器人令牌、Mattermost 插件令牌等。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:11Z"} -{"cache_key":"debd94851d1f9c8951da5858e545b056346bbc436ba2720f05f5260a5dd44a44","segment_id":"start/wizard.md:aa9e63906bb59344","source_path":"start/wizard.md","text_hash":"aa9e63906bb5934462d7a9f29afd4a9562d5366c583706512cb48dce19c847df","text":"Web tools","translated":"网页工具","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:27Z"} -{"cache_key":"dfa9d0ec2c6831536363b0e1eed21cd1626774a92d3de45da94e234fae5386d2","segment_id":"environment.md:d4a67341570f4656","source_path":"environment.md","text_hash":"d4a67341570f4656784c5f8fe1bfb48a738ace57b52544977431d50e2b718099","text":"FAQ: env vars and .env loading","translated":"常见问题:环境变量 和 .env 加载","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:41:42Z"} -{"cache_key":"e02de3fd6a9838fd351be176f196cbde274da86bff8be2e8b2303bf6790df0cb","segment_id":"start/getting-started.md:698ca3e004f541ad","source_path":"start/getting-started.md","text_hash":"698ca3e004f541ad543cc5f936c56142f246a15f22c6dd5c9c7afd95532583c6","text":"3.5) Quick verify (2 min)","translated":"3.5)快速验证(2 分钟)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:04Z"} -{"cache_key":"e04e0151c02320e186d2fd1b07d89104ddb194e3ae4971af4bd1f9f1710bad19","segment_id":"index.md:032f5589cfa2b449","source_path":"index.md","text_hash":"032f5589cfa2b44973fe96c42e17dcc2692281413a05b16f48ff0f958f7f7ade","text":"Discord Bot","translated":"Discord 机器人","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:04Z"} -{"cache_key":"e08315c1cc4da73870b3503c2ab91309c6687ee63c42656605372e35941f2bfd","segment_id":"index.md:74f99190ef66a7d5","source_path":"index.md","text_hash":"74f99190ef66a7d513049d31bafc76e05f9703f3320bf757fb2693447a48c25b","text":"Linux app","translated":"Linux 应用","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:53:43Z"} -{"cache_key":"e0893eb3c8cefa57f80842b1e6f91535ad0274b358f897d7bb69a01346be4a59","segment_id":"index.md:5eeecff4ba2df15c","source_path":"index.md","text_hash":"5eeecff4ba2df15c51bcc1ba70a5a2198fbcac141ebe047a2db7acf0e1e83450","text":" — Local UI + menu bar companion for ops and voice wake","translated":" — 本地界面 + 菜单栏辅助工具,用于操作和语音唤醒","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:02:33Z"} -{"cache_key":"e09e0f7a58717d8dd5e93c9405e9e7a87e99b23ed91d6f88fef646f8686c4c06","segment_id":"index.md:c7a5e268ddd8545e","source_path":"index.md","text_hash":"c7a5e268ddd8545e5a59a58ef1365189862f802cc7b61d4a3212c70565e2dff1","text":"WhatsApp Integration","translated":"WhatsApp 集成","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:26Z"} -{"cache_key":"e0a3b73e10d18fd81805c5666c076468ea1043dd951f611550833d143c7c86c7","segment_id":"environment.md:frontmatter:read_when:2","source_path":"environment.md:frontmatter:read_when:2","text_hash":"822b3d74ce16c1be19059fad4ca5bf7ae9327f58fa1ff4e75e78d5afa75c038f","text":"You are documenting provider auth or deployment environments","translated":"你正在记录提供商认证或部署环境","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:15Z"} -{"cache_key":"e0bae3d42ce06b6edf1f45f8f78cb8923b3cab4aa4c1e89ef2b78a6b8116bf98","segment_id":"environment.md:fb135d32fb09abb6","source_path":"environment.md","text_hash":"fb135d32fb09abb6844f68b8fdb5545a2929cbc0a980fd7e19fc1fcba4d8cb32","text":" (what the Gateway process already has from the parent","translated":" (Gateway 进程已从父级","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:36Z"} -{"cache_key":"e10ee0a761ae715ddd355ff5b07c6707d58a7c4aa3d27284863c46797dce8eb9","segment_id":"environment.md:668e5590b5bb9990","source_path":"environment.md","text_hash":"668e5590b5bb9990eeb25bf657f7d17281a4c613ee4442036787cd4b2efd22bb","text":"If the config file is missing entirely, step 4 is skipped; shell import still runs if enabled.","translated":"如果配置文件完全缺失,则跳过步骤 4;如果已启用,shell 导入仍会运行。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:26:05Z"} -{"cache_key":"e116abb724100f07db70423f94752290e45ae7e83fbbb522f560aa75f8827bf3","segment_id":"index.md:6fa3cbf451b2a1d5","source_path":"index.md","text_hash":"6fa3cbf451b2a1d54159d42c3ea5ab8725b0c8620d831f8c1602676b38ab00e6","text":"Sessions","translated":"会话","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:23Z"} -{"cache_key":"e1190c4a2612cc2cea5658f3b586bfab859bd0df7c15f12bc4be6d0657f84734","segment_id":"index.md:013e11a23ec9833f","source_path":"index.md","text_hash":"013e11a23ec9833f907b2ead492b0949015e25d10ba92461669609aee559335d","text":"Start here:","translated":"从这里开始:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:12Z"} -{"cache_key":"e1257e0dfdcc12dc7e241311ad2ab6bd8b89cc6ced9cda94ef01fc35920887b8","segment_id":"environment.md:cf3f9ba035da9f09","source_path":"environment.md","text_hash":"cf3f9ba035da9f09202ba669adca3109148811ef31d484cc2efa1ff50a1621b1","text":" (what the Gateway process already has from the parent shell/daemon).","translated":" (Gateway 进程已从父 shell/守护进程继承的值)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:29Z"} -{"cache_key":"e1d82e4a5f815268a0e65b21f1722eb4d465937ea4849a800bfacf6dc70869bf","segment_id":"environment.md:6d4090fbae05a048","source_path":"environment.md","text_hash":"6d4090fbae05a048bc57d06313e19799dd5d4b3c1d2a18c6eb745b3dd3442593","text":" equivalents:","translated":" 等效项:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:50Z"} -{"cache_key":"e1f970bed34760abb7d362cd2f7f4af368a2c76a63130e47fb36466f738231ec","segment_id":"index.md:1016b5bdce94a848","source_path":"index.md","text_hash":"1016b5bdce94a8484312c123416c1a18c29fab915ba2512155df3a82ee097f8f","text":"If the Gateway is running on the same computer, that link opens the browser Control UI\nimmediately. If it fails, start the Gateway first: ","translated":"如果 Gateway 运行在同一台计算机上,该链接会立即打开浏览器控制界面。如果无法打开,请先启动 Gateway: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:17Z"} -{"cache_key":"e288c66a34282338017002bdebb3d43b611e9268ee96a9a71377e27358f92a8d","segment_id":"start/wizard.md:0b7555ea7f832be2","source_path":"start/wizard.md","text_hash":"0b7555ea7f832be2c45b8912d6503cb867f500ab982c899ca3edf2bbd25da155","text":"Remote Gateway URL (","translated":"远程 Gateway URL(","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:46:18Z"} -{"cache_key":"e2a65642000db41fe132dae4ebaf8405dbcc8b607a6f85a2fe2b0ab89fc6113f","segment_id":"help/index.md:2adc964c084749b1","source_path":"help/index.md","text_hash":"2adc964c084749b1f2d8aef24030988b667dbda2e38a6a1699556c93e07c1cea","text":"Start here","translated":"从这里开始","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:15Z"} -{"cache_key":"e2be4f7a702604ffc4d6368630ac09d3dc83d72a7906b32ec1c6194d24768883","segment_id":"index.md:1cce617e15b49dca","source_path":"index.md","text_hash":"1cce617e15b49dca89b212bb5290edfcfee010ef2eeef369b36af78c53756e1c","text":" — Optional transcription hook","translated":" — 可选的转录钩子","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:46Z"} -{"cache_key":"e2bea8a812ba82ddc73f36802a93dadd6c4a0ab8d8c47a0b3959a2d3ac2e18e5","segment_id":"index.md:042c75df73389c8a","source_path":"index.md","text_hash":"042c75df73389c8a7c0871d2a451bd20431d24e908e2c192827a54022df95005","text":"Nacho Iacovino","translated":"Nacho Iacovino","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:06:25Z"} -{"cache_key":"e2f06db885ce6a775a64734d17016fb2c273cd62257def34b9ba0ca1a33a5b83","segment_id":"index.md:03279877bfe1de07","source_path":"index.md","text_hash":"03279877bfe1de0766393b51e69853dec7e95c287ef887d65d91c8bbe84ff9ff","text":"WebChat + macOS app","translated":"网页聊天 + macOS 应用","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:50Z"} -{"cache_key":"e3046cb9f63303cfbf56509890a29667276de5c6b954a6d62bfec56bbd2f5f6f","segment_id":"index.md:e47cdb55779aa06a","source_path":"index.md","text_hash":"e47cdb55779aa06a74ae994c998061bd9b7327f5f171c141caf2cf9f626bfe4b","text":"Peter Steinberger","translated":"Peter Steinberger","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:29Z"} -{"cache_key":"e355a25ce68c149fd415e9a5282ed06cf6d1b14a323d007e6e4bb63f516b63e2","segment_id":"start/wizard.md:frontmatter:read_when:0","source_path":"start/wizard.md:frontmatter:read_when:0","text_hash":"644fc34986851b3419d5dbb492d58c980aaef5ba5b75385e789421654bac2f0e","text":"Running or configuring the onboarding wizard","translated":"运行或配置上手引导向导","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:53Z"} -{"cache_key":"e35afed952675c044e4af3fb46f49fb19ffe702d850a44bd68d322846b87c3a8","segment_id":"index.md:2566561f81db7a7c","source_path":"index.md","text_hash":"2566561f81db7a7c4adb6cee3e93139155a6b01d52ff0d3d5c11648f46bc79bb","text":"📱 ","translated":"📱 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:49Z"} -{"cache_key":"e35cd8ef4c58d52ece200d844acc87c82675d4bfab5626181d5a19a80619121b","segment_id":"index.md:fdef9f917ee2f72f","source_path":"index.md","text_hash":"fdef9f917ee2f72fbd5c08b709272d28a2ae7ad8787c7d3b973063f0ebeeff7a","text":" to update the gateway service entrypoint.","translated":" 以更新网关服务入口点。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:32Z"} -{"cache_key":"e373ad3f709800b61550e436e63f2d836a6d8ef0d20d024a17c1e84979c3123b","segment_id":"start/getting-started.md:d7fc08e9364a1f77","source_path":"start/getting-started.md","text_hash":"d7fc08e9364a1f778246387363b55f32ca59ece0738ae543c994da0dab3dba09","text":"What you’ll choose:","translated":"您需要选择的内容:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:58Z"} -{"cache_key":"e47ee10a7f2c053bb20dc3cc1e1019c5043b6704d065442933270fd16de75cbc","segment_id":"index.md:774f1d6b2910de20","source_path":"index.md","text_hash":"774f1d6b2910de200115afec1bd87fe1ea6b0bc2142ac729e121e10a45df4b5d","text":" ← ","translated":" ← ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:03:52Z"} -{"cache_key":"e4d336ccc6430b7ad958c679f191372f6e1cd5ad513c5ce8f9b77cda4f2766e7","segment_id":"index.md:eec70d1d47ec5ac0","source_path":"index.md","text_hash":"eec70d1d47ec5ac00f04e59437e7d8b0988984c0cea3dddd81b1a2a10257960b","text":" — DMs + groups via grammY","translated":" —— 通过 grammY 支持私聊和群组","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:36Z"} -{"cache_key":"e51947f3a8d4e7ab79dc357deb1fcb7df73a48359733696bcd8ef64aaf7c4a45","segment_id":"index.md:297d5c673f5439aa","source_path":"index.md","text_hash":"297d5c673f5439aa31dca3bbc965cb657a89a643803997257defb3baef870f89","text":"Open the dashboard (local Gateway):","translated":"打开仪表板(本地 Gateway):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:19Z"} -{"cache_key":"e535ba32611dbfdfbdb030dbefbe4fa338d0de9c3dcf09e716b80b85ac6ec56e","segment_id":"start/getting-started.md:9995caf4a7d96e04","source_path":"start/getting-started.md","text_hash":"9995caf4a7d96e04d44f069d0e4b3ef3a2b210186fb92c3b1e846daf26b21a24","text":"macOS: if you plan to build the apps, install Xcode / CLT. For the CLI + gateway only, Node is enough.\nWindows: use ","translated":"macOS:如果您计划构建应用程序,请安装 Xcode / CLT。如果仅使用 CLI + Gateway,Node 就足够了。\nWindows:使用 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:38Z"} -{"cache_key":"e5714db86354a7868e7543683f77af47aa597f3bcddb61f46f2c313cb4cf8636","segment_id":"index.md:74926756385b8442","source_path":"index.md","text_hash":"74926756385b844294a215b2830576e3b2e93b84c5a8c8112b3816c5960f3022","text":" — DMs + guild channels via channels.discord.js","translated":" —— 通过 渠道.discord.js 支持私聊和服务器 渠道","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:43Z"} -{"cache_key":"e5857a240e24225783be67421286d47a4b18135d04c6f4f031e82d2a61cb02a3","segment_id":"index.md:f0e2018271f51504","source_path":"index.md","text_hash":"f0e2018271f515041084c8189f297236abe18f9ec77edad1a61c5413310bbd9e","text":"🖥️ ","translated":"🖥️ ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:02:28Z"} -{"cache_key":"e5a865669cc0d84b9b7f66db70c9b2536473891af6dc11f20fc3f7d5fccfceb6","segment_id":"environment.md:b4736422e64c0a36","source_path":"environment.md","text_hash":"b4736422e64c0a369663d1b2d386f1b8f4b31b8936b588e4a54453c61a24e0fd","text":"Process environment","translated":"进程环境","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:33Z"} -{"cache_key":"e5ab95a17152cbd3025b5413a5d7d8f0642fb9e3e3c72d241c7eec3e73b9104a","segment_id":"environment.md:7175517a370b5cd2","source_path":"environment.md","text_hash":"7175517a370b5cd2e664e3fd29c4ea9db5ce17058eb9772fe090a5485e49dad6","text":" or ","translated":" 或 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:39Z"} -{"cache_key":"e5b4eab0ca38617f4b76c99dc5fa36151812c02576b33f954a56cf5f77703696","segment_id":"index.md:bf0e823c81b87c5d","source_path":"index.md","text_hash":"bf0e823c81b87c5de79676155debf20a29b52d6d7eb7e77deda73a56d0afbaaa","text":"🧠 ","translated":"🧠 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:08Z"} -{"cache_key":"e5be378ff2d92da3de35b20680f90f5d1aa0a98ce205139d6fcaeac91ef06f65","segment_id":"index.md:9bcda844990ec646","source_path":"index.md","text_hash":"9bcda844990ec646b3b6ee63cbdf10f70b0403727dea3b5ab601ca55e3949db9","text":" for node WebViews; see ","translated":" 用于节点 WebView;参见 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:04Z"} -{"cache_key":"e5d655052f08f79672770734c9717dc24a5a9359defba7095dc7a9e2cf9e801b","segment_id":"start/wizard.md:bba52d8bacabbacc","source_path":"start/wizard.md","text_hash":"bba52d8bacabbacc510a1902b4eb35435f691903eb2db22fd110d41eadedec8d","text":" exists, the wizard can reuse it.","translated":" 存在,向导可以复用它。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:13Z"} -{"cache_key":"e628a7773be8d41e10dc53dcb383a11096e0573ec6b470aa13d2a14adcefb8e7","segment_id":"start/wizard.md:e3ba8a2959965f9c","source_path":"start/wizard.md","text_hash":"e3ba8a2959965f9c8360537e304016b2f75d561bdb03655a42adb02ce75a0e3f","text":"Default workspaces follow ","translated":"默认工作区遵循 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:46:57Z"} -{"cache_key":"e62ed5670f8283396dcc6a81182cda94667ff98973f153e4c86a04db364a4895","segment_id":"start/wizard.md:a8dbd136ed7c8e55","source_path":"start/wizard.md","text_hash":"a8dbd136ed7c8e55f9c0ae6e5acd2576d485f642d964a61f3693afc1c0c4ffdf","text":": uses ","translated":":使用 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:50Z"} -{"cache_key":"e66b34ec94f9a9c10b99b098ad8806551356222f1ac50f6fec7d719991faceee","segment_id":"start/wizard.md:c36d819e7bc6d2b7","source_path":"start/wizard.md","text_hash":"c36d819e7bc6d2b7da51394411c733db89c395987885ca6770167a3b9bc45c3c","text":"Use ","translated":"使用 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:46:45Z"} -{"cache_key":"e689f27ba4febf31a28a5b79eb2af514a15a3dff5dfe458bb3067cc59b2e7481","segment_id":"index.md:be48ae89c73a75da","source_path":"index.md","text_hash":"be48ae89c73a75da3454d565526d777938c20664618905a9bc77d6a0a21a689d","text":"\"EXFOLIATE! EXFOLIATE!\"","translated":"\"去角质!去角质!\"","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:47:25Z"} -{"cache_key":"e6b4ca13a3b7e39f521b1aadbb4f54f37875d228cd918c6406bd6519d5c7b6c8","segment_id":"index.md:6638cf2301d3109d","source_path":"index.md","text_hash":"6638cf2301d3109da66a44ee3506fbd35b29773fa4ca33ff35eb838c21609e19","text":"Features (high level)","translated":"功能特性(概览)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:26Z"} -{"cache_key":"e6e2a9985237253e0478229a54f3693bc7b0472bc450d53a4122dc20dfe08b21","segment_id":"environment.md:6863067eb0a2c749","source_path":"environment.md","text_hash":"6863067eb0a2c7499425c6c189b2c88bac55ca754285a6ab1ef37b75b4cfad4d","text":"See ","translated":"参见 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:22:37Z"} -{"cache_key":"e6e456289628d5a4b6cbbc0fbb263d656ba7d49427a2009ce3c5f608b8505ea0","segment_id":"index.md:f0d82ba647b4a33d","source_path":"index.md","text_hash":"f0d82ba647b4a33da3008927253f9bed21e380f54eab0608b1136de4cbff1286","text":"OpenClaw bridges WhatsApp (via WhatsApp Web / Baileys), Telegram (Bot API / grammY), Discord (Bot API / channels.discord.js), and iMessage (imsg CLI) to coding agents like ","translated":"OpenClaw 将 WhatsApp(通过 WhatsApp Web / Baileys)、Telegram(Bot API / grammY)、Discord(Bot API / channels.discord.js)和 iMessage(imsg CLI)桥接到编程 智能体,例如 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:56Z"} -{"cache_key":"e723a0b2ab360a74b84f4ccd08fdc4cc1639b85d5178d45d8103a18069bd3d8d","segment_id":"start/getting-started.md:1b59a1d9fa6d392f","source_path":"start/getting-started.md","text_hash":"1b59a1d9fa6d392f1f68642200583ed0f7b372af2fbc7c01d5f7f00463e229de","text":" also bundles A2UI assets; if you need to run just that step, use ","translated":" 也会打包 A2UI 资源;如果您只需要运行该步骤,请使用 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:51Z"} -{"cache_key":"e7279b78eeb5dccdf1897af612ce9f34bbae6f6ad7d8a7fed40a48f2f59c2367","segment_id":"environment.md:frontmatter:summary","source_path":"environment.md:frontmatter:summary","text_hash":"78351223e7068721146d2de022fdf440c2866b2ee02fbbb50bf64369b999820b","text":"Where OpenClaw loads environment variables and the precedence order","translated":"OpenClaw 加载环境变量的位置及优先级顺序","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:05Z"} -{"cache_key":"e73887cca1549bd1acf945a50dfbd054a3ec1c87741be5a0a4381a4840ce13e5","segment_id":"index.md:1df4f2299f0d9cc4","source_path":"index.md","text_hash":"1df4f2299f0d9cc466fa05abeb2831e76e9f89583228174ffcd9af415fd869fe","text":"Send a test message (requires a running Gateway):","translated":"发送测试消息(需要运行中的 Gateway):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:03:17Z"} -{"cache_key":"e747cc049257f34351f8e9510202e9a6f21541b6ab738d9c1e2aa1a41c519657","segment_id":"environment.md:cb133602d7dd4bc6","source_path":"environment.md","text_hash":"cb133602d7dd4bc6ecfe37a040de72b562547e609327bdd41ea294f9257b7248","text":" keys.","translated":" 密钥时应用。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:22Z"} -{"cache_key":"e758b5241da8091ae15d39a4bd67f4c86e9beb81d84def2a94118597695be1b4","segment_id":"index.md:42bb365211decccb","source_path":"index.md","text_hash":"42bb365211decccb3509f3bf8c4dfcb5ae05fe36dfdedb000cbf44e59e420dc9","text":" — Local imsg CLI integration (macOS)","translated":" — 本地 imsg CLI 集成(macOS)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:21Z"} -{"cache_key":"e7692faaf02464b2a4dd119d057cc5aced8c33764089e7974d2634ae997c09f2","segment_id":"environment.md:496aca80e4d8f29f","source_path":"environment.md","text_hash":"496aca80e4d8f29fb8e8cd816c3afb48d3f103970b3a2ee1600c08ca67326dee","text":" block","translated":" 块","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:22:11Z"} -{"cache_key":"e7bc8ffa042426610faa9c40c7191933bfda50deb769ef153580d4ab1c75d679","segment_id":"start/getting-started.md:cdb4ee2aea69cc6a","source_path":"start/getting-started.md","text_hash":"cdb4ee2aea69cc6a83331bbe96dc2caa9a299d21329efb0336fc02a82e1839a8","text":".","translated":"。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:45Z"} -{"cache_key":"e8160fc2a7763ac99c0933d4424a99f211b661b0d7649bb1d33f908c3ff5e0d2","segment_id":"start/getting-started.md:75e23f5184b23835","source_path":"start/getting-started.md","text_hash":"75e23f5184b23835efb6fdc64309312d3c9212d10566350b1a08ff7838c79d03","text":"2) Run the onboarding wizard (and install the service)","translated":"2)运行上手引导向导(并安装服务)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:35:55Z"} -{"cache_key":"e81fa8ea81e681a305d677a823722958c2fdf42c3afbf4149a2d5cdfc4c6e1df","segment_id":"index.md:4eb58187170dc141","source_path":"index.md","text_hash":"4eb58187170dc14198eacb534c8577bef076349c26f2479e1f6a2e31df8eb948","text":" — An AI, probably high on tokens","translated":" — 一个可能被令牌冲昏头脑的 AI","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:06:53Z"} -{"cache_key":"e87435d09fd52a520aeae4097eb83a149aeb498192ccfbdd63da8db57571de09","segment_id":"index.md:d08cec54f66c140c","source_path":"index.md","text_hash":"d08cec54f66c140c655a1631f6d629927c7c38b9c8bfa91c875df9bd3ad3c559","text":"OpenClaw assistant setup","translated":"OpenClaw 助手设置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:12Z"} -{"cache_key":"e8a313447619fd5d7895acf1c467e347d47a8c35861910facf5ff08f88a8905e","segment_id":"index.md:5928d14b4d45263d","source_path":"index.md","text_hash":"5928d14b4d45263d4964dfd301c84ed2674ca8b4b698c5efeb88fb86076d2bf9","text":"🎮 ","translated":"🎮 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:39Z"} -{"cache_key":"e8bfa9777ff1ca6f2921ef47688f6ddb7d1a68c074dc27c7af195521940fb68f","segment_id":"help/index.md:frontmatter:summary","source_path":"help/index.md:frontmatter:summary","text_hash":"aece82a2d540ab1a9a21c7b038127cae6e9db2149491564bb1856b6f8999f205","text":"Help hub: common fixes, install sanity, and where to look when something breaks","translated":"帮助中心:常见修复方法、安装完整性检查,以及出现问题时的排查指南","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:39:25Z"} -{"cache_key":"e8ee67c09bdbe71798a5c6348316e32fa4bf8cdf688a0fba4493ffc836a62fde","segment_id":"environment.md:c2d7247c8acb83a5","source_path":"environment.md","text_hash":"c2d7247c8acb83a5a020458fa836c2445922b51513dbdbf154ab5f7656cb04e9","text":"; does not override).","translated":";不会覆盖)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:44Z"} -{"cache_key":"e8fb144a38ce4b1553a092808d81c2faabee7f47fc5f950ff809998508ead2a9","segment_id":"environment.md:6db0742daaf9f191","source_path":"environment.md","text_hash":"6db0742daaf9f191ab7816d2c9d317b1ea1693453a8c63b95af8b01477e0f5bb","text":" runs your login shell and imports only ","translated":" 运行您的登录 shell 并仅导入 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:07Z"} -{"cache_key":"e9196b72990174331920ecd407ae4e20e96e67c7a2bd9e9deecdf9dda0a49b1e","segment_id":"index.md:c4b2896a2081395e","source_path":"index.md","text_hash":"c4b2896a2081395e282313d6683f07c81e3339ef8b9d2b5a299ea5b626a0998f","text":").","translated":")。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:34Z"} -{"cache_key":"e96f23e744751e56e76bb4914d500540aa9e7477681bf82acf3e8d249b7443e9","segment_id":"start/wizard.md:fda4a25e07825d0e","source_path":"start/wizard.md","text_hash":"fda4a25e07825d0e741782945be50a3bbf326b9403943ae322f9ff2c9d959a99","text":"QuickStart","translated":"快速入门","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:34Z"} -{"cache_key":"e974c0b5a54da233c9d3202030578368ed8f3ea979c5c958f879fcce408ef324","segment_id":"index.md:frontmatter:summary","source_path":"index.md:frontmatter:summary","text_hash":"891b2aa093410f546b89f8cf1aa2b477ba958c2c06d2ae772e126d49786df061","text":"Top-level overview of OpenClaw, features, and purpose","translated":"OpenClaw 的顶层概述、功能特性与用途","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:27:24Z"} -{"cache_key":"ea45ea5fb5edafd10885c5996709509fad9abd882c5daacc6f032e390b66c408","segment_id":"start/wizard.md:b1f78eea9ea563ca","source_path":"start/wizard.md","text_hash":"b1f78eea9ea563cab0611c9d9f74199e0f1dc1b7855a0f4e0eb8f4e0b9848b9e","text":"Add agent (non‑interactive) example:","translated":"添加智能体(非交互)示例:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:47:37Z"} -{"cache_key":"eacecaae490a307e52e287a93f22dd76cb2bab3c62c7d3e8e95480d7333a1d84","segment_id":"index.md:0eb95fb6244c03f1","source_path":"index.md","text_hash":"0eb95fb6244c03f1ccca696718a06766485c231347bf382424fb273145472355","text":"Quick start","translated":"快速入门","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:22Z"} -{"cache_key":"eaf2d170adde0688e23ca9cabb4074fdfbddd11f9e9327e51891878b361dfb2d","segment_id":"index.md:d372b90f0ccffad0","source_path":"index.md","text_hash":"d372b90f0ccffad0ae6e3df3c3aaeccd7a17eb59b4bc492a5469dc05ac3629ec","text":", OpenClaw uses the bundled Pi binary in RPC mode with per-sender sessions.","translated":",OpenClaw 将使用捆绑的 Pi 二进制文件以 RPC 模式运行,并使用每个发送者的 会话。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:03:33Z"} -{"cache_key":"eba13072b1a354b471f3da30934e0e7c51b0a4954b7b528817a8f20be0ec9c53","segment_id":"index.md:ceee4f2088b9d5ba","source_path":"index.md","text_hash":"ceee4f2088b9d5ba7d417bac7395003acfbcef576fd4cc1dd3063972f038218a","text":"The name","translated":"名称由来","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:16Z"} -{"cache_key":"ec2ec567c80acb4eaebb70c38df1d9ab94f68714cb99694d11d947a071edfdd4","segment_id":"start/wizard.md:3f485847642a332e","source_path":"start/wizard.md","text_hash":"3f485847642a332ed0374201686055314594de14929920d4c40d44676929d972","text":" to automate or script onboarding:","translated":" 用于自动化或脚本化上手引导:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:47:14Z"} -{"cache_key":"ec52d1059c9865c5fc3c2a42df8c7a6bf0a0b11707cd03f66a7767f8ea7eb532","segment_id":"environment.md:453c14128fbfb5f6","source_path":"environment.md","text_hash":"453c14128fbfb5f6757511557132a1dbb3bcbf243267630bfec49db8518c7780","text":"Env var substitution in config","translated":"配置中的环境变量替换","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:19:42Z"} -{"cache_key":"ec6203797e9e6d7c8b84dff668fa87d4f4e18e599a55a3e235a54bcfa85dcc08","segment_id":"environment.md:6db0742daaf9f191","source_path":"environment.md","text_hash":"6db0742daaf9f191ab7816d2c9d317b1ea1693453a8c63b95af8b01477e0f5bb","text":" runs your login shell and imports only ","translated":" 运行你的登录 shell 并仅导入 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:22:20Z"} -{"cache_key":"ec6544cf9a2fdf796cb6d3311bf84b9d9f4212fd4491ceb30cc7830f1bfe7024","segment_id":"help/index.md:b79cac926e0b2e34","source_path":"help/index.md","text_hash":"b79cac926e0b2e347e72cc91d5174037c9e17ae7733fd7bdb570f71b10cd7bfc","text":"Help","translated":"帮助","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:24:32Z"} -{"cache_key":"ec84b886dc2d0638c71fa040e38e36a5fa259ee781decdf9493570c2fec604fa","segment_id":"index.md:e9f63c8876aec738","source_path":"index.md","text_hash":"e9f63c8876aec7381ffb5a68efb39f50525f9fc4e732857488561516d47f5654","text":" — Uses Baileys for WhatsApp Web protocol","translated":" —— 使用 Baileys 实现 WhatsApp Web 协议","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:29Z"} -{"cache_key":"ec9e3eb6d2bd790ee1b161f31b6bb70649ee6b5df85dd2b6a0178ee01c443f69","segment_id":"start/wizard.md:61c5ae608ddc7474","source_path":"start/wizard.md","text_hash":"61c5ae608ddc7474cd3aadc92c22059f7a539eefb0a56b02f625c39e552ff7f7","text":"The wizard can install ","translated":"向导可以安装 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:47:51Z"} -{"cache_key":"eca7489e62538a4b68a7d49f3a67df1c6bad8affc75d6411f68ca1e81bef47b2","segment_id":"environment.md:f6b2ffe1d0d5f521","source_path":"environment.md","text_hash":"f6b2ffe1d0d5f521b76cabc67d6e96da2b1170eef8086d530558e9906a7f092d","text":"Models overview","translated":"模型概览","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:13:17Z"} -{"cache_key":"ecb4df64e132ff6212066948863adabaa06122c77d8971d5c924dc2e744df845","segment_id":"index.md:98a670e2fb754896","source_path":"index.md","text_hash":"98a670e2fb7548964e8b78b90fef47f679580423427bfd15e5869aca9681d0dd","text":"\"We're all just playing with our own prompts.\"","translated":"\"我们都只是在玩弄自己的提示词。\"","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:05:43Z"} -{"cache_key":"ecd894720faa37450014e0fe1630be8382cf6ec23cbb9bfe76bc4125495d8fa5","segment_id":"index.md:9adcfa4aa10a4e8b","source_path":"index.md","text_hash":"9adcfa4aa10a4e8b991a72ccc45261cd64f296aed5b257e4caf9c87aff1290a0","text":" — Send and receive images, audio, documents","translated":" — 收发图片、音频、文档","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:38Z"} -{"cache_key":"ed10c233aa195883b17061f166f647efac5a27535a85ce4d16fc90d40e138882","segment_id":"help/index.md:8cd501e1124c3047","source_path":"help/index.md","text_hash":"8cd501e1124c30473473c06e536a2d145e2a14a6d7dc1b99028ce818e14442e2","text":"Repairs:","translated":"修复:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:39:56Z"} -{"cache_key":"ed15427258ffbf85620a0c9c0c42deb7f37be17b7abeff5993a34962964f0e96","segment_id":"index.md:a194ca16424ddd17","source_path":"index.md","text_hash":"a194ca16424ddd17dacc45f1cbd7d0e41376d8955a7b6d02bc38c295cedd04e4","text":"RPC adapters","translated":"RPC 适配器","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:19Z"} -{"cache_key":"ed24753e60b54d629cfd978be87185f4772676322534432302319caf28452d29","segment_id":"index.md:ab201ddd7ab330d0","source_path":"index.md","text_hash":"ab201ddd7ab330d04be364c0ac14ce68c52073a0ee8d164a98c3034e91ce1848","text":" from the repo.","translated":" (在仓库目录中执行)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:21Z"} -{"cache_key":"ed37a2b1a8c3351a6c04bee81df6f507f306be344485e69eb87b3b2451aad89f","segment_id":"help/index.md:d3ef01b4a9c99103","source_path":"help/index.md","text_hash":"d3ef01b4a9c9910364c9b26b2499c8787a0461d2d24ab80376fff736a288b34c","text":"Logging","translated":"日志记录","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:24:47Z"} -{"cache_key":"ee3f1647acf674397ba7f7e1aee0f9972b9830f978b622695d8ab5360de5a496","segment_id":"index.md:255ce77b7a6a015f","source_path":"index.md","text_hash":"255ce77b7a6a015f8595868a524b67c134e8fb405f4584fdac020e57f4ccd5f6","text":"Loopback-first","translated":"回环优先","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:01Z"} -{"cache_key":"ee582fba5363de60fb2c00f9238f2ac9ad6dc7615694d8d23d24d88bf7ec13e1","segment_id":"environment.md:582967534d0f909d","source_path":"environment.md","text_hash":"582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf","text":" in ","translated":" 在 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:29Z"} -{"cache_key":"eead1cfedffdef3e1e7e8bfc6339df973b1390f8cd648602a62448762b8963f4","segment_id":"start/wizard.md:15836cbac4abdca3","source_path":"start/wizard.md","text_hash":"15836cbac4abdca3c78de3c3470fdc7bea9a96d0f38a1d0e4ec941bfc18ecb26","text":"Config only","translated":"仅配置","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:41:30Z"} -{"cache_key":"eeebff3da1cf246a7ee248bd8bc9694ee3d98c0f3fe5a0dcbfefa5e252b113a2","segment_id":"index.md:c3af076f92c5ed8d","source_path":"index.md","text_hash":"c3af076f92c5ed8dcb0d0b0d36dd120bc31b68264efea96cf8019ca19f1c13a3","text":"Troubleshooting","translated":"故障排除","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:05:33Z"} -{"cache_key":"eeef5f9dd1ae51906bf8d4a97c86db5d9327f00c8117da5fe2276a1ac1b155f4","segment_id":"help/index.md:156597e2632411d1","source_path":"help/index.md","text_hash":"156597e2632411d1d5f634db15004072607ba45072a4e17dfa51790a37b6781f","text":"Gateway issues:","translated":"Gateway 问题:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:24:43Z"} -{"cache_key":"ef28fdc07b59ec5ce5915e3de7389d8d70ecb8ed31445ed4066d7118fe6dd63e","segment_id":"environment.md:6f59001999ef7b71","source_path":"environment.md","text_hash":"6f59001999ef7b7128bab80d2034c419f3034497e05f69fbdf67f7b655cdc173","text":"Configuration: Env var substitution","translated":"配置:环境变量 替换","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:41:33Z"} -{"cache_key":"ef3b396216400003eb534a0ab4fe41ae559b2fb39623ec3e2f9892c4f4cba9ef","segment_id":"index.md:ec05222b3777fd7f","source_path":"index.md","text_hash":"ec05222b3777fd7f91a2964132f05e3cfc75777eaeec6f06a9a5c9c34a8fc3e9","text":"Nix mode","translated":"Nix 模式","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:04:10Z"} -{"cache_key":"ef7f4605237a606f565a596c39809fa969774059be148db688b808634350bf09","segment_id":"index.md:5928d14b4d45263d","source_path":"index.md","text_hash":"5928d14b4d45263d4964dfd301c84ed2674ca8b4b698c5efeb88fb86076d2bf9","text":"🎮 ","translated":"🎮 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:38Z"} -{"cache_key":"efa246765d696f04600590562765687bb4f5fefce8a4df66bc2cbe3275f3f43e","segment_id":"start/wizard.md:426263b5cd4ab1f3","source_path":"start/wizard.md","text_hash":"426263b5cd4ab1f3211193944727955444c6454a1640bec5e6f35b017c6d285f","text":"Non‑loopback binds still require auth.","translated":"非回环绑定仍需认证。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:44:08Z"} -{"cache_key":"efd8767a5fede85377af51202b1450a0f73054f978162c2d8bcef5dfa6220323","segment_id":"start/getting-started.md:e67454c1b6dd66c2","source_path":"start/getting-started.md","text_hash":"e67454c1b6dd66c2f006a8a98ff9c6a1279f8283eab3a272c15436f164cefe7b","text":"Recommended path: use the ","translated":"推荐路径:使用 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:46Z"} -{"cache_key":"effbe87506ca4373185a6bd9eb8262362bc299b5fbd8da0ce76b0aa8fe73ff1d","segment_id":"environment.md:a258b30f88c30650","source_path":"environment.md","text_hash":"a258b30f88c30650e73073d5bdde5cfcc6987100ae62d37789e5c46a0d85b7c6","text":"Global ","translated":"全局 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:36Z"} -{"cache_key":"f02f949874120a6c5b691141073ad6c170eaa88039cdad423e870a2753e957b3","segment_id":"start/getting-started.md:caf33dca8b21dc18","source_path":"start/getting-started.md","text_hash":"caf33dca8b21dc18f96b1f009b0dba4d75ddc00ea245972e98d56b1d1a5a009d","text":"Mattermost (plugin): ","translated":"Mattermost(插件): ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:28Z"} -{"cache_key":"f04ed463aa434ea141889ce238029572813914c69789bd6fb5eacba8423f5768","segment_id":"help/index.md:frontmatter:read_when:0","source_path":"help/index.md:frontmatter:read_when:0","text_hash":"ee0615553374970664b58ebd8e5d0ebc9bc8a5f03387671afbfd0096b390aa9b","text":"You’re new and want the “what do I click/run” guide","translated":"你是新手,想要一份\"我该点击/运行什么\"的指南","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:44:25Z"} -{"cache_key":"f0bc0a82d8a06b403ce5154b870a817a8097bacdb2e4fe64ab876d6f084f389c","segment_id":"index.md:d372b90f0ccffad0","source_path":"index.md","text_hash":"d372b90f0ccffad0ae6e3df3c3aaeccd7a17eb59b4bc492a5469dc05ac3629ec","text":", OpenClaw uses the bundled Pi binary in RPC mode with per-sender sessions.","translated":",OpenClaw 将使用内置的 Pi 二进制文件以 RPC 模式运行,并为每个发送者提供 会话。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:58Z"} -{"cache_key":"f11584b1b8bb57dbe543960af7b37e9ff6fb5eab1a8da25c423f5780dd0d676c","segment_id":"start/getting-started.md:ab744fe26b887abd","source_path":"start/getting-started.md","text_hash":"ab744fe26b887abdb3558472d5bfe074f2716bbd88c8fab2b86bc745cbe7cf52","text":"Tip: ","translated":"提示: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:07Z"} -{"cache_key":"f16eb7fed19f8561d7438f4379417058d14d6effa70a7e8ab163a2c08e69b70f","segment_id":"start/wizard.md:8ef5034a90ff178a","source_path":"start/wizard.md","text_hash":"8ef5034a90ff178aded1c6f9898a864b8af345b28b62274e520c62e4bc44dec8","text":"Native builds are used when available.","translated":"如有原生构建则优先使用。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:48:15Z"} -{"cache_key":"f18978cae4cb765c8959cd68c4897fde778c8cece0f3e6a778e862fc767efebe","segment_id":"index.md:013e11a23ec9833f","source_path":"index.md","text_hash":"013e11a23ec9833f907b2ead492b0949015e25d10ba92461669609aee559335d","text":"Start here:","translated":"从这里开始:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:03:44Z"} -{"cache_key":"f1bf5865e234c088f292333d3304a20f3b9b69544d67f32494540f263fa1e1cc","segment_id":"index.md:2adc964c084749b1","source_path":"index.md","text_hash":"2adc964c084749b1f2d8aef24030988b667dbda2e38a6a1699556c93e07c1cea","text":"Start here","translated":"从这里开始","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:47:39Z"} -{"cache_key":"f1f9640f4e20ead3c4890cd38fa2d2f83e102d190c71f31bf74e43411b220707","segment_id":"environment.md:3527b238ea049608","source_path":"environment.md","text_hash":"3527b238ea04960811e4f77378c46a6cddaf9dbf907d8affb0974772028b269e","text":"If the config file is missing entirely, step 4 is skipped; shell import still runs if","translated":"如果配置文件完全缺失,则跳过第 4 步;如果","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:46:24Z"} -{"cache_key":"f2078834885c634ec26e8903f4ed129d2fa2611d43b07c1b65d99b4207dd3f17","segment_id":"index.md:cdb4ee2aea69cc6a","source_path":"index.md","text_hash":"cdb4ee2aea69cc6a83331bbe96dc2caa9a299d21329efb0336fc02a82e1839a8","text":".","translated":"。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:28Z"} -{"cache_key":"f218922442b56c5e09b8f23fab26599a3631012ca6e296456125326f409f1f7e","segment_id":"help/index.md:cad44fbae951d379","source_path":"help/index.md","text_hash":"cad44fbae951d3791565b0cee788c01c3bd10e0176167acb691b8dba0f7895f8","text":"Gateway logging","translated":"Gateway 日志记录","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:56:40Z"} -{"cache_key":"f22c948c8f08bba03ae5ab9b17be95ed84ed98de50cbcbea09d5812b3d9fd4e1","segment_id":"start/wizard.md:7c2a0a6b7bb37dc2","source_path":"start/wizard.md","text_hash":"7c2a0a6b7bb37dc269429103bc13c5f5172b11631d7d44e84e0d5e4881354e4f","text":" works without a key). Easiest path: ","translated":" 无需密钥也可使用)。最简单的方式: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:39:21Z"} -{"cache_key":"f23e602e5722bcb75d4969fec8ae88209555d9f30e4cc863e54cb0665c150f93","segment_id":"index.md:e3572f8733529fd3","source_path":"index.md","text_hash":"e3572f8733529fd30a8604d41d624c15f4433df68f40bd092d1ee61f7d8d15e2","text":"Agent bridge","translated":"智能体桥接","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:57Z"} -{"cache_key":"f258e8524ff328198c2d9437453a1d91d940664b2f522b1ec9ac79b0139fc660","segment_id":"start/wizard.md:54ec12801f42e556","source_path":"start/wizard.md","text_hash":"54ec12801f42e5568f617d1aad18c458515c72920de170a24ef0f2be60cd3d33","text":"Moonshot AI (Kimi + Kimi Coding)","translated":"Moonshot AI (Kimi + Kimi Coding)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:13Z"} -{"cache_key":"f25bc202081adc9aa4d305452fe50f1a9c63b9077c112ebdc0d9166737b3675a","segment_id":"index.md:99260acc29f71e4b","source_path":"index.md","text_hash":"99260acc29f71e4baeb36805a1fdbd2c17254b57c8e5a9cba29ee56518832397","text":" — Route provider accounts/peers to isolated agents (workspace + per-agent sessions)","translated":" — 将 提供商 账户/对等方路由到隔离的 智能体(工作区 + 每个 智能体 的 会话)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:46Z"} -{"cache_key":"f2a0941718593a4be66a7a033a4117a7b3a502ef64b25fd7d6d3475c77dd5a1a","segment_id":"environment.md:87e89abb4c1c551f","source_path":"environment.md","text_hash":"87e89abb4c1c551fe08d355d097f18b8de78edca5f556997085681662fce8eed","text":"Config ","translated":"配置 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:24Z"} -{"cache_key":"f2a0c70d8b9f94722b586320f11c58339d30dd1fe8ff7250a962bb2db84d5ab4","segment_id":"environment.md:ffa63583dfa6706b","source_path":"environment.md","text_hash":"ffa63583dfa6706b87d284b86b0d693a161e4840aad2c5cf6b5d27c3b9621f7d","text":"missing","translated":"缺失的","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:09Z"} -{"cache_key":"f2c14989f888bbff9c7330f2d5b3892af3b900910840435595031590dc8248e3","segment_id":"environment.md:frontmatter:read_when:0","source_path":"environment.md:frontmatter:read_when:0","text_hash":"90fc0487bff88009979cff1061c1a882df8c3b1baa9c43538331d9d5dab15479","text":"You need to know which env vars are loaded, and in what order","translated":"你需要了解加载了哪些环境变量,以及它们的加载顺序","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:47Z"} -{"cache_key":"f34789e2cb492196e8c057294dd98c5f9d4b8054d548a7b883a47f113efa1277","segment_id":"index.md:31365ab9453d6a1e","source_path":"index.md","text_hash":"31365ab9453d6a1ec03731622803d3b44f345b6afad08040d7f3e97290c77913","text":"do nothing","translated":"不做任何操作","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:55Z"} -{"cache_key":"f36f13a67a73f6768bfbf346d552067475ef4f8137e13edfd4f636e1b7ef2ef8","segment_id":"start/getting-started.md:649cfa2f76a80b42","source_path":"start/getting-started.md","text_hash":"649cfa2f76a80b42e1821c89edd348794689409dcdf619dcd10624fb577c676b","text":"not recommended","translated":"不推荐","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:36:21Z"} -{"cache_key":"f3701b1ce8ac7f8931cafd209250aa5ae388ecfdb0154dbbb21c03fd72ce5d08","segment_id":"help/index.md:729bc562eec2658b","source_path":"help/index.md","text_hash":"729bc562eec2658bd11ffdd522fe5277177dc73e86eaca7baac0b472a4d8f8b2","text":"If you’re looking for conceptual questions (not “something broke”):","translated":"如果你在寻找概念性问题(不是\"某个东西坏了\"):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:11:29Z"} -{"cache_key":"f37dcde1b1a3572f2e12cec637bb9435d7594f5d680ca4c8d2916587ceaa5b49","segment_id":"environment.md:baa5be7f6320780b","source_path":"environment.md","text_hash":"baa5be7f6320780bd7bb7b7ddbb8cd1ffb26ccf7d94d363350668c50aedcf95f","text":" (applied only if missing).","translated":" (仅在缺失时应用)。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:32Z"} -{"cache_key":"f3bae8376433842a2647a0f99681be1ae704993131bd626b47c7ead29db85121","segment_id":"index.md:41ed52921661c7f0","source_path":"index.md","text_hash":"41ed52921661c7f0d68d92511589cc9d7aaeab2b5db49fb27f0be336cbfdb7df","text":"Gateway","translated":"Gateway","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:48:23Z"} -{"cache_key":"f3d666bd4b1803904177f2fd15477daab9b1988d37873a621ff0ff20fc67430a","segment_id":"index.md:32ebb1abcc1c601c","source_path":"index.md","text_hash":"32ebb1abcc1c601ceb9c4e3c4faba0caa5b85bb98c4f1e6612c40faa528a91c9","text":" (","translated":" (","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:47:51Z"} -{"cache_key":"f44674e6fe8bdf7df11beea733dc32ed87d3f98aa27ab39d91af414342ea24ac","segment_id":"environment.md:frontmatter:read_when:1","source_path":"environment.md:frontmatter:read_when:1","text_hash":"a3a2d99a99de98220c8e0296d6f4e4b2a34024916bd2379d1b3b9179c8fae46f","text":"You are debugging missing API keys in the Gateway","translated":"你正在调试 Gateway 中缺失的 API 密钥","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:49Z"} -{"cache_key":"f4572fb2d4379ec9633f4e503fc4ffe1b6e5d42baf75386b995e4453a220112f","segment_id":"start/wizard.md:5c237035504bf1d8","source_path":"start/wizard.md","text_hash":"5c237035504bf1d829557c9f34d581e874170d29eb78178780d9de279686878b","text":": service account JSON + webhook audience.","translated":":服务账户 JSON + webhook 受众。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:44:37Z"} -{"cache_key":"f4b0c2b320a173553e165db9e33134bd687611509a67f872b3802da035e18003","segment_id":"start/wizard.md:c47c637c5420619c","source_path":"start/wizard.md","text_hash":"c47c637c5420619cf8a485038799bbf646ac4dd9fb434e4da93e49276e6c63cf","text":"Linux: Avahi (","translated":"Linux:Avahi(","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:46:39Z"} -{"cache_key":"f4b8ff8f3efbd8ee938358900957557c4222b284b44d2a7048b9d12bafcaccb3","segment_id":"environment.md:frontmatter:read_when:2","source_path":"environment.md:frontmatter:read_when:2","text_hash":"822b3d74ce16c1be19059fad4ca5bf7ae9327f58fa1ff4e75e78d5afa75c038f","text":"You are documenting provider auth or deployment environments","translated":"你正在记录提供商认证或部署环境的文档","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:12Z"} -{"cache_key":"f4bde41e2630aeb2a70bf71ad4d202512d708d38dd36418cd9ac8d4332cd2359","segment_id":"index.md:add4778f9e60899d","source_path":"index.md","text_hash":"add4778f9e60899d7f44218483498c0baf7a0468154bc593a60747ee769c718c","text":"Android node","translated":"Android 节点","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:59Z"} -{"cache_key":"f52a9c7d0d2374d22023815ee71b9d667d1f40014d21c495be00062bb7ff7e9d","segment_id":"start/wizard.md:9349cb3da677e30e","source_path":"start/wizard.md","text_hash":"9349cb3da677e30edeeea7e42cf0ef9b5bcbb063c2c1e11e4805728cfb809b27","text":"Auth recommendation: keep ","translated":"认证建议:保持 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:59Z"} -{"cache_key":"f560e7bf274a11b63b63dfc2b1e34b5d4f767099b60c828981323400825310c0","segment_id":"index.md:83f4fc80f6b452f7","source_path":"index.md","text_hash":"83f4fc80f6b452f7cdf426f6b87f08346d7a2d9c74a0fb62815dce2bfddacf63","text":" — A space lobster, probably","translated":" — 大概是一只太空龙虾说的","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:27:52Z"} -{"cache_key":"f5ce8d582224799c2c298caa9a9f7dfb7d86186f570cfddd641946668d1d13da","segment_id":"index.md:79a482cf546c23b0","source_path":"index.md","text_hash":"79a482cf546c23b04cd48a33d4ca8411f62e5b7dc8c3a8f30165e28e747f263a","text":"iMessage","translated":"iMessage","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:29:51Z"} -{"cache_key":"f5fa9cda34fd26fb939c24c123c64b46dd61b92c355cd4a750f394defd4a695c","segment_id":"index.md:2adc964c084749b1","source_path":"index.md","text_hash":"2adc964c084749b1f2d8aef24030988b667dbda2e38a6a1699556c93e07c1cea","text":"Start here","translated":"从这里开始","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:00Z"} -{"cache_key":"f5ffb1cdcefe6f0cd2d2b69e0756d6cc01a9c6a0e02b454f0e30b38b6ad7b2e2","segment_id":"index.md:723fad6d27da9393","source_path":"index.md","text_hash":"723fad6d27da939353c65417bbaf646b65903b316eb4456297ff4a1c20811e8d","text":": HTTP file server on ","translated":":HTTP 文件服务器位于 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:20Z"} -{"cache_key":"f60fee3592c356f74a3be54ab30e9b0a0715eb1a3bbf7e17b0f99aa6f3d33df7","segment_id":"environment.md:3f52403cd330847b","source_path":"environment.md","text_hash":"3f52403cd330847bbe6aabe3d447592616cdc1a8efcbc1f48fb6643f8384fe96","text":"Precedence (highest →","translated":"优先级(最高 →","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:28Z"} -{"cache_key":"f621705327b389ad82a822a75b8c7ca9f3373484abe4c0fa698439958d39456d","segment_id":"environment.md:6f59001999ef7b71","source_path":"environment.md","text_hash":"6f59001999ef7b7128bab80d2034c419f3034497e05f69fbdf67f7b655cdc173","text":"Configuration: Env var substitution","translated":"配置:环境变量 替换","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:58:25Z"} -{"cache_key":"f621dff6a1a64fd61fe1f234bee676aeae91455321dcee4f6e67091184df6c62","segment_id":"start/wizard.md:66d0f523a379b2de","source_path":"start/wizard.md","text_hash":"66d0f523a379b2de6f8d5fba3a817ebc395f7bcaa54cc132ca9dfa665d1e9378","text":"Skills","translated":"技能","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:49:18Z"} -{"cache_key":"f63fecf5eae55dcc313461e84c71dff7e4c62437c912b31e37160ab24e814c22","segment_id":"index.md:9dea37e7f1ff0e24","source_path":"index.md","text_hash":"9dea37e7f1ff0e24f7daecf6ea9cc38a58194f11fbeab1d3cfaa3a5645099ef4","text":"Updating / rollback","translated":"更新 / 回滚","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:31Z"} -{"cache_key":"f6b24d421bb819dd74d316c3be99e4848a1b48cd29aa83b5955b323ccf7a6c71","segment_id":"help/index.md:d3ef01b4a9c99103","source_path":"help/index.md","text_hash":"d3ef01b4a9c9910364c9b26b2499c8787a0461d2d24ab80376fff736a288b34c","text":"Logging","translated":"日志记录","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:56:33Z"} -{"cache_key":"f6bca6b4934d23476401fd77c2d68803d43a4cc7147a31663887d519bebad085","segment_id":"index.md:7af023c43013b9a5","source_path":"index.md","text_hash":"7af023c43013b9a53fbff7dd4b5821588bba3319308878229740489152c43f6d","text":"Docs","translated":"文档","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:31:46Z"} -{"cache_key":"f6bf8734b049080c670e9161d3f62cff12800947ad422096af488dda32c63f66","segment_id":"index.md:5eeecff4ba2df15c","source_path":"index.md","text_hash":"5eeecff4ba2df15c51bcc1ba70a5a2198fbcac141ebe047a2db7acf0e1e83450","text":" — Local UI + menu bar companion for ops and voice wake","translated":" — 本地界面 + 菜单栏辅助工具,支持操作和语音唤醒","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:30:54Z"} -{"cache_key":"f6cb43180d1cb38f88fcf0a8d2c978f67c90b54bde664ec85ac14abce14c1b83","segment_id":"help/index.md:8ddb7fc8a87904de","source_path":"help/index.md","text_hash":"8ddb7fc8a87904dedc2afc16400fbe4e78582b302e01c30b1319c8a465d04684","text":"Troubleshooting:","translated":"故障排除:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:39:35Z"} -{"cache_key":"f6f420edf7e69a495fa2341fbcbfcb89f4edd0193ad98bca1bf5bd34822e6914","segment_id":"index.md:316cd41f595f3095","source_path":"index.md","text_hash":"316cd41f595f3095f149f98af70f77ab85404307a1505467ee45a26b316a9984","text":"Guided setup (recommended):","translated":"引导式设置(推荐):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:59:10Z"} -{"cache_key":"f7109a2845e6fbe35c8bdf279b2c337808867d39dd637a5c7d9b2a1b91018916","segment_id":"start/getting-started.md:d48b35a5fde42ec0","source_path":"start/getting-started.md","text_hash":"d48b35a5fde42ec00cf04a49d5ddeb555c65a520eeb97108da303bc05673dc84","text":"WhatsApp doc: ","translated":"WhatsApp 文档: ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:12Z"} -{"cache_key":"f722cbdc201f4b5e079dd175c0f52bce3bf3aa1658174683d7b51d71a4e9cd84","segment_id":"index.md:6b8ebac7903757ce","source_path":"index.md","text_hash":"6b8ebac7903757ce7399cc729651a27e459903c24c64aa94827b20d8a2a411d2","text":"For Tailnet access, run ","translated":"如需 Tailnet 访问,请运行 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:28:53Z"} -{"cache_key":"f727381238c5d317e8cd685354a48f793bc0d76af5f89de378ced4f0307c043d","segment_id":"start/wizard.md:3dd83b614e806664","source_path":"start/wizard.md","text_hash":"3dd83b614e8066647eed34747cca7bd8ecd848f994ab0e1870611515a0947051","text":"macOS: Bonjour (","translated":"macOS:Bonjour(","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:46:36Z"} -{"cache_key":"f75c83d90f9118aeb4862c47a07a5896f5da054fa28cebd9a9770f2bd5fcbe1c","segment_id":"start/wizard.md:e7ac0786668e0ff0","source_path":"start/wizard.md","text_hash":"e7ac0786668e0ff0f02b62bd04f45ff636fd82db63b1104601c975dc005f3a67","text":":","translated":":","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:48:30Z"} -{"cache_key":"f76e7b041b6273a09aa1e9309c09963be833cac5d00695ee47013a664b4d68d7","segment_id":"help/index.md:frontmatter:read_when:0","source_path":"help/index.md:frontmatter:read_when:0","text_hash":"ee0615553374970664b58ebd8e5d0ebc9bc8a5f03387671afbfd0096b390aa9b","text":"You’re new and want the “what do I click/run” guide","translated":"你是新手,想要一份\"我该点击/运行什么\"的指南","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:18:57Z"} -{"cache_key":"f794b56056508717fd48cd6db6dc75a458a0fa23834757f5ab7a0993982c6594","segment_id":"environment.md:496aca80e4d8f29f","source_path":"environment.md","text_hash":"496aca80e4d8f29fb8e8cd816c3afb48d3f103970b3a2ee1600c08ca67326dee","text":" block","translated":" 块","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:59Z"} -{"cache_key":"f80879a2302c298e8c95d914d9d6c71f03acd6f6dd6f974af01bfc0bc6c2e1c5","segment_id":"start/wizard.md:b90faf89583190c7","source_path":"start/wizard.md","text_hash":"b90faf89583190c7e34f7f5da172378019ea35b5da533c04dd2f7eec4c22eb9b","text":"Add another agent","translated":"添加另一个智能体","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:46:43Z"} -{"cache_key":"f8ba17c2741fd5744982e25324fa40baf96c8bc58d317be0648263b55a430f7e","segment_id":"index.md:76d6f9c532961885","source_path":"index.md","text_hash":"76d6f9c5329618856f133dc695e78f085545ae05fae74228fb1135cba7009fca","text":") — Pi creator, security pen-tester","translated":")—— Pi 创建者,安全渗透测试员","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:54:30Z"} -{"cache_key":"f9105824cf6a7d20518e37b8bf0823c644d1c0f6ce291e122a94e6e6470b7533","segment_id":"index.md:898e28d91a14b400","source_path":"index.md","text_hash":"898e28d91a14b400e7dc11f9dc861afe9143c18bf9424b1d1b274841615f38b1","text":"If you want to lock it down, start with ","translated":"如果您想进行锁定配置,请从以下内容开始 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:00Z"} -{"cache_key":"f91d9117f2bb9b64cf66ea1411b0be3f171f40e08c8c9e9f26c55c7e8bfe7189","segment_id":"environment.md:6863067eb0a2c749","source_path":"environment.md","text_hash":"6863067eb0a2c7499425c6c189b2c88bac55ca754285a6ab1ef37b75b4cfad4d","text":"See ","translated":"参见 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:26:28Z"} -{"cache_key":"f94a81f9b0bf40ffe1357c455d8aa1521caf2e5b7567514ceebb6cddac71ed20","segment_id":"start/wizard.md:812ae9cc61bc8004","source_path":"start/wizard.md","text_hash":"812ae9cc61bc800431e08012a3e2dedf0f928f6f5d1266663f3f9c9009a33865","text":"What the wizard writes","translated":"向导写入的内容","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:48:22Z"} -{"cache_key":"f9d9e2053d57e1dbcea8393af82dbd0d30bed4822f1d89bfe03c7cfadb02ecd7","segment_id":"environment.md:8d076464a84995bc","source_path":"environment.md","text_hash":"8d076464a84995bc095e934b0aa1e4419372f27cd71d033571e4dbba201ee5d8","text":"You can reference env vars directly in config string values using ","translated":"你可以在配置的字符串值中直接引用环境变量,使用 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:26:23Z"} -{"cache_key":"f9f5b27505056942f667c21acc05200a9acbbdcb3fddaceca9d2a30e2dbe81a9","segment_id":"index.md:b214cd10585678ca","source_path":"index.md","text_hash":"b214cd10585678ca1250ce1ae1a50ad4001de4577a10e36be396a3409314e442","text":"@badlogicc","translated":"@badlogicc","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:38Z"} -{"cache_key":"fa024aedd372ab7765061298a10db13f4e5bcdc6133bc25a65c53f8236557315","segment_id":"environment.md:907940a35852447a","source_path":"environment.md","text_hash":"907940a35852447aad5f21c5a180d993ff31cfd5807b1352ed0c24eabe183465","text":"never override existing values","translated":"永远不要覆盖现有值","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T11:45:24Z"} -{"cache_key":"fa3713ea436d20ec73664c073e488b38fc0bb3809eaa3ac4dc08811132bee115","segment_id":"index.md:5afbb1c887f6d850","source_path":"index.md","text_hash":"5afbb1c887f6d8501dba36cd2113d8f8b6ce6fa711a0d3e7efdc66f170abd2c2","text":"Cron jobs","translated":"定时任务","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:33:06Z"} -{"cache_key":"fa78bcdd35b740179d777f1399ca259d74e49151d5fe68ebcb2e8e073e5cacbd","segment_id":"environment.md:582967534d0f909d","source_path":"environment.md","text_hash":"582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf","text":" in ","translated":" 在 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:25:51Z"} -{"cache_key":"fa7eadfbeb6089c235d526f5463bcba6bd1d0ab30fbc4eff7f170e3e03fb83be","segment_id":"help/index.md:5c94724fa7810fa9","source_path":"help/index.md","text_hash":"5c94724fa7810fa9902e565cf66c5f5a973074f2961fcd3a40bad4ee4aeca5e0","text":"If you want a quick “get unstuck” flow, start here:","translated":"如果你想快速排障,请从这里开始:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:09Z"} -{"cache_key":"fa8390ce00f9c591f6fb7e0d5d4753ca5f421b96668f90965f884e53f15ff87c","segment_id":"index.md:185beb968bd1a81d","source_path":"index.md","text_hash":"185beb968bd1a81d07ebcf82376642f7b29f1b5594b21fe9edee714efbdcaa44","text":"✈️ ","translated":"✈️ ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:49:31Z"} -{"cache_key":"fa9908d4e7381bb3cc4d9ce5dd90158a06ebae51ae44d2b138bc9191e25abc34","segment_id":"start/wizard.md:4c8906cf76f5740a","source_path":"start/wizard.md","text_hash":"4c8906cf76f5740ab8792aef9f0033fe21a92045e90b357816064e9f6860a03e","text":"Channels","translated":"渠道","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:44:11Z"} -{"cache_key":"faae749a1e3720731bd89450cc30ca39d65ca2d3968ac048373c3f6ba5087381","segment_id":"start/getting-started.md:9c7c1a1750d380e8","source_path":"start/getting-started.md","text_hash":"9c7c1a1750d380e8b4f5329437dd3e6066f20891e74af700595ddf8a5eac42a3","text":"Bun warning (WhatsApp + Telegram):","translated":"Bun 警告(WhatsApp + Telegram):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:37:01Z"} -{"cache_key":"fab1c40ef11182f7118f5528b5ba6ed5b5c169c37b302382107e3fbab3d200c1","segment_id":"index.md:3d8fed7c358b2ccf","source_path":"index.md","text_hash":"3d8fed7c358b2ccf225ee16857a0bb9b950fd414319749e0f6fff58c99fa5f22","text":"Subscription auth","translated":"订阅认证","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:50:25Z"} -{"cache_key":"fae191ae8b8380df30a34afd63fc9ba9125258cee9f76e625da9a9c41a858973","segment_id":"start/wizard.md:158ac20b77d1dc12","source_path":"start/wizard.md","text_hash":"158ac20b77d1dc1223a47723e75f03b49fe61d0a6d69de4c3bba9fdd4c123c04","text":" only configures the local client to connect to a Gateway elsewhere.\nIt does ","translated":" 仅配置本地客户端以连接到其他位置的 Gateway。它 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:40:36Z"} -{"cache_key":"faf6394b29b7de4f1af4a5c01405a2c33d4a1f8f58691915d75eedd3572b1d49","segment_id":"index.md:a7a19d4f14d001a5","source_path":"index.md","text_hash":"a7a19d4f14d001a56c27f68a13ff267859a407c7a9ab457c0945693c9067dd1c","text":"Configuration (optional)","translated":"配置(可选)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:03:21Z"} -{"cache_key":"fc41f7c0ff1d82b20353a8a79f2da756675af014a48e1c36b3e693e2030aca4c","segment_id":"help/index.md:6201111b83a0cb5b","source_path":"help/index.md","text_hash":"6201111b83a0cb5b0922cb37cc442b9a40e24e3b1ce100a4bb204f4c63fd2ac0","text":" and ","translated":" 和 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:39:50Z"} -{"cache_key":"fc43ec1fbbcff82d8d617e73687d1fa0c004b3fa731fdb6c9a1b0825ac2df2f5","segment_id":"start/wizard.md:d80c4025fe9728d6","source_path":"start/wizard.md","text_hash":"d80c4025fe9728d67b8330bdbb25a3062c7748ae6779d348b66687d5a796550f","text":"Gateway wizard RPC","translated":"Gateway 向导 RPC","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:47:41Z"} -{"cache_key":"fc503e5044847f8c5412b75ba55ec912df5577a3bc37a7a975393684059d9c12","segment_id":"environment.md:61115f6649792387","source_path":"environment.md","text_hash":"61115f664979238731a390e84433a818965b7eaf1d38fa5b4b1507c33ef28c91","text":"Precedence (highest → lowest)","translated":"优先级(从高到低)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:16:00Z"} -{"cache_key":"fc5a2a3c595c777506fa783ae7fdb46154bc1a9d2990062d2816de3f42b4a5a4","segment_id":"index.md:c011d6097bfbc8e9","source_path":"index.md","text_hash":"c011d6097bfbc8e936280addcf2e3e7d06ea2223ffd596973191b800a7035c32","text":"License","translated":"许可证","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:06:48Z"} -{"cache_key":"fc7b6106c6fe0ee6f9470690d4557420fe96c6bf88d32572c1c6bcebeeca0ba5","segment_id":"index.md:1e37e607483201e2","source_path":"index.md","text_hash":"1e37e607483201e2152d2e9c68874dd4027648efdd9cfccb7bf8c9837398d143","text":"), serving ","translated":"),提供 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:00:27Z"} -{"cache_key":"fc98ca0f83f0fb76119a9483b4e7cf04bba735dc5c4bac23b5fea356315322a6","segment_id":"start/wizard.md:78db1bd89a6a2b1c","source_path":"start/wizard.md","text_hash":"78db1bd89a6a2b1cfa5c7af25c03cdd0aaef049910f8532b3440fdf3e5d41759","text":"May prompt for sudo (writes ","translated":"可能会提示输入 sudo(写入 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:45:24Z"} -{"cache_key":"fca2c0b7fa4c88f595ccb62204b07c5d014cb1f1240a39a203bfe37e25fe8c07","segment_id":"index.md:eef0107bb5a4e06b","source_path":"index.md","text_hash":"eef0107bb5a4e06b9de432b9e62bcf1e39ca5dfbbb9cb0cc1c803ca7671c06ab","text":"Gateway runbook","translated":"Gateway 运行手册","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:54Z"} -{"cache_key":"fcb8a00898eb27b04a3ced786d117b0d7be079d0f45d8608b8a8fe87ad32f0eb","segment_id":"index.md:82ba9b60b12da3ab","source_path":"index.md","text_hash":"82ba9b60b12da3ab4e7dbcb0d7d937214cff80c82268311423a6dc8c4bc09df5","text":"OpenClaw 🦞","translated":"OpenClaw 🦞","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:47:22Z"} -{"cache_key":"fd042da779d8af0e3f90024d3ee3ed60dc05ed4220b6645c1c7afd148c481918","segment_id":"help/index.md:729bc562eec2658b","source_path":"help/index.md","text_hash":"729bc562eec2658bd11ffdd522fe5277177dc73e86eaca7baac0b472a4d8f8b2","text":"If you’re looking for conceptual questions (not “something broke”):","translated":"如果你在寻找概念性问题的答案(而不是\"出了问题\"):","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:15:36Z"} -{"cache_key":"fd16400d64e6f3b7376b1999211a6ed33688eeb2c9a6fd26ce226094628b2647","segment_id":"help/index.md:d3ef01b4a9c99103","source_path":"help/index.md","text_hash":"d3ef01b4a9c9910364c9b26b2499c8787a0461d2d24ab80376fff736a288b34c","text":"Logging","translated":"日志记录","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:11:22Z"} -{"cache_key":"fd42cd6d27d391746b39a68daf76869aab50130d11563f38793103f97b0cc634","segment_id":"environment.md:b4736422e64c0a36","source_path":"environment.md","text_hash":"b4736422e64c0a369663d1b2d386f1b8f4b31b8936b588e4a54453c61a24e0fd","text":"Process environment","translated":"进程环境","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:40:30Z"} -{"cache_key":"fd81a6834413dec93cb0fa720f94f980ebd8de062a9f03c67f8a5eac7dba177b","segment_id":"start/wizard.md:f9101c545949c8fd","source_path":"start/wizard.md","text_hash":"f9101c545949c8fd264de16e8705ea2867f73b1e72f14ed6701d37169226731b","text":"The onboarding wizard is the ","translated":"上手引导向导是 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:38:59Z"} -{"cache_key":"fdd0251e3da40ed9b7947f5fc52798e46adbdbe32b4687efe40bf1c34c3f8a54","segment_id":"environment.md:45ca56d179d4788c","source_path":"environment.md","text_hash":"45ca56d179d4788c55ba9f7653b376d62e7faa738e92259e3d4f6f5c1b554f28","text":"Related","translated":"相关内容","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:13:09Z"} -{"cache_key":"fe03652b8fbba7658cd3c33e1ecfc88bf7a2a2416727c8de537a1ff4a7d04c63","segment_id":"start/wizard.md:51aa8bdcedfdb0c9","source_path":"start/wizard.md","text_hash":"51aa8bdcedfdb0c9eefbf91a6fa25d78b4c367be285bd472553cc0b461d983c8","text":"OpenAI API key","translated":"OpenAI API 密钥","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:26Z"} -{"cache_key":"fe28d810ff498a350b586785445582bed45cf1b1de02ea8be1569cf0da546ecc","segment_id":"index.md:3f8466cd9cb153d0","source_path":"index.md","text_hash":"3f8466cd9cb153d0c78a88f6a209e2206992db28c6dab45424132dc187974e2b","text":"Note: legacy Claude/Codex/Gemini/Opencode paths have been removed; Pi is the only coding-agent path.","translated":"注意:旧版 Claude/Codex/Gemini/Opencode 路径已被移除;Pi 是唯一的编程 智能体 路径。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:51:20Z"} -{"cache_key":"fe4dd967a44b8e8082aa5b2441ea4e4fc4478e2e370087cf666830f23b215d1c","segment_id":"index.md:74f99190ef66a7d5","source_path":"index.md","text_hash":"74f99190ef66a7d513049d31bafc76e05f9703f3320bf757fb2693447a48c25b","text":"Linux app","translated":"Linux 应用","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:05:16Z"} -{"cache_key":"fe554549a7c67caf1f51ae69b2d4bdb126cc0bfeb0963610e8b0be605fb058e3","segment_id":"start/wizard.md:87bb59ba2f92f2a5","source_path":"start/wizard.md","text_hash":"87bb59ba2f92f2a5a9f13e021fd58dd14ae5c065b1046146875e6e68d5ebc8b7","text":"Workspace","translated":"工作区","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:43:38Z"} -{"cache_key":"fe81eef1d52c47b26c55cb74fd8c6fe31a5c648213d3dcf3de567d8125f222fd","segment_id":"index.md:11450a0f023dc48c","source_path":"index.md","text_hash":"11450a0f023dc48cc9cef026357e2b4569a2b756290191c45a9eb0120a919cb7","text":" and (for groups) mention rules.","translated":" 以及(针对群组的)提及规则。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:03Z"} -{"cache_key":"fe9fff29a8a3a18b8ba8f7493dc3331ffb90c4585bcdc2a3c03e402202f786ae","segment_id":"start/wizard.md:2f6975ca07f6b950","source_path":"start/wizard.md","text_hash":"2f6975ca07f6b95055db357fed97ef04d04d7ac57351e48bd69e0a0675ac47b1","text":"OpenCode Zen (multi-model proxy)","translated":"OpenCode Zen(多模型代理)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:42:32Z"} -{"cache_key":"fecfa9809bf3844fdc62208030ad2364304c83d2c2a278f691a06fe1d95eef29","segment_id":"environment.md:61115f6649792387","source_path":"environment.md","text_hash":"61115f664979238731a390e84433a818965b7eaf1d38fa5b4b1507c33ef28c91","text":"Precedence (highest → lowest)","translated":"优先级(从高到低)","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:18Z"} -{"cache_key":"fed9ca0b4a8c8162f989410401afbb3038f19d1060104d1804a5bacb2af45013","segment_id":"start/wizard.md:f7952490362d43d3","source_path":"start/wizard.md","text_hash":"f7952490362d43d362bce1e931f3e707e6b39369e9182fae26b54f677f778145","text":"If no GUI is detected, the wizard prints SSH port-forward instructions for the Control UI instead of opening a browser.","translated":"如果未检测到 GUI,向导会打印 Control UI 的 SSH 端口转发说明,而不是打开浏览器。","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:46:04Z"} -{"cache_key":"ff0818747bde0777bfd88d234d27b7ccd9e866cb8d477f1c022943f425735631","segment_id":"environment.md:frontmatter:read_when:0","source_path":"environment.md:frontmatter:read_when:0","text_hash":"90fc0487bff88009979cff1061c1a882df8c3b1baa9c43538331d9d5dab15479","text":"You need to know which env vars are loaded, and in what order","translated":"您需要了解哪些 环境变量 被加载,以及加载顺序","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:01Z"} -{"cache_key":"ff35a70223602ebd4e2ccb376f9a05a23436de50c0661a69a6c189e54386369c","segment_id":"environment.md:907940a35852447a","source_path":"environment.md","text_hash":"907940a35852447aad5f21c5a180d993ff31cfd5807b1352ed0c24eabe183465","text":"never override existing values","translated":"永远不覆盖已有的值","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:57:13Z"} -{"cache_key":"ff4870ed3d31dd15db9a3753847994b892bfbbcd169eaf654fa2a9347de1b80a","segment_id":"index.md:053bc65874ad6098","source_path":"index.md","text_hash":"053bc65874ad6098e58c41c57b378a2f36b0220e5e0b46722245e6c2f796818c","text":"Discord","translated":"Discord","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:32:38Z"} -{"cache_key":"ff9cd1150279b1783fc13d1d8deb389b0589027719aa184d39812dab44ad30c3","segment_id":"index.md:075a4a45c3999f34","source_path":"index.md","text_hash":"075a4a45c3999f340be8487cd7c0dd2ed77ced931054d75e95e5e24d5539b45b","text":" — Pi (RPC mode) with tool streaming","translated":" — Pi(RPC 模式)配合 工具 流式传输","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:29Z"} -{"cache_key":"ffc0edaae36968ae44b65f6baba8cef750ebcff415a26c7bbda8f59ed632b548","segment_id":"index.md:872887e563e75957","source_path":"index.md","text_hash":"872887e563e75957ffc20b021332504f2ddd0a8f3964cb93070863bfaf13cdad","text":"Example:","translated":"示例:","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T12:52:06Z"} -{"cache_key":"ffd04ac4efed00f848ef0d6f549a5e3f7237a0942d8d18a0ace2751a1f044099","segment_id":"index.md:0c67abfaa5415391","source_path":"index.md","text_hash":"0c67abfaa5415391a31cf3a4624746b6b212b5ae66364be28ee2d131f014e0c6","text":"🧩 ","translated":"🧩 ","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:01:09Z"} -{"cache_key":"ffd193a2ab6714302a69cbe3b1bc24f881807a3a8ce88558687554509a4c1c1c","segment_id":"index.md:7e2735e5df8f4e9f","source_path":"index.md","text_hash":"7e2735e5df8f4e9f006d10e079fe8045612aa662b02a9d1948081d1173798dec","text":"MIT — Free as a lobster in the ocean 🦞","translated":"MIT — 像大海中的龙虾一样自由 🦞","provider":"pi","model":"claude-opus-4-5","src_lang":"en","tgt_lang":"zh-CN","updated_at":"2026-02-01T13:34:07Z"} diff --git a/docs/CNAME b/docs/CNAME deleted file mode 100644 index 715bc9df52..0000000000 --- a/docs/CNAME +++ /dev/null @@ -1 +0,0 @@ -docs.openclaw.ai diff --git a/docs/assets/install-script.svg b/docs/assets/install-script.svg deleted file mode 100644 index 78a6f97564..0000000000 --- a/docs/assets/install-script.svg +++ /dev/null @@ -1 +0,0 @@ -seb@ubuntu:~$curl-fsSLhttps://openclaw.ai/install.sh|bash╭─────────────────────────────────────────╮🦞OpenClawInstallerBecauseSiriwasn'tansweringat3AM.moderninstallermode╰─────────────────────────────────────────╯gumbootstrapped(temp,verified,v0.17.0)Detected:linuxInstallplanOSlinuxInstallmethodnpmRequestedversionlatest[1/3]PreparingenvironmentINFONode.jsnotfound,installingitnowINFOInstallingNode.jsviaNodeSourceConfiguringNodeSourcerepositoryConfiguringNodeSourcerepositoryConfiguringNodeSourcerepositoryConfiguringNodeSourcerepositoryConfiguringNodeSourcerepositoryConfiguringNodeSourcerepositoryConfiguringNodeSourcerepositoryConfiguringNodeSourcerepositoryInstallingNode.jsInstallingNode.jsInstallingNode.jsInstallingNode.jsInstallingNode.jsInstallingNode.jsInstallingNode.jsInstallingNode.jsNode.jsv22installed[2/3]InstallingOpenClawINFOGitnotfound,installingitnowUpdatingpackageindexInstallingGitInstallingGitInstallingGitInstallingGitInstallingGitInstallingGitInstallingGitInstallingGitGitinstalledINFOConfiguringnpmforuser-localinstallsnpmconfiguredforuserinstallsINFOInstallingOpenClawv2026.2.9InstallingOpenClawpackageInstallingOpenClawpackageInstallingOpenClawpackageInstallingOpenClawpackageInstallingOpenClawpackageInstallingOpenClawpackageInstallingOpenClawpackageInstallingOpenClawpackageOpenClawnpmpackageinstalledOpenClawinstalled[3/3]FinalizingsetupWARNPATHmissingnpmglobalbindir:/home/seb/.npm-global/binThiscanmakeopenclawshowas"commandnotfound"innewterminals.Fix(zsh:~/.zshrc,bash:~/.bashrc):exportPATH="/home/seb/.npm-global/bin:$PATH"🦞OpenClawinstalledsuccessfully(2026.2.9)!Finallyunpacked.Nowpointmeatyourproblems.INFOStartingsetup🦞OpenClaw2026.2.9(33c75cb)Thinkdifferent.Actuallythink.▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄██░▄▄▄░██░▄▄░██░▄▄▄██░▀██░██░▄▄▀██░████░▄▄▀██░███░████░███░██░▀▀░██░▄▄▄██░█░█░██░█████░████░▀▀░██░█░█░████░▀▀▀░██░█████░▀▀▀██░██▄░██░▀▀▄██░▀▀░█░██░██▄▀▄▀▄██▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀🦞OPENCLAW🦞OpenClawonboardingSecurity──────────────────────────────────────────────────────────────────────────────╮Securitywarningpleaseread.OpenClawisahobbyprojectandstillinbeta.Expectsharpedges.Thisbotcanreadfilesandrunactionsiftoolsareenabled.Abadpromptcantrickitintodoingunsafethings.Ifyou’renotcomfortablewithbasicsecurityandaccesscontrol,don’trunOpenClaw.Asksomeoneexperiencedtohelpbeforeenablingtoolsorexposingittotheinternet.Recommendedbaseline:-Pairing/allowlists+mentiongating.-Sandbox+least-privilegetools.-Keepsecretsoutoftheagent’sreachablefilesystem.-Usethestrongestavailablemodelforanybotwithtoolsoruntrustedinboxes.Runregularly:openclawsecurityaudit--deepopenclawsecurityaudit--fixMustread:https://docs.openclaw.ai/gateway/security├─────────────────────────────────────────────────────────────────────────────────────────╯Iunderstandthisispowerfulandinherentlyrisky.Continue?Yes/NoYes/Noseb@ubuntu:~$asciinemaseb@ubuntu:~$asciinemauploadseb@ubuntu:~$asciinemauploaddemo.castseb@ubuntu:~$seb@ubuntu:~$curl -fsSL https://openclaw.ai/install.sh | bashUpdatingpackageindexUpdatingpackageindexUpdatingpackageindexUpdatingpackageindexUpdatingpackageindexUpdatingpackageindexUpdatingpackageindexAbadpromptcantrickitintodoingunsafethings.-Keepsecretsoutoftheagent’sreachablefilesystem.seb@ubuntu:~$seb@ubuntu:~$aseb@ubuntu:~$asseb@ubuntu:~$ascseb@ubuntu:~$asciseb@ubuntu:~$asciiseb@ubuntu:~$asciinseb@ubuntu:~$asciineseb@ubuntu:~$asciinemseb@ubuntu:~$asciinemauseb@ubuntu:~$asciinemaupseb@ubuntu:~$asciinemauplseb@ubuntu:~$asciinemauploseb@ubuntu:~$asciinemauploaseb@ubuntu:~$asciinemauploaddseb@ubuntu:~$asciinemauploaddeseb@ubuntu:~$asciinemauploaddemseb@ubuntu:~$asciinemauploaddemoseb@ubuntu:~$asciinemauploaddemo.seb@ubuntu:~$asciinemauploaddemo.cseb@ubuntu:~$asciinemauploaddemo.caseb@ubuntu:~$asciinemauploaddemo.cas \ No newline at end of file diff --git a/docs/assets/macos-onboarding/01-macos-warning.jpeg b/docs/assets/macos-onboarding/01-macos-warning.jpeg deleted file mode 100644 index 255976fe51..0000000000 Binary files a/docs/assets/macos-onboarding/01-macos-warning.jpeg and /dev/null differ diff --git a/docs/assets/macos-onboarding/02-local-networks.jpeg b/docs/assets/macos-onboarding/02-local-networks.jpeg deleted file mode 100644 index 0135e38f69..0000000000 Binary files a/docs/assets/macos-onboarding/02-local-networks.jpeg and /dev/null differ diff --git a/docs/assets/macos-onboarding/03-security-notice.png b/docs/assets/macos-onboarding/03-security-notice.png deleted file mode 100644 index ca0dac9684..0000000000 Binary files a/docs/assets/macos-onboarding/03-security-notice.png and /dev/null differ diff --git a/docs/assets/macos-onboarding/04-choose-gateway.png b/docs/assets/macos-onboarding/04-choose-gateway.png deleted file mode 100644 index 4e0233c22d..0000000000 Binary files a/docs/assets/macos-onboarding/04-choose-gateway.png and /dev/null differ diff --git a/docs/assets/macos-onboarding/05-permissions.png b/docs/assets/macos-onboarding/05-permissions.png deleted file mode 100644 index 910a5f8daa..0000000000 Binary files a/docs/assets/macos-onboarding/05-permissions.png and /dev/null differ diff --git a/docs/assets/openclaw-logo-text-dark.png b/docs/assets/openclaw-logo-text-dark.png deleted file mode 100644 index b14e4233b6..0000000000 Binary files a/docs/assets/openclaw-logo-text-dark.png and /dev/null differ diff --git a/docs/assets/openclaw-logo-text.png b/docs/assets/openclaw-logo-text.png deleted file mode 100644 index 705d2c0ba1..0000000000 Binary files a/docs/assets/openclaw-logo-text.png and /dev/null differ diff --git a/docs/assets/pixel-lobster.svg b/docs/assets/pixel-lobster.svg deleted file mode 100644 index 7bfb7fc4d4..0000000000 --- a/docs/assets/pixel-lobster.svg +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/assets/showcase/agents-ui.jpg b/docs/assets/showcase/agents-ui.jpg deleted file mode 100644 index ae6ab6d18d..0000000000 Binary files a/docs/assets/showcase/agents-ui.jpg and /dev/null differ diff --git a/docs/assets/showcase/bambu-cli.png b/docs/assets/showcase/bambu-cli.png deleted file mode 100644 index 046f627ba4..0000000000 Binary files a/docs/assets/showcase/bambu-cli.png and /dev/null differ diff --git a/docs/assets/showcase/codexmonitor.png b/docs/assets/showcase/codexmonitor.png deleted file mode 100644 index 43952b92bd..0000000000 Binary files a/docs/assets/showcase/codexmonitor.png and /dev/null differ diff --git a/docs/assets/showcase/gohome-grafana.png b/docs/assets/showcase/gohome-grafana.png deleted file mode 100644 index bd7cf07740..0000000000 Binary files a/docs/assets/showcase/gohome-grafana.png and /dev/null differ diff --git a/docs/assets/showcase/ios-testflight.jpg b/docs/assets/showcase/ios-testflight.jpg deleted file mode 100644 index 4e19768f97..0000000000 Binary files a/docs/assets/showcase/ios-testflight.jpg and /dev/null differ diff --git a/docs/assets/showcase/oura-health.png b/docs/assets/showcase/oura-health.png deleted file mode 100644 index b1e9f70724..0000000000 Binary files a/docs/assets/showcase/oura-health.png and /dev/null differ diff --git a/docs/assets/showcase/padel-cli.svg b/docs/assets/showcase/padel-cli.svg deleted file mode 100644 index 61eb6334d3..0000000000 --- a/docs/assets/showcase/padel-cli.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - $ padel search --location "Barcelona" --date 2026-01-08 --time 18:00-22:00 - Available courts (3): - - Vall d'Hebron 19:00 Court 2 (90m) EUR 34 - - Badalona 20:30 Court 1 (60m) EUR 28 - - Gracia 21:00 Court 4 (90m) EUR 36 - - diff --git a/docs/assets/showcase/padel-screenshot.jpg b/docs/assets/showcase/padel-screenshot.jpg deleted file mode 100644 index eb1ae39eac..0000000000 Binary files a/docs/assets/showcase/padel-screenshot.jpg and /dev/null differ diff --git a/docs/assets/showcase/papla-tts.jpg b/docs/assets/showcase/papla-tts.jpg deleted file mode 100644 index 3e7af38386..0000000000 Binary files a/docs/assets/showcase/papla-tts.jpg and /dev/null differ diff --git a/docs/assets/showcase/pr-review-telegram.jpg b/docs/assets/showcase/pr-review-telegram.jpg deleted file mode 100644 index 888a413295..0000000000 Binary files a/docs/assets/showcase/pr-review-telegram.jpg and /dev/null differ diff --git a/docs/assets/showcase/roborock-screenshot.jpg b/docs/assets/showcase/roborock-screenshot.jpg deleted file mode 100644 index e31ba11eb9..0000000000 Binary files a/docs/assets/showcase/roborock-screenshot.jpg and /dev/null differ diff --git a/docs/assets/showcase/roborock-status.svg b/docs/assets/showcase/roborock-status.svg deleted file mode 100644 index 470840423c..0000000000 --- a/docs/assets/showcase/roborock-status.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - $ gohome roborock status --device "Living Room" - Device: Roborock Q Revo - State: cleaning (zone) - Battery: 78% - Dustbin: 42% - Water tank: 61% - Last clean: 2026-01-06 19:42 - - diff --git a/docs/assets/showcase/roof-camera-sky.jpg b/docs/assets/showcase/roof-camera-sky.jpg deleted file mode 100644 index 3396f1405c..0000000000 Binary files a/docs/assets/showcase/roof-camera-sky.jpg and /dev/null differ diff --git a/docs/assets/showcase/snag.png b/docs/assets/showcase/snag.png deleted file mode 100644 index c82c47acfc..0000000000 Binary files a/docs/assets/showcase/snag.png and /dev/null differ diff --git a/docs/assets/showcase/tesco-shop.jpg b/docs/assets/showcase/tesco-shop.jpg deleted file mode 100644 index 66af85d3c1..0000000000 Binary files a/docs/assets/showcase/tesco-shop.jpg and /dev/null differ diff --git a/docs/assets/showcase/wienerlinien.png b/docs/assets/showcase/wienerlinien.png deleted file mode 100644 index 8bdf5ae66a..0000000000 Binary files a/docs/assets/showcase/wienerlinien.png and /dev/null differ diff --git a/docs/assets/showcase/wine-cellar-skill.jpg b/docs/assets/showcase/wine-cellar-skill.jpg deleted file mode 100644 index 7cd2016cf0..0000000000 Binary files a/docs/assets/showcase/wine-cellar-skill.jpg and /dev/null differ diff --git a/docs/assets/showcase/winix-air-purifier.jpg b/docs/assets/showcase/winix-air-purifier.jpg deleted file mode 100644 index c8b99540c2..0000000000 Binary files a/docs/assets/showcase/winix-air-purifier.jpg and /dev/null differ diff --git a/docs/assets/showcase/xuezh-pronunciation.jpeg b/docs/assets/showcase/xuezh-pronunciation.jpeg deleted file mode 100644 index 7f7d86a8fa..0000000000 Binary files a/docs/assets/showcase/xuezh-pronunciation.jpeg and /dev/null differ diff --git a/docs/automation/auth-monitoring.md b/docs/automation/auth-monitoring.md deleted file mode 100644 index 877a1c2ce2..0000000000 --- a/docs/automation/auth-monitoring.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -summary: "Monitor OAuth expiry for model providers" -read_when: - - Setting up auth expiry monitoring or alerts - - Automating Claude Code / Codex OAuth refresh checks -title: "Auth Monitoring" ---- - -# Auth monitoring - -OpenClaw exposes OAuth expiry health via `openclaw models status`. Use that for -automation and alerting; scripts are optional extras for phone workflows. - -## Preferred: CLI check (portable) - -```bash -openclaw models status --check -``` - -Exit codes: - -- `0`: OK -- `1`: expired or missing credentials -- `2`: expiring soon (within 24h) - -This works in cron/systemd and requires no extra scripts. - -## Optional scripts (ops / phone workflows) - -These live under `scripts/` and are **optional**. They assume SSH access to the -gateway host and are tuned for systemd + Termux. - -- `scripts/claude-auth-status.sh` now uses `openclaw models status --json` as the - source of truth (falling back to direct file reads if the CLI is unavailable), - so keep `openclaw` on `PATH` for timers. -- `scripts/auth-monitor.sh`: cron/systemd timer target; sends alerts (ntfy or phone). -- `scripts/systemd/openclaw-auth-monitor.{service,timer}`: systemd user timer. -- `scripts/claude-auth-status.sh`: Claude Code + OpenClaw auth checker (full/json/simple). -- `scripts/mobile-reauth.sh`: guided re‑auth flow over SSH. -- `scripts/termux-quick-auth.sh`: one‑tap widget status + open auth URL. -- `scripts/termux-auth-widget.sh`: full guided widget flow. -- `scripts/termux-sync-widget.sh`: sync Claude Code creds → OpenClaw. - -If you don’t need phone automation or systemd timers, skip these scripts. diff --git a/docs/automation/cron-jobs.md b/docs/automation/cron-jobs.md deleted file mode 100644 index aae5f58fdf..0000000000 --- a/docs/automation/cron-jobs.md +++ /dev/null @@ -1,542 +0,0 @@ ---- -summary: "Cron jobs + wakeups for the Gateway scheduler" -read_when: - - Scheduling background jobs or wakeups - - Wiring automation that should run with or alongside heartbeats - - Deciding between heartbeat and cron for scheduled tasks -title: "Cron Jobs" ---- - -# Cron jobs (Gateway scheduler) - -> **Cron vs Heartbeat?** See [Cron vs Heartbeat](/automation/cron-vs-heartbeat) for guidance on when to use each. - -Cron is the Gateway’s built-in scheduler. It persists jobs, wakes the agent at -the right time, and can optionally deliver output back to a chat. - -If you want _“run this every morning”_ or _“poke the agent in 20 minutes”_, -cron is the mechanism. - -Troubleshooting: [/automation/troubleshooting](/automation/troubleshooting) - -## TL;DR - -- Cron runs **inside the Gateway** (not inside the model). -- Jobs persist under `~/.openclaw/cron/` so restarts don’t lose schedules. -- Two execution styles: - - **Main session**: enqueue a system event, then run on the next heartbeat. - - **Isolated**: run a dedicated agent turn in `cron:`, with delivery (announce by default or none). -- Wakeups are first-class: a job can request “wake now” vs “next heartbeat”. -- Webhook posting is per job via `delivery.mode = "webhook"` + `delivery.to = ""`. -- Legacy fallback remains for stored jobs with `notify: true` when `cron.webhook` is set, migrate those jobs to webhook delivery mode. - -## Quick start (actionable) - -Create a one-shot reminder, verify it exists, and run it immediately: - -```bash -openclaw cron add \ - --name "Reminder" \ - --at "2026-02-01T16:00:00Z" \ - --session main \ - --system-event "Reminder: check the cron docs draft" \ - --wake now \ - --delete-after-run - -openclaw cron list -openclaw cron run -openclaw cron runs --id -``` - -Schedule a recurring isolated job with delivery: - -```bash -openclaw cron add \ - --name "Morning brief" \ - --cron "0 7 * * *" \ - --tz "America/Los_Angeles" \ - --session isolated \ - --message "Summarize overnight updates." \ - --announce \ - --channel slack \ - --to "channel:C1234567890" -``` - -## Tool-call equivalents (Gateway cron tool) - -For the canonical JSON shapes and examples, see [JSON schema for tool calls](/automation/cron-jobs#json-schema-for-tool-calls). - -## Where cron jobs are stored - -Cron jobs are persisted on the Gateway host at `~/.openclaw/cron/jobs.json` by default. -The Gateway loads the file into memory and writes it back on changes, so manual edits -are only safe when the Gateway is stopped. Prefer `openclaw cron add/edit` or the cron -tool call API for changes. - -## Beginner-friendly overview - -Think of a cron job as: **when** to run + **what** to do. - -1. **Choose a schedule** - - One-shot reminder → `schedule.kind = "at"` (CLI: `--at`) - - Repeating job → `schedule.kind = "every"` or `schedule.kind = "cron"` - - If your ISO timestamp omits a timezone, it is treated as **UTC**. - -2. **Choose where it runs** - - `sessionTarget: "main"` → run during the next heartbeat with main context. - - `sessionTarget: "isolated"` → run a dedicated agent turn in `cron:`. - -3. **Choose the payload** - - Main session → `payload.kind = "systemEvent"` - - Isolated session → `payload.kind = "agentTurn"` - -Optional: one-shot jobs (`schedule.kind = "at"`) delete after success by default. Set -`deleteAfterRun: false` to keep them (they will disable after success). - -## Concepts - -### Jobs - -A cron job is a stored record with: - -- a **schedule** (when it should run), -- a **payload** (what it should do), -- optional **delivery mode** (`announce`, `webhook`, or `none`). -- optional **agent binding** (`agentId`): run the job under a specific agent; if - missing or unknown, the gateway falls back to the default agent. - -Jobs are identified by a stable `jobId` (used by CLI/Gateway APIs). -In agent tool calls, `jobId` is canonical; legacy `id` is accepted for compatibility. -One-shot jobs auto-delete after success by default; set `deleteAfterRun: false` to keep them. - -### Schedules - -Cron supports three schedule kinds: - -- `at`: one-shot timestamp via `schedule.at` (ISO 8601). -- `every`: fixed interval (ms). -- `cron`: 5-field cron expression (or 6-field with seconds) with optional IANA timezone. - -Cron expressions use `croner`. If a timezone is omitted, the Gateway host’s -local timezone is used. - -To reduce top-of-hour load spikes across many gateways, OpenClaw applies a -deterministic per-job stagger window of up to 5 minutes for recurring -top-of-hour expressions (for example `0 * * * *`, `0 */2 * * *`). Fixed-hour -expressions such as `0 7 * * *` remain exact. - -For any cron schedule, you can set an explicit stagger window with `schedule.staggerMs` -(`0` keeps exact timing). CLI shortcuts: - -- `--stagger 30s` (or `1m`, `5m`) to set an explicit stagger window. -- `--exact` to force `staggerMs = 0`. - -### Main vs isolated execution - -#### Main session jobs (system events) - -Main jobs enqueue a system event and optionally wake the heartbeat runner. -They must use `payload.kind = "systemEvent"`. - -- `wakeMode: "now"` (default): event triggers an immediate heartbeat run. -- `wakeMode: "next-heartbeat"`: event waits for the next scheduled heartbeat. - -This is the best fit when you want the normal heartbeat prompt + main-session context. -See [Heartbeat](/gateway/heartbeat). - -#### Isolated jobs (dedicated cron sessions) - -Isolated jobs run a dedicated agent turn in session `cron:`. - -Key behaviors: - -- Prompt is prefixed with `[cron: ]` for traceability. -- Each run starts a **fresh session id** (no prior conversation carry-over). -- Default behavior: if `delivery` is omitted, isolated jobs announce a summary (`delivery.mode = "announce"`). -- `delivery.mode` chooses what happens: - - `announce`: deliver a summary to the target channel and post a brief summary to the main session. - - `webhook`: POST the finished event payload to `delivery.to` when the finished event includes a summary. - - `none`: internal only (no delivery, no main-session summary). -- `wakeMode` controls when the main-session summary posts: - - `now`: immediate heartbeat. - - `next-heartbeat`: waits for the next scheduled heartbeat. - -Use isolated jobs for noisy, frequent, or "background chores" that shouldn't spam -your main chat history. - -### Payload shapes (what runs) - -Two payload kinds are supported: - -- `systemEvent`: main-session only, routed through the heartbeat prompt. -- `agentTurn`: isolated-session only, runs a dedicated agent turn. - -Common `agentTurn` fields: - -- `message`: required text prompt. -- `model` / `thinking`: optional overrides (see below). -- `timeoutSeconds`: optional timeout override. - -Delivery config: - -- `delivery.mode`: `none` | `announce` | `webhook`. -- `delivery.channel`: `last` or a specific channel. -- `delivery.to`: channel-specific target (announce) or webhook URL (webhook mode). -- `delivery.bestEffort`: avoid failing the job if announce delivery fails. - -Announce delivery suppresses messaging tool sends for the run; use `delivery.channel`/`delivery.to` -to target the chat instead. When `delivery.mode = "none"`, no summary is posted to the main session. - -If `delivery` is omitted for isolated jobs, OpenClaw defaults to `announce`. - -#### Announce delivery flow - -When `delivery.mode = "announce"`, cron delivers directly via the outbound channel adapters. -The main agent is not spun up to craft or forward the message. - -Behavior details: - -- Content: delivery uses the isolated run's outbound payloads (text/media) with normal chunking and - channel formatting. -- Heartbeat-only responses (`HEARTBEAT_OK` with no real content) are not delivered. -- If the isolated run already sent a message to the same target via the message tool, delivery is - skipped to avoid duplicates. -- Missing or invalid delivery targets fail the job unless `delivery.bestEffort = true`. -- A short summary is posted to the main session only when `delivery.mode = "announce"`. -- The main-session summary respects `wakeMode`: `now` triggers an immediate heartbeat and - `next-heartbeat` waits for the next scheduled heartbeat. - -#### Webhook delivery flow - -When `delivery.mode = "webhook"`, cron posts the finished event payload to `delivery.to` when the finished event includes a summary. - -Behavior details: - -- The endpoint must be a valid HTTP(S) URL. -- No channel delivery is attempted in webhook mode. -- No main-session summary is posted in webhook mode. -- If `cron.webhookToken` is set, auth header is `Authorization: Bearer `. -- Deprecated fallback: stored legacy jobs with `notify: true` still post to `cron.webhook` (if configured), with a warning so you can migrate to `delivery.mode = "webhook"`. - -### Model and thinking overrides - -Isolated jobs (`agentTurn`) can override the model and thinking level: - -- `model`: Provider/model string (e.g., `anthropic/claude-sonnet-4-20250514`) or alias (e.g., `opus`) -- `thinking`: Thinking level (`off`, `minimal`, `low`, `medium`, `high`, `xhigh`; GPT-5.2 + Codex models only) - -Note: You can set `model` on main-session jobs too, but it changes the shared main -session model. We recommend model overrides only for isolated jobs to avoid -unexpected context shifts. - -Resolution priority: - -1. Job payload override (highest) -2. Hook-specific defaults (e.g., `hooks.gmail.model`) -3. Agent config default - -### Delivery (channel + target) - -Isolated jobs can deliver output to a channel via the top-level `delivery` config: - -- `delivery.mode`: `announce` (channel delivery), `webhook` (HTTP POST), or `none`. -- `delivery.channel`: `whatsapp` / `telegram` / `discord` / `slack` / `mattermost` (plugin) / `signal` / `imessage` / `last`. -- `delivery.to`: channel-specific recipient target. - -`announce` delivery is only valid for isolated jobs (`sessionTarget: "isolated"`). -`webhook` delivery is valid for both main and isolated jobs. - -If `delivery.channel` or `delivery.to` is omitted, cron can fall back to the main session’s -“last route” (the last place the agent replied). - -Target format reminders: - -- Slack/Discord/Mattermost (plugin) targets should use explicit prefixes (e.g. `channel:`, `user:`) to avoid ambiguity. -- Telegram topics should use the `:topic:` form (see below). - -#### Telegram delivery targets (topics / forum threads) - -Telegram supports forum topics via `message_thread_id`. For cron delivery, you can encode -the topic/thread into the `to` field: - -- `-1001234567890` (chat id only) -- `-1001234567890:topic:123` (preferred: explicit topic marker) -- `-1001234567890:123` (shorthand: numeric suffix) - -Prefixed targets like `telegram:...` / `telegram:group:...` are also accepted: - -- `telegram:group:-1001234567890:topic:123` - -## JSON schema for tool calls - -Use these shapes when calling Gateway `cron.*` tools directly (agent tool calls or RPC). -CLI flags accept human durations like `20m`, but tool calls should use an ISO 8601 string -for `schedule.at` and milliseconds for `schedule.everyMs`. - -### cron.add params - -One-shot, main session job (system event): - -```json -{ - "name": "Reminder", - "schedule": { "kind": "at", "at": "2026-02-01T16:00:00Z" }, - "sessionTarget": "main", - "wakeMode": "now", - "payload": { "kind": "systemEvent", "text": "Reminder text" }, - "deleteAfterRun": true -} -``` - -Recurring, isolated job with delivery: - -```json -{ - "name": "Morning brief", - "schedule": { "kind": "cron", "expr": "0 7 * * *", "tz": "America/Los_Angeles" }, - "sessionTarget": "isolated", - "wakeMode": "next-heartbeat", - "payload": { - "kind": "agentTurn", - "message": "Summarize overnight updates." - }, - "delivery": { - "mode": "announce", - "channel": "slack", - "to": "channel:C1234567890", - "bestEffort": true - } -} -``` - -Notes: - -- `schedule.kind`: `at` (`at`), `every` (`everyMs`), or `cron` (`expr`, optional `tz`). -- `schedule.at` accepts ISO 8601 (timezone optional; treated as UTC when omitted). -- `everyMs` is milliseconds. -- `sessionTarget` must be `"main"` or `"isolated"` and must match `payload.kind`. -- Optional fields: `agentId`, `description`, `enabled`, `deleteAfterRun` (defaults to true for `at`), - `delivery`. -- `wakeMode` defaults to `"now"` when omitted. - -### cron.update params - -```json -{ - "jobId": "job-123", - "patch": { - "enabled": false, - "schedule": { "kind": "every", "everyMs": 3600000 } - } -} -``` - -Notes: - -- `jobId` is canonical; `id` is accepted for compatibility. -- Use `agentId: null` in the patch to clear an agent binding. - -### cron.run and cron.remove params - -```json -{ "jobId": "job-123", "mode": "force" } -``` - -```json -{ "jobId": "job-123" } -``` - -## Storage & history - -- Job store: `~/.openclaw/cron/jobs.json` (Gateway-managed JSON). -- Run history: `~/.openclaw/cron/runs/.jsonl` (JSONL, auto-pruned). -- Override store path: `cron.store` in config. - -## Configuration - -```json5 -{ - cron: { - enabled: true, // default true - store: "~/.openclaw/cron/jobs.json", - maxConcurrentRuns: 1, // default 1 - webhook: "https://example.invalid/legacy", // deprecated fallback for stored notify:true jobs - webhookToken: "replace-with-dedicated-webhook-token", // optional bearer token for webhook mode - }, -} -``` - -Webhook behavior: - -- Preferred: set `delivery.mode: "webhook"` with `delivery.to: "https://..."` per job. -- Webhook URLs must be valid `http://` or `https://` URLs. -- When posted, payload is the cron finished event JSON. -- If `cron.webhookToken` is set, auth header is `Authorization: Bearer `. -- If `cron.webhookToken` is not set, no `Authorization` header is sent. -- Deprecated fallback: stored legacy jobs with `notify: true` still use `cron.webhook` when present. - -Disable cron entirely: - -- `cron.enabled: false` (config) -- `OPENCLAW_SKIP_CRON=1` (env) - -## CLI quickstart - -One-shot reminder (UTC ISO, auto-delete after success): - -```bash -openclaw cron add \ - --name "Send reminder" \ - --at "2026-01-12T18:00:00Z" \ - --session main \ - --system-event "Reminder: submit expense report." \ - --wake now \ - --delete-after-run -``` - -One-shot reminder (main session, wake immediately): - -```bash -openclaw cron add \ - --name "Calendar check" \ - --at "20m" \ - --session main \ - --system-event "Next heartbeat: check calendar." \ - --wake now -``` - -Recurring isolated job (announce to WhatsApp): - -```bash -openclaw cron add \ - --name "Morning status" \ - --cron "0 7 * * *" \ - --tz "America/Los_Angeles" \ - --session isolated \ - --message "Summarize inbox + calendar for today." \ - --announce \ - --channel whatsapp \ - --to "+15551234567" -``` - -Recurring cron job with explicit 30-second stagger: - -```bash -openclaw cron add \ - --name "Minute watcher" \ - --cron "0 * * * * *" \ - --tz "UTC" \ - --stagger 30s \ - --session isolated \ - --message "Run minute watcher checks." \ - --announce -``` - -Recurring isolated job (deliver to a Telegram topic): - -```bash -openclaw cron add \ - --name "Nightly summary (topic)" \ - --cron "0 22 * * *" \ - --tz "America/Los_Angeles" \ - --session isolated \ - --message "Summarize today; send to the nightly topic." \ - --announce \ - --channel telegram \ - --to "-1001234567890:topic:123" -``` - -Isolated job with model and thinking override: - -```bash -openclaw cron add \ - --name "Deep analysis" \ - --cron "0 6 * * 1" \ - --tz "America/Los_Angeles" \ - --session isolated \ - --message "Weekly deep analysis of project progress." \ - --model "opus" \ - --thinking high \ - --announce \ - --channel whatsapp \ - --to "+15551234567" -``` - -Agent selection (multi-agent setups): - -```bash -# Pin a job to agent "ops" (falls back to default if that agent is missing) -openclaw cron add --name "Ops sweep" --cron "0 6 * * *" --session isolated --message "Check ops queue" --agent ops - -# Switch or clear the agent on an existing job -openclaw cron edit --agent ops -openclaw cron edit --clear-agent -``` - -Manual run (force is the default, use `--due` to only run when due): - -```bash -openclaw cron run -openclaw cron run --due -``` - -Edit an existing job (patch fields): - -```bash -openclaw cron edit \ - --message "Updated prompt" \ - --model "opus" \ - --thinking low -``` - -Force an existing cron job to run exactly on schedule (no stagger): - -```bash -openclaw cron edit --exact -``` - -Run history: - -```bash -openclaw cron runs --id --limit 50 -``` - -Immediate system event without creating a job: - -```bash -openclaw system event --mode now --text "Next heartbeat: check battery." -``` - -## Gateway API surface - -- `cron.list`, `cron.status`, `cron.add`, `cron.update`, `cron.remove` -- `cron.run` (force or due), `cron.runs` - For immediate system events without a job, use [`openclaw system event`](/cli/system). - -## Troubleshooting - -### “Nothing runs” - -- Check cron is enabled: `cron.enabled` and `OPENCLAW_SKIP_CRON`. -- Check the Gateway is running continuously (cron runs inside the Gateway process). -- For `cron` schedules: confirm timezone (`--tz`) vs the host timezone. - -### A recurring job keeps delaying after failures - -- OpenClaw applies exponential retry backoff for recurring jobs after consecutive errors: - 30s, 1m, 5m, 15m, then 60m between retries. -- Backoff resets automatically after the next successful run. -- One-shot (`at`) jobs disable after a terminal run (`ok`, `error`, or `skipped`) and do not retry. - -### Telegram delivers to the wrong place - -- For forum topics, use `-100…:topic:` so it’s explicit and unambiguous. -- If you see `telegram:...` prefixes in logs or stored “last route” targets, that’s normal; - cron delivery accepts them and still parses topic IDs correctly. - -### Subagent announce delivery retries - -- When a subagent run completes, the gateway announces the result to the requester session. -- If the announce flow returns `false` (e.g. requester session is busy), the gateway retries up to 3 times with tracking via `announceRetryCount`. -- Announces older than 5 minutes past `endedAt` are force-expired to prevent stale entries from looping indefinitely. -- If you see repeated announce deliveries in logs, check the subagent registry for entries with high `announceRetryCount` values. diff --git a/docs/automation/cron-vs-heartbeat.md b/docs/automation/cron-vs-heartbeat.md deleted file mode 100644 index c25cbcb80d..0000000000 --- a/docs/automation/cron-vs-heartbeat.md +++ /dev/null @@ -1,286 +0,0 @@ ---- -summary: "Guidance for choosing between heartbeat and cron jobs for automation" -read_when: - - Deciding how to schedule recurring tasks - - Setting up background monitoring or notifications - - Optimizing token usage for periodic checks -title: "Cron vs Heartbeat" ---- - -# Cron vs Heartbeat: When to Use Each - -Both heartbeats and cron jobs let you run tasks on a schedule. This guide helps you choose the right mechanism for your use case. - -## Quick Decision Guide - -| Use Case | Recommended | Why | -| ------------------------------------ | ------------------- | ---------------------------------------- | -| Check inbox every 30 min | Heartbeat | Batches with other checks, context-aware | -| Send daily report at 9am sharp | Cron (isolated) | Exact timing needed | -| Monitor calendar for upcoming events | Heartbeat | Natural fit for periodic awareness | -| Run weekly deep analysis | Cron (isolated) | Standalone task, can use different model | -| Remind me in 20 minutes | Cron (main, `--at`) | One-shot with precise timing | -| Background project health check | Heartbeat | Piggybacks on existing cycle | - -## Heartbeat: Periodic Awareness - -Heartbeats run in the **main session** at a regular interval (default: 30 min). They're designed for the agent to check on things and surface anything important. - -### When to use heartbeat - -- **Multiple periodic checks**: Instead of 5 separate cron jobs checking inbox, calendar, weather, notifications, and project status, a single heartbeat can batch all of these. -- **Context-aware decisions**: The agent has full main-session context, so it can make smart decisions about what's urgent vs. what can wait. -- **Conversational continuity**: Heartbeat runs share the same session, so the agent remembers recent conversations and can follow up naturally. -- **Low-overhead monitoring**: One heartbeat replaces many small polling tasks. - -### Heartbeat advantages - -- **Batches multiple checks**: One agent turn can review inbox, calendar, and notifications together. -- **Reduces API calls**: A single heartbeat is cheaper than 5 isolated cron jobs. -- **Context-aware**: The agent knows what you've been working on and can prioritize accordingly. -- **Smart suppression**: If nothing needs attention, the agent replies `HEARTBEAT_OK` and no message is delivered. -- **Natural timing**: Drifts slightly based on queue load, which is fine for most monitoring. - -### Heartbeat example: HEARTBEAT.md checklist - -```md -# Heartbeat checklist - -- Check email for urgent messages -- Review calendar for events in next 2 hours -- If a background task finished, summarize results -- If idle for 8+ hours, send a brief check-in -``` - -The agent reads this on each heartbeat and handles all items in one turn. - -### Configuring heartbeat - -```json5 -{ - agents: { - defaults: { - heartbeat: { - every: "30m", // interval - target: "last", // where to deliver alerts - activeHours: { start: "08:00", end: "22:00" }, // optional - }, - }, - }, -} -``` - -See [Heartbeat](/gateway/heartbeat) for full configuration. - -## Cron: Precise Scheduling - -Cron jobs run at precise times and can run in isolated sessions without affecting main context. -Recurring top-of-hour schedules are automatically spread by a deterministic -per-job offset in a 0-5 minute window. - -### When to use cron - -- **Exact timing required**: "Send this at 9:00 AM every Monday" (not "sometime around 9"). -- **Standalone tasks**: Tasks that don't need conversational context. -- **Different model/thinking**: Heavy analysis that warrants a more powerful model. -- **One-shot reminders**: "Remind me in 20 minutes" with `--at`. -- **Noisy/frequent tasks**: Tasks that would clutter main session history. -- **External triggers**: Tasks that should run independently of whether the agent is otherwise active. - -### Cron advantages - -- **Precise timing**: 5-field or 6-field (seconds) cron expressions with timezone support. -- **Built-in load spreading**: recurring top-of-hour schedules are staggered by up to 5 minutes by default. -- **Per-job control**: override stagger with `--stagger ` or force exact timing with `--exact`. -- **Session isolation**: Runs in `cron:` without polluting main history. -- **Model overrides**: Use a cheaper or more powerful model per job. -- **Delivery control**: Isolated jobs default to `announce` (summary); choose `none` as needed. -- **Immediate delivery**: Announce mode posts directly without waiting for heartbeat. -- **No agent context needed**: Runs even if main session is idle or compacted. -- **One-shot support**: `--at` for precise future timestamps. - -### Cron example: Daily morning briefing - -```bash -openclaw cron add \ - --name "Morning briefing" \ - --cron "0 7 * * *" \ - --tz "America/New_York" \ - --session isolated \ - --message "Generate today's briefing: weather, calendar, top emails, news summary." \ - --model opus \ - --announce \ - --channel whatsapp \ - --to "+15551234567" -``` - -This runs at exactly 7:00 AM New York time, uses Opus for quality, and announces a summary directly to WhatsApp. - -### Cron example: One-shot reminder - -```bash -openclaw cron add \ - --name "Meeting reminder" \ - --at "20m" \ - --session main \ - --system-event "Reminder: standup meeting starts in 10 minutes." \ - --wake now \ - --delete-after-run -``` - -See [Cron jobs](/automation/cron-jobs) for full CLI reference. - -## Decision Flowchart - -``` -Does the task need to run at an EXACT time? - YES -> Use cron - NO -> Continue... - -Does the task need isolation from main session? - YES -> Use cron (isolated) - NO -> Continue... - -Can this task be batched with other periodic checks? - YES -> Use heartbeat (add to HEARTBEAT.md) - NO -> Use cron - -Is this a one-shot reminder? - YES -> Use cron with --at - NO -> Continue... - -Does it need a different model or thinking level? - YES -> Use cron (isolated) with --model/--thinking - NO -> Use heartbeat -``` - -## Combining Both - -The most efficient setup uses **both**: - -1. **Heartbeat** handles routine monitoring (inbox, calendar, notifications) in one batched turn every 30 minutes. -2. **Cron** handles precise schedules (daily reports, weekly reviews) and one-shot reminders. - -### Example: Efficient automation setup - -**HEARTBEAT.md** (checked every 30 min): - -```md -# Heartbeat checklist - -- Scan inbox for urgent emails -- Check calendar for events in next 2h -- Review any pending tasks -- Light check-in if quiet for 8+ hours -``` - -**Cron jobs** (precise timing): - -```bash -# Daily morning briefing at 7am -openclaw cron add --name "Morning brief" --cron "0 7 * * *" --session isolated --message "..." --announce - -# Weekly project review on Mondays at 9am -openclaw cron add --name "Weekly review" --cron "0 9 * * 1" --session isolated --message "..." --model opus - -# One-shot reminder -openclaw cron add --name "Call back" --at "2h" --session main --system-event "Call back the client" --wake now -``` - -## Lobster: Deterministic workflows with approvals - -Lobster is the workflow runtime for **multi-step tool pipelines** that need deterministic execution and explicit approvals. -Use it when the task is more than a single agent turn, and you want a resumable workflow with human checkpoints. - -### When Lobster fits - -- **Multi-step automation**: You need a fixed pipeline of tool calls, not a one-off prompt. -- **Approval gates**: Side effects should pause until you approve, then resume. -- **Resumable runs**: Continue a paused workflow without re-running earlier steps. - -### How it pairs with heartbeat and cron - -- **Heartbeat/cron** decide _when_ a run happens. -- **Lobster** defines _what steps_ happen once the run starts. - -For scheduled workflows, use cron or heartbeat to trigger an agent turn that calls Lobster. -For ad-hoc workflows, call Lobster directly. - -### Operational notes (from the code) - -- Lobster runs as a **local subprocess** (`lobster` CLI) in tool mode and returns a **JSON envelope**. -- If the tool returns `needs_approval`, you resume with a `resumeToken` and `approve` flag. -- The tool is an **optional plugin**; enable it additively via `tools.alsoAllow: ["lobster"]` (recommended). -- Lobster expects the `lobster` CLI to be available on `PATH`. - -See [Lobster](/tools/lobster) for full usage and examples. - -## Main Session vs Isolated Session - -Both heartbeat and cron can interact with the main session, but differently: - -| | Heartbeat | Cron (main) | Cron (isolated) | -| ------- | ------------------------------- | ------------------------ | -------------------------- | -| Session | Main | Main (via system event) | `cron:` | -| History | Shared | Shared | Fresh each run | -| Context | Full | Full | None (starts clean) | -| Model | Main session model | Main session model | Can override | -| Output | Delivered if not `HEARTBEAT_OK` | Heartbeat prompt + event | Announce summary (default) | - -### When to use main session cron - -Use `--session main` with `--system-event` when you want: - -- The reminder/event to appear in main session context -- The agent to handle it during the next heartbeat with full context -- No separate isolated run - -```bash -openclaw cron add \ - --name "Check project" \ - --every "4h" \ - --session main \ - --system-event "Time for a project health check" \ - --wake now -``` - -### When to use isolated cron - -Use `--session isolated` when you want: - -- A clean slate without prior context -- Different model or thinking settings -- Announce summaries directly to a channel -- History that doesn't clutter main session - -```bash -openclaw cron add \ - --name "Deep analysis" \ - --cron "0 6 * * 0" \ - --session isolated \ - --message "Weekly codebase analysis..." \ - --model opus \ - --thinking high \ - --announce -``` - -## Cost Considerations - -| Mechanism | Cost Profile | -| --------------- | ------------------------------------------------------- | -| Heartbeat | One turn every N minutes; scales with HEARTBEAT.md size | -| Cron (main) | Adds event to next heartbeat (no isolated turn) | -| Cron (isolated) | Full agent turn per job; can use cheaper model | - -**Tips**: - -- Keep `HEARTBEAT.md` small to minimize token overhead. -- Batch similar checks into heartbeat instead of multiple cron jobs. -- Use `target: "none"` on heartbeat if you only want internal processing. -- Use isolated cron with a cheaper model for routine tasks. - -## Related - -- [Heartbeat](/gateway/heartbeat) - full heartbeat configuration -- [Cron jobs](/automation/cron-jobs) - full cron CLI and API reference -- [System](/cli/system) - system events + heartbeat controls diff --git a/docs/automation/gmail-pubsub.md b/docs/automation/gmail-pubsub.md deleted file mode 100644 index b853b99559..0000000000 --- a/docs/automation/gmail-pubsub.md +++ /dev/null @@ -1,256 +0,0 @@ ---- -summary: "Gmail Pub/Sub push wired into OpenClaw webhooks via gogcli" -read_when: - - Wiring Gmail inbox triggers to OpenClaw - - Setting up Pub/Sub push for agent wake -title: "Gmail PubSub" ---- - -# Gmail Pub/Sub -> OpenClaw - -Goal: Gmail watch -> Pub/Sub push -> `gog gmail watch serve` -> OpenClaw webhook. - -## Prereqs - -- `gcloud` installed and logged in ([install guide](https://docs.cloud.google.com/sdk/docs/install-sdk)). -- `gog` (gogcli) installed and authorized for the Gmail account ([gogcli.sh](https://gogcli.sh/)). -- OpenClaw hooks enabled (see [Webhooks](/automation/webhook)). -- `tailscale` logged in ([tailscale.com](https://tailscale.com/)). Supported setup uses Tailscale Funnel for the public HTTPS endpoint. - Other tunnel services can work, but are DIY/unsupported and require manual wiring. - Right now, Tailscale is what we support. - -Example hook config (enable Gmail preset mapping): - -```json5 -{ - hooks: { - enabled: true, - token: "OPENCLAW_HOOK_TOKEN", - path: "/hooks", - presets: ["gmail"], - }, -} -``` - -To deliver the Gmail summary to a chat surface, override the preset with a mapping -that sets `deliver` + optional `channel`/`to`: - -```json5 -{ - hooks: { - enabled: true, - token: "OPENCLAW_HOOK_TOKEN", - presets: ["gmail"], - mappings: [ - { - match: { path: "gmail" }, - action: "agent", - wakeMode: "now", - name: "Gmail", - sessionKey: "hook:gmail:{{messages[0].id}}", - messageTemplate: "New email from {{messages[0].from}}\nSubject: {{messages[0].subject}}\n{{messages[0].snippet}}\n{{messages[0].body}}", - model: "openai/gpt-5.2-mini", - deliver: true, - channel: "last", - // to: "+15551234567" - }, - ], - }, -} -``` - -If you want a fixed channel, set `channel` + `to`. Otherwise `channel: "last"` -uses the last delivery route (falls back to WhatsApp). - -To force a cheaper model for Gmail runs, set `model` in the mapping -(`provider/model` or alias). If you enforce `agents.defaults.models`, include it there. - -To set a default model and thinking level specifically for Gmail hooks, add -`hooks.gmail.model` / `hooks.gmail.thinking` in your config: - -```json5 -{ - hooks: { - gmail: { - model: "openrouter/meta-llama/llama-3.3-70b-instruct:free", - thinking: "off", - }, - }, -} -``` - -Notes: - -- Per-hook `model`/`thinking` in the mapping still overrides these defaults. -- Fallback order: `hooks.gmail.model` → `agents.defaults.model.fallbacks` → primary (auth/rate-limit/timeouts). -- If `agents.defaults.models` is set, the Gmail model must be in the allowlist. -- Gmail hook content is wrapped with external-content safety boundaries by default. - To disable (dangerous), set `hooks.gmail.allowUnsafeExternalContent: true`. - -To customize payload handling further, add `hooks.mappings` or a JS/TS transform module -under `~/.openclaw/hooks/transforms` (see [Webhooks](/automation/webhook)). - -## Wizard (recommended) - -Use the OpenClaw helper to wire everything together (installs deps on macOS via brew): - -```bash -openclaw webhooks gmail setup \ - --account openclaw@gmail.com -``` - -Defaults: - -- Uses Tailscale Funnel for the public push endpoint. -- Writes `hooks.gmail` config for `openclaw webhooks gmail run`. -- Enables the Gmail hook preset (`hooks.presets: ["gmail"]`). - -Path note: when `tailscale.mode` is enabled, OpenClaw automatically sets -`hooks.gmail.serve.path` to `/` and keeps the public path at -`hooks.gmail.tailscale.path` (default `/gmail-pubsub`) because Tailscale -strips the set-path prefix before proxying. -If you need the backend to receive the prefixed path, set -`hooks.gmail.tailscale.target` (or `--tailscale-target`) to a full URL like -`http://127.0.0.1:8788/gmail-pubsub` and match `hooks.gmail.serve.path`. - -Want a custom endpoint? Use `--push-endpoint ` or `--tailscale off`. - -Platform note: on macOS the wizard installs `gcloud`, `gogcli`, and `tailscale` -via Homebrew; on Linux install them manually first. - -Gateway auto-start (recommended): - -- When `hooks.enabled=true` and `hooks.gmail.account` is set, the Gateway starts - `gog gmail watch serve` on boot and auto-renews the watch. -- Set `OPENCLAW_SKIP_GMAIL_WATCHER=1` to opt out (useful if you run the daemon yourself). -- Do not run the manual daemon at the same time, or you will hit - `listen tcp 127.0.0.1:8788: bind: address already in use`. - -Manual daemon (starts `gog gmail watch serve` + auto-renew): - -```bash -openclaw webhooks gmail run -``` - -## One-time setup - -1. Select the GCP project **that owns the OAuth client** used by `gog`. - -```bash -gcloud auth login -gcloud config set project -``` - -Note: Gmail watch requires the Pub/Sub topic to live in the same project as the OAuth client. - -2. Enable APIs: - -```bash -gcloud services enable gmail.googleapis.com pubsub.googleapis.com -``` - -3. Create a topic: - -```bash -gcloud pubsub topics create gog-gmail-watch -``` - -4. Allow Gmail push to publish: - -```bash -gcloud pubsub topics add-iam-policy-binding gog-gmail-watch \ - --member=serviceAccount:gmail-api-push@system.gserviceaccount.com \ - --role=roles/pubsub.publisher -``` - -## Start the watch - -```bash -gog gmail watch start \ - --account openclaw@gmail.com \ - --label INBOX \ - --topic projects//topics/gog-gmail-watch -``` - -Save the `history_id` from the output (for debugging). - -## Run the push handler - -Local example (shared token auth): - -```bash -gog gmail watch serve \ - --account openclaw@gmail.com \ - --bind 127.0.0.1 \ - --port 8788 \ - --path /gmail-pubsub \ - --token \ - --hook-url http://127.0.0.1:18789/hooks/gmail \ - --hook-token OPENCLAW_HOOK_TOKEN \ - --include-body \ - --max-bytes 20000 -``` - -Notes: - -- `--token` protects the push endpoint (`x-gog-token` or `?token=`). -- `--hook-url` points to OpenClaw `/hooks/gmail` (mapped; isolated run + summary to main). -- `--include-body` and `--max-bytes` control the body snippet sent to OpenClaw. - -Recommended: `openclaw webhooks gmail run` wraps the same flow and auto-renews the watch. - -## Expose the handler (advanced, unsupported) - -If you need a non-Tailscale tunnel, wire it manually and use the public URL in the push -subscription (unsupported, no guardrails): - -```bash -cloudflared tunnel --url http://127.0.0.1:8788 --no-autoupdate -``` - -Use the generated URL as the push endpoint: - -```bash -gcloud pubsub subscriptions create gog-gmail-watch-push \ - --topic gog-gmail-watch \ - --push-endpoint "https:///gmail-pubsub?token=" -``` - -Production: use a stable HTTPS endpoint and configure Pub/Sub OIDC JWT, then run: - -```bash -gog gmail watch serve --verify-oidc --oidc-email -``` - -## Test - -Send a message to the watched inbox: - -```bash -gog gmail send \ - --account openclaw@gmail.com \ - --to openclaw@gmail.com \ - --subject "watch test" \ - --body "ping" -``` - -Check watch state and history: - -```bash -gog gmail watch status --account openclaw@gmail.com -gog gmail history --account openclaw@gmail.com --since -``` - -## Troubleshooting - -- `Invalid topicName`: project mismatch (topic not in the OAuth client project). -- `User not authorized`: missing `roles/pubsub.publisher` on the topic. -- Empty messages: Gmail push only provides `historyId`; fetch via `gog gmail history`. - -## Cleanup - -```bash -gog gmail watch stop --account openclaw@gmail.com -gcloud pubsub subscriptions delete gog-gmail-watch-push -gcloud pubsub topics delete gog-gmail-watch -``` diff --git a/docs/automation/hooks.md b/docs/automation/hooks.md deleted file mode 100644 index 66b96cd1e9..0000000000 --- a/docs/automation/hooks.md +++ /dev/null @@ -1,1001 +0,0 @@ ---- -summary: "Hooks: event-driven automation for commands and lifecycle events" -read_when: - - You want event-driven automation for /new, /reset, /stop, and agent lifecycle events - - You want to build, install, or debug hooks -title: "Hooks" ---- - -# Hooks - -Hooks provide an extensible event-driven system for automating actions in response to agent commands and events. Hooks are automatically discovered from directories and can be managed via CLI commands, similar to how skills work in OpenClaw. - -## Getting Oriented - -Hooks are small scripts that run when something happens. There are two kinds: - -- **Hooks** (this page): run inside the Gateway when agent events fire, like `/new`, `/reset`, `/stop`, or lifecycle events. -- **Webhooks**: external HTTP webhooks that let other systems trigger work in OpenClaw. See [Webhook Hooks](/automation/webhook) or use `openclaw webhooks` for Gmail helper commands. - -Hooks can also be bundled inside plugins; see [Plugins](/tools/plugin#plugin-hooks). - -Common uses: - -- Save a memory snapshot when you reset a session -- Keep an audit trail of commands for troubleshooting or compliance -- Trigger follow-up automation when a session starts or ends -- Write files into the agent workspace or call external APIs when events fire - -If you can write a small TypeScript function, you can write a hook. Hooks are discovered automatically, and you enable or disable them via the CLI. - -## Overview - -The hooks system allows you to: - -- Save session context to memory when `/new` is issued -- Log all commands for auditing -- Trigger custom automations on agent lifecycle events -- Extend OpenClaw's behavior without modifying core code - -## Getting Started - -### Bundled Hooks - -OpenClaw ships with four bundled hooks that are automatically discovered: - -- **💾 session-memory**: Saves session context to your agent workspace (default `~/.openclaw/workspace/memory/`) when you issue `/new` -- **📎 bootstrap-extra-files**: Injects additional workspace bootstrap files from configured glob/path patterns during `agent:bootstrap` -- **📝 command-logger**: Logs all command events to `~/.openclaw/logs/commands.log` -- **🚀 boot-md**: Runs `BOOT.md` when the gateway starts (requires internal hooks enabled) - -List available hooks: - -```bash -openclaw hooks list -``` - -Enable a hook: - -```bash -openclaw hooks enable session-memory -``` - -Check hook status: - -```bash -openclaw hooks check -``` - -Get detailed information: - -```bash -openclaw hooks info session-memory -``` - -### Onboarding - -During onboarding (`openclaw onboard`), you'll be prompted to enable recommended hooks. The wizard automatically discovers eligible hooks and presents them for selection. - -## Hook Discovery - -Hooks are automatically discovered from three directories (in order of precedence): - -1. **Workspace hooks**: `/hooks/` (per-agent, highest precedence) -2. **Managed hooks**: `~/.openclaw/hooks/` (user-installed, shared across workspaces) -3. **Bundled hooks**: `/dist/hooks/bundled/` (shipped with OpenClaw) - -Managed hook directories can be either a **single hook** or a **hook pack** (package directory). - -Each hook is a directory containing: - -``` -my-hook/ -├── HOOK.md # Metadata + documentation -└── handler.ts # Handler implementation -``` - -## Hook Packs (npm/archives) - -Hook packs are standard npm packages that export one or more hooks via `openclaw.hooks` in -`package.json`. Install them with: - -```bash -openclaw hooks install -``` - -Npm specs are registry-only (package name + optional version/tag). Git/URL/file specs are rejected. - -Example `package.json`: - -```json -{ - "name": "@acme/my-hooks", - "version": "0.1.0", - "openclaw": { - "hooks": ["./hooks/my-hook", "./hooks/other-hook"] - } -} -``` - -Each entry points to a hook directory containing `HOOK.md` and `handler.ts` (or `index.ts`). -Hook packs can ship dependencies; they will be installed under `~/.openclaw/hooks/`. -Each `openclaw.hooks` entry must stay inside the package directory after symlink -resolution; entries that escape are rejected. - -Security note: `openclaw hooks install` installs dependencies with `npm install --ignore-scripts` -(no lifecycle scripts). Keep hook pack dependency trees "pure JS/TS" and avoid packages that rely -on `postinstall` builds. - -## Hook Structure - -### HOOK.md Format - -The `HOOK.md` file contains metadata in YAML frontmatter plus Markdown documentation: - -```markdown ---- -name: my-hook -description: "Short description of what this hook does" -homepage: https://docs.openclaw.ai/automation/hooks#my-hook -metadata: - { "openclaw": { "emoji": "🔗", "events": ["command:new"], "requires": { "bins": ["node"] } } } ---- - -# My Hook - -Detailed documentation goes here... - -## What It Does - -- Listens for `/new` commands -- Performs some action -- Logs the result - -## Requirements - -- Node.js must be installed - -## Configuration - -No configuration needed. -``` - -### Metadata Fields - -The `metadata.openclaw` object supports: - -- **`emoji`**: Display emoji for CLI (e.g., `"💾"`) -- **`events`**: Array of events to listen for (e.g., `["command:new", "command:reset"]`) -- **`export`**: Named export to use (defaults to `"default"`) -- **`homepage`**: Documentation URL -- **`requires`**: Optional requirements - - **`bins`**: Required binaries on PATH (e.g., `["git", "node"]`) - - **`anyBins`**: At least one of these binaries must be present - - **`env`**: Required environment variables - - **`config`**: Required config paths (e.g., `["workspace.dir"]`) - - **`os`**: Required platforms (e.g., `["darwin", "linux"]`) -- **`always`**: Bypass eligibility checks (boolean) -- **`install`**: Installation methods (for bundled hooks: `[{"id":"bundled","kind":"bundled"}]`) - -### Handler Implementation - -The `handler.ts` file exports a `HookHandler` function: - -```typescript -import type { HookHandler } from "../../src/hooks/hooks.js"; - -const myHandler: HookHandler = async (event) => { - // Only trigger on 'new' command - if (event.type !== "command" || event.action !== "new") { - return; - } - - console.log(`[my-hook] New command triggered`); - console.log(` Session: ${event.sessionKey}`); - console.log(` Timestamp: ${event.timestamp.toISOString()}`); - - // Your custom logic here - - // Optionally send message to user - event.messages.push("✨ My hook executed!"); -}; - -export default myHandler; -``` - -#### Event Context - -Each event includes: - -```typescript -{ - type: 'command' | 'session' | 'agent' | 'gateway' | 'message', - action: string, // e.g., 'new', 'reset', 'stop', 'received', 'sent' - sessionKey: string, // Session identifier - timestamp: Date, // When the event occurred - messages: string[], // Push messages here to send to user - context: { - // Command events: - sessionEntry?: SessionEntry, - sessionId?: string, - sessionFile?: string, - commandSource?: string, // e.g., 'whatsapp', 'telegram' - senderId?: string, - workspaceDir?: string, - bootstrapFiles?: WorkspaceBootstrapFile[], - cfg?: OpenClawConfig, - // Message events (see Message Events section for full details): - from?: string, // message:received - to?: string, // message:sent - content?: string, - channelId?: string, - success?: boolean, // message:sent - } -} -``` - -## Event Types - -### Command Events - -Triggered when agent commands are issued: - -- **`command`**: All command events (general listener) -- **`command:new`**: When `/new` command is issued -- **`command:reset`**: When `/reset` command is issued -- **`command:stop`**: When `/stop` command is issued - -### Agent Events - -- **`agent:bootstrap`**: Before workspace bootstrap files are injected (hooks may mutate `context.bootstrapFiles`) - -### Gateway Events - -Triggered when the gateway starts: - -- **`gateway:startup`**: After channels start and hooks are loaded - -### Message Events - -Triggered when messages are received or sent: - -- **`message`**: All message events (general listener) -- **`message:received`**: When an inbound message is received from any channel -- **`message:sent`**: When an outbound message is successfully sent - -#### Message Event Context - -Message events include rich context about the message: - -```typescript -// message:received context -{ - from: string, // Sender identifier (phone number, user ID, etc.) - content: string, // Message content - timestamp?: number, // Unix timestamp when received - channelId: string, // Channel (e.g., "whatsapp", "telegram", "discord") - accountId?: string, // Provider account ID for multi-account setups - conversationId?: string, // Chat/conversation ID - messageId?: string, // Message ID from the provider - metadata?: { // Additional provider-specific data - to?: string, - provider?: string, - surface?: string, - threadId?: string, - senderId?: string, - senderName?: string, - senderUsername?: string, - senderE164?: string, - } -} - -// message:sent context -{ - to: string, // Recipient identifier - content: string, // Message content that was sent - success: boolean, // Whether the send succeeded - error?: string, // Error message if sending failed - channelId: string, // Channel (e.g., "whatsapp", "telegram", "discord") - accountId?: string, // Provider account ID - conversationId?: string, // Chat/conversation ID - messageId?: string, // Message ID returned by the provider -} -``` - -#### Example: Message Logger Hook - -```typescript -import type { HookHandler } from "../../src/hooks/hooks.js"; -import { isMessageReceivedEvent, isMessageSentEvent } from "../../src/hooks/internal-hooks.js"; - -const handler: HookHandler = async (event) => { - if (isMessageReceivedEvent(event)) { - console.log(`[message-logger] Received from ${event.context.from}: ${event.context.content}`); - } else if (isMessageSentEvent(event)) { - console.log(`[message-logger] Sent to ${event.context.to}: ${event.context.content}`); - } -}; - -export default handler; -``` - -### Tool Result Hooks (Plugin API) - -These hooks are not event-stream listeners; they let plugins synchronously adjust tool results before OpenClaw persists them. - -- **`tool_result_persist`**: transform tool results before they are written to the session transcript. Must be synchronous; return the updated tool result payload or `undefined` to keep it as-is. See [Agent Loop](/concepts/agent-loop). - -### Future Events - -Planned event types: - -- **`session:start`**: When a new session begins -- **`session:end`**: When a session ends -- **`agent:error`**: When an agent encounters an error - -## Creating Custom Hooks - -### 1. Choose Location - -- **Workspace hooks** (`/hooks/`): Per-agent, highest precedence -- **Managed hooks** (`~/.openclaw/hooks/`): Shared across workspaces - -### 2. Create Directory Structure - -```bash -mkdir -p ~/.openclaw/hooks/my-hook -cd ~/.openclaw/hooks/my-hook -``` - -### 3. Create HOOK.md - -```markdown ---- -name: my-hook -description: "Does something useful" -metadata: { "openclaw": { "emoji": "🎯", "events": ["command:new"] } } ---- - -# My Custom Hook - -This hook does something useful when you issue `/new`. -``` - -### 4. Create handler.ts - -```typescript -import type { HookHandler } from "../../src/hooks/hooks.js"; - -const handler: HookHandler = async (event) => { - if (event.type !== "command" || event.action !== "new") { - return; - } - - console.log("[my-hook] Running!"); - // Your logic here -}; - -export default handler; -``` - -### 5. Enable and Test - -```bash -# Verify hook is discovered -openclaw hooks list - -# Enable it -openclaw hooks enable my-hook - -# Restart your gateway process (menu bar app restart on macOS, or restart your dev process) - -# Trigger the event -# Send /new via your messaging channel -``` - -## Configuration - -### New Config Format (Recommended) - -```json -{ - "hooks": { - "internal": { - "enabled": true, - "entries": { - "session-memory": { "enabled": true }, - "command-logger": { "enabled": false } - } - } - } -} -``` - -### Per-Hook Configuration - -Hooks can have custom configuration: - -```json -{ - "hooks": { - "internal": { - "enabled": true, - "entries": { - "my-hook": { - "enabled": true, - "env": { - "MY_CUSTOM_VAR": "value" - } - } - } - } - } -} -``` - -### Extra Directories - -Load hooks from additional directories: - -```json -{ - "hooks": { - "internal": { - "enabled": true, - "load": { - "extraDirs": ["/path/to/more/hooks"] - } - } - } -} -``` - -### Legacy Config Format (Still Supported) - -The old config format still works for backwards compatibility: - -```json -{ - "hooks": { - "internal": { - "enabled": true, - "handlers": [ - { - "event": "command:new", - "module": "./hooks/handlers/my-handler.ts", - "export": "default" - } - ] - } - } -} -``` - -Note: `module` must be a workspace-relative path. Absolute paths and traversal outside the workspace are rejected. - -**Migration**: Use the new discovery-based system for new hooks. Legacy handlers are loaded after directory-based hooks. - -## CLI Commands - -### List Hooks - -```bash -# List all hooks -openclaw hooks list - -# Show only eligible hooks -openclaw hooks list --eligible - -# Verbose output (show missing requirements) -openclaw hooks list --verbose - -# JSON output -openclaw hooks list --json -``` - -### Hook Information - -```bash -# Show detailed info about a hook -openclaw hooks info session-memory - -# JSON output -openclaw hooks info session-memory --json -``` - -### Check Eligibility - -```bash -# Show eligibility summary -openclaw hooks check - -# JSON output -openclaw hooks check --json -``` - -### Enable/Disable - -```bash -# Enable a hook -openclaw hooks enable session-memory - -# Disable a hook -openclaw hooks disable command-logger -``` - -## Bundled hook reference - -### session-memory - -Saves session context to memory when you issue `/new`. - -**Events**: `command:new` - -**Requirements**: `workspace.dir` must be configured - -**Output**: `/memory/YYYY-MM-DD-slug.md` (defaults to `~/.openclaw/workspace`) - -**What it does**: - -1. Uses the pre-reset session entry to locate the correct transcript -2. Extracts the last 15 lines of conversation -3. Uses LLM to generate a descriptive filename slug -4. Saves session metadata to a dated memory file - -**Example output**: - -```markdown -# Session: 2026-01-16 14:30:00 UTC - -- **Session Key**: agent:main:main -- **Session ID**: abc123def456 -- **Source**: telegram -``` - -**Filename examples**: - -- `2026-01-16-vendor-pitch.md` -- `2026-01-16-api-design.md` -- `2026-01-16-1430.md` (fallback timestamp if slug generation fails) - -**Enable**: - -```bash -openclaw hooks enable session-memory -``` - -### bootstrap-extra-files - -Injects additional bootstrap files (for example monorepo-local `AGENTS.md` / `TOOLS.md`) during `agent:bootstrap`. - -**Events**: `agent:bootstrap` - -**Requirements**: `workspace.dir` must be configured - -**Output**: No files written; bootstrap context is modified in-memory only. - -**Config**: - -```json -{ - "hooks": { - "internal": { - "enabled": true, - "entries": { - "bootstrap-extra-files": { - "enabled": true, - "paths": ["packages/*/AGENTS.md", "packages/*/TOOLS.md"] - } - } - } - } -} -``` - -**Notes**: - -- Paths are resolved relative to workspace. -- Files must stay inside workspace (realpath-checked). -- Only recognized bootstrap basenames are loaded. -- Subagent allowlist is preserved (`AGENTS.md` and `TOOLS.md` only). - -**Enable**: - -```bash -openclaw hooks enable bootstrap-extra-files -``` - -### command-logger - -Logs all command events to a centralized audit file. - -**Events**: `command` - -**Requirements**: None - -**Output**: `~/.openclaw/logs/commands.log` - -**What it does**: - -1. Captures event details (command action, timestamp, session key, sender ID, source) -2. Appends to log file in JSONL format -3. Runs silently in the background - -**Example log entries**: - -```jsonl -{"timestamp":"2026-01-16T14:30:00.000Z","action":"new","sessionKey":"agent:main:main","senderId":"+1234567890","source":"telegram"} -{"timestamp":"2026-01-16T15:45:22.000Z","action":"stop","sessionKey":"agent:main:main","senderId":"user@example.com","source":"whatsapp"} -``` - -**View logs**: - -```bash -# View recent commands -tail -n 20 ~/.openclaw/logs/commands.log - -# Pretty-print with jq -cat ~/.openclaw/logs/commands.log | jq . - -# Filter by action -grep '"action":"new"' ~/.openclaw/logs/commands.log | jq . -``` - -**Enable**: - -```bash -openclaw hooks enable command-logger -``` - -### boot-md - -Runs `BOOT.md` when the gateway starts (after channels start). -Internal hooks must be enabled for this to run. - -**Events**: `gateway:startup` - -**Requirements**: `workspace.dir` must be configured - -**What it does**: - -1. Reads `BOOT.md` from your workspace -2. Runs the instructions via the agent runner -3. Sends any requested outbound messages via the message tool - -**Enable**: - -```bash -openclaw hooks enable boot-md -``` - -## Best Practices - -### Keep Handlers Fast - -Hooks run during command processing. Keep them lightweight: - -```typescript -// ✓ Good - async work, returns immediately -const handler: HookHandler = async (event) => { - void processInBackground(event); // Fire and forget -}; - -// ✗ Bad - blocks command processing -const handler: HookHandler = async (event) => { - await slowDatabaseQuery(event); - await evenSlowerAPICall(event); -}; -``` - -### Handle Errors Gracefully - -Always wrap risky operations: - -```typescript -const handler: HookHandler = async (event) => { - try { - await riskyOperation(event); - } catch (err) { - console.error("[my-handler] Failed:", err instanceof Error ? err.message : String(err)); - // Don't throw - let other handlers run - } -}; -``` - -### Filter Events Early - -Return early if the event isn't relevant: - -```typescript -const handler: HookHandler = async (event) => { - // Only handle 'new' commands - if (event.type !== "command" || event.action !== "new") { - return; - } - - // Your logic here -}; -``` - -### Use Specific Event Keys - -Specify exact events in metadata when possible: - -```yaml -metadata: { "openclaw": { "events": ["command:new"] } } # Specific -``` - -Rather than: - -```yaml -metadata: { "openclaw": { "events": ["command"] } } # General - more overhead -``` - -## Debugging - -### Enable Hook Logging - -The gateway logs hook loading at startup: - -``` -Registered hook: session-memory -> command:new -Registered hook: bootstrap-extra-files -> agent:bootstrap -Registered hook: command-logger -> command -Registered hook: boot-md -> gateway:startup -``` - -### Check Discovery - -List all discovered hooks: - -```bash -openclaw hooks list --verbose -``` - -### Check Registration - -In your handler, log when it's called: - -```typescript -const handler: HookHandler = async (event) => { - console.log("[my-handler] Triggered:", event.type, event.action); - // Your logic -}; -``` - -### Verify Eligibility - -Check why a hook isn't eligible: - -```bash -openclaw hooks info my-hook -``` - -Look for missing requirements in the output. - -## Testing - -### Gateway Logs - -Monitor gateway logs to see hook execution: - -```bash -# macOS -./scripts/clawlog.sh -f - -# Other platforms -tail -f ~/.openclaw/gateway.log -``` - -### Test Hooks Directly - -Test your handlers in isolation: - -```typescript -import { test } from "vitest"; -import { createHookEvent } from "./src/hooks/hooks.js"; -import myHandler from "./hooks/my-hook/handler.js"; - -test("my handler works", async () => { - const event = createHookEvent("command", "new", "test-session", { - foo: "bar", - }); - - await myHandler(event); - - // Assert side effects -}); -``` - -## Architecture - -### Core Components - -- **`src/hooks/types.ts`**: Type definitions -- **`src/hooks/workspace.ts`**: Directory scanning and loading -- **`src/hooks/frontmatter.ts`**: HOOK.md metadata parsing -- **`src/hooks/config.ts`**: Eligibility checking -- **`src/hooks/hooks-status.ts`**: Status reporting -- **`src/hooks/loader.ts`**: Dynamic module loader -- **`src/cli/hooks-cli.ts`**: CLI commands -- **`src/gateway/server-startup.ts`**: Loads hooks at gateway start -- **`src/auto-reply/reply/commands-core.ts`**: Triggers command events - -### Discovery Flow - -``` -Gateway startup - ↓ -Scan directories (workspace → managed → bundled) - ↓ -Parse HOOK.md files - ↓ -Check eligibility (bins, env, config, os) - ↓ -Load handlers from eligible hooks - ↓ -Register handlers for events -``` - -### Event Flow - -``` -User sends /new - ↓ -Command validation - ↓ -Create hook event - ↓ -Trigger hook (all registered handlers) - ↓ -Command processing continues - ↓ -Session reset -``` - -## Troubleshooting - -### Hook Not Discovered - -1. Check directory structure: - - ```bash - ls -la ~/.openclaw/hooks/my-hook/ - # Should show: HOOK.md, handler.ts - ``` - -2. Verify HOOK.md format: - - ```bash - cat ~/.openclaw/hooks/my-hook/HOOK.md - # Should have YAML frontmatter with name and metadata - ``` - -3. List all discovered hooks: - - ```bash - openclaw hooks list - ``` - -### Hook Not Eligible - -Check requirements: - -```bash -openclaw hooks info my-hook -``` - -Look for missing: - -- Binaries (check PATH) -- Environment variables -- Config values -- OS compatibility - -### Hook Not Executing - -1. Verify hook is enabled: - - ```bash - openclaw hooks list - # Should show ✓ next to enabled hooks - ``` - -2. Restart your gateway process so hooks reload. - -3. Check gateway logs for errors: - - ```bash - ./scripts/clawlog.sh | grep hook - ``` - -### Handler Errors - -Check for TypeScript/import errors: - -```bash -# Test import directly -node -e "import('./path/to/handler.ts').then(console.log)" -``` - -## Migration Guide - -### From Legacy Config to Discovery - -**Before**: - -```json -{ - "hooks": { - "internal": { - "enabled": true, - "handlers": [ - { - "event": "command:new", - "module": "./hooks/handlers/my-handler.ts" - } - ] - } - } -} -``` - -**After**: - -1. Create hook directory: - - ```bash - mkdir -p ~/.openclaw/hooks/my-hook - mv ./hooks/handlers/my-handler.ts ~/.openclaw/hooks/my-hook/handler.ts - ``` - -2. Create HOOK.md: - - ```markdown - --- - name: my-hook - description: "My custom hook" - metadata: { "openclaw": { "emoji": "🎯", "events": ["command:new"] } } - --- - - # My Hook - - Does something useful. - ``` - -3. Update config: - - ```json - { - "hooks": { - "internal": { - "enabled": true, - "entries": { - "my-hook": { "enabled": true } - } - } - } - } - ``` - -4. Verify and restart your gateway process: - - ```bash - openclaw hooks list - # Should show: 🎯 my-hook ✓ - ``` - -**Benefits of migration**: - -- Automatic discovery -- CLI management -- Eligibility checking -- Better documentation -- Consistent structure - -## See Also - -- [CLI Reference: hooks](/cli/hooks) -- [Bundled Hooks README](https://github.com/openclaw/openclaw/tree/main/src/hooks/bundled) -- [Webhook Hooks](/automation/webhook) -- [Configuration](/gateway/configuration#hooks) diff --git a/docs/automation/poll.md b/docs/automation/poll.md deleted file mode 100644 index fab0b0e073..0000000000 --- a/docs/automation/poll.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -summary: "Poll sending via gateway + CLI" -read_when: - - Adding or modifying poll support - - Debugging poll sends from the CLI or gateway -title: "Polls" ---- - -# Polls - -## Supported channels - -- WhatsApp (web channel) -- Discord -- MS Teams (Adaptive Cards) - -## CLI - -```bash -# WhatsApp -openclaw message poll --target +15555550123 \ - --poll-question "Lunch today?" --poll-option "Yes" --poll-option "No" --poll-option "Maybe" -openclaw message poll --target 123456789@g.us \ - --poll-question "Meeting time?" --poll-option "10am" --poll-option "2pm" --poll-option "4pm" --poll-multi - -# Discord -openclaw message poll --channel discord --target channel:123456789 \ - --poll-question "Snack?" --poll-option "Pizza" --poll-option "Sushi" -openclaw message poll --channel discord --target channel:123456789 \ - --poll-question "Plan?" --poll-option "A" --poll-option "B" --poll-duration-hours 48 - -# MS Teams -openclaw message poll --channel msteams --target conversation:19:abc@thread.tacv2 \ - --poll-question "Lunch?" --poll-option "Pizza" --poll-option "Sushi" -``` - -Options: - -- `--channel`: `whatsapp` (default), `discord`, or `msteams` -- `--poll-multi`: allow selecting multiple options -- `--poll-duration-hours`: Discord-only (defaults to 24 when omitted) - -## Gateway RPC - -Method: `poll` - -Params: - -- `to` (string, required) -- `question` (string, required) -- `options` (string[], required) -- `maxSelections` (number, optional) -- `durationHours` (number, optional) -- `channel` (string, optional, default: `whatsapp`) -- `idempotencyKey` (string, required) - -## Channel differences - -- WhatsApp: 2-12 options, `maxSelections` must be within option count, ignores `durationHours`. -- Discord: 2-10 options, `durationHours` clamped to 1-768 hours (default 24). `maxSelections > 1` enables multi-select; Discord does not support a strict selection count. -- MS Teams: Adaptive Card polls (OpenClaw-managed). No native poll API; `durationHours` is ignored. - -## Agent tool (Message) - -Use the `message` tool with `poll` action (`to`, `pollQuestion`, `pollOption`, optional `pollMulti`, `pollDurationHours`, `channel`). - -Note: Discord has no “pick exactly N” mode; `pollMulti` maps to multi-select. -Teams polls are rendered as Adaptive Cards and require the gateway to stay online -to record votes in `~/.openclaw/msteams-polls.json`. diff --git a/docs/automation/troubleshooting.md b/docs/automation/troubleshooting.md deleted file mode 100644 index a189d80522..0000000000 --- a/docs/automation/troubleshooting.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -summary: "Troubleshoot cron and heartbeat scheduling and delivery" -read_when: - - Cron did not run - - Cron ran but no message was delivered - - Heartbeat seems silent or skipped -title: "Automation Troubleshooting" ---- - -# Automation troubleshooting - -Use this page for scheduler and delivery issues (`cron` + `heartbeat`). - -## Command ladder - -```bash -openclaw status -openclaw gateway status -openclaw logs --follow -openclaw doctor -openclaw channels status --probe -``` - -Then run automation checks: - -```bash -openclaw cron status -openclaw cron list -openclaw system heartbeat last -``` - -## Cron not firing - -```bash -openclaw cron status -openclaw cron list -openclaw cron runs --id --limit 20 -openclaw logs --follow -``` - -Good output looks like: - -- `cron status` reports enabled and a future `nextWakeAtMs`. -- Job is enabled and has a valid schedule/timezone. -- `cron runs` shows `ok` or explicit skip reason. - -Common signatures: - -- `cron: scheduler disabled; jobs will not run automatically` → cron disabled in config/env. -- `cron: timer tick failed` → scheduler tick crashed; inspect surrounding stack/log context. -- `reason: not-due` in run output → manual run called without `--force` and job not due yet. - -## Cron fired but no delivery - -```bash -openclaw cron runs --id --limit 20 -openclaw cron list -openclaw channels status --probe -openclaw logs --follow -``` - -Good output looks like: - -- Run status is `ok`. -- Delivery mode/target are set for isolated jobs. -- Channel probe reports target channel connected. - -Common signatures: - -- Run succeeded but delivery mode is `none` → no external message is expected. -- Delivery target missing/invalid (`channel`/`to`) → run may succeed internally but skip outbound. -- Channel auth errors (`unauthorized`, `missing_scope`, `Forbidden`) → delivery blocked by channel credentials/permissions. - -## Heartbeat suppressed or skipped - -```bash -openclaw system heartbeat last -openclaw logs --follow -openclaw config get agents.defaults.heartbeat -openclaw channels status --probe -``` - -Good output looks like: - -- Heartbeat enabled with non-zero interval. -- Last heartbeat result is `ran` (or skip reason is understood). - -Common signatures: - -- `heartbeat skipped` with `reason=quiet-hours` → outside `activeHours`. -- `requests-in-flight` → main lane busy; heartbeat deferred. -- `empty-heartbeat-file` → interval heartbeat skipped because `HEARTBEAT.md` has no actionable content and no tagged cron event is queued. -- `no-heartbeat-file` → interval heartbeat skipped because `HEARTBEAT.md` is missing and no tagged cron event is queued. -- `alerts-disabled` → visibility settings suppress outbound heartbeat messages. - -## Timezone and activeHours gotchas - -```bash -openclaw config get agents.defaults.heartbeat.activeHours -openclaw config get agents.defaults.heartbeat.activeHours.timezone -openclaw config get agents.defaults.userTimezone || echo "agents.defaults.userTimezone not set" -openclaw cron list -openclaw logs --follow -``` - -Quick rules: - -- `Config path not found: agents.defaults.userTimezone` means the key is unset; heartbeat falls back to host timezone (or `activeHours.timezone` if set). -- Cron without `--tz` uses gateway host timezone. -- Heartbeat `activeHours` uses configured timezone resolution (`user`, `local`, or explicit IANA tz). -- ISO timestamps without timezone are treated as UTC for cron `at` schedules. - -Common signatures: - -- Jobs run at the wrong wall-clock time after host timezone changes. -- Heartbeat always skipped during your daytime because `activeHours.timezone` is wrong. - -Related: - -- [/automation/cron-jobs](/automation/cron-jobs) -- [/gateway/heartbeat](/gateway/heartbeat) -- [/automation/cron-vs-heartbeat](/automation/cron-vs-heartbeat) -- [/concepts/timezone](/concepts/timezone) diff --git a/docs/automation/webhook.md b/docs/automation/webhook.md deleted file mode 100644 index 8072b4a1a3..0000000000 --- a/docs/automation/webhook.md +++ /dev/null @@ -1,215 +0,0 @@ ---- -summary: "Webhook ingress for wake and isolated agent runs" -read_when: - - Adding or changing webhook endpoints - - Wiring external systems into OpenClaw -title: "Webhooks" ---- - -# Webhooks - -Gateway can expose a small HTTP webhook endpoint for external triggers. - -## Enable - -```json5 -{ - hooks: { - enabled: true, - token: "shared-secret", - path: "/hooks", - // Optional: restrict explicit `agentId` routing to this allowlist. - // Omit or include "*" to allow any agent. - // Set [] to deny all explicit `agentId` routing. - allowedAgentIds: ["hooks", "main"], - }, -} -``` - -Notes: - -- `hooks.token` is required when `hooks.enabled=true`. -- `hooks.path` defaults to `/hooks`. - -## Auth - -Every request must include the hook token. Prefer headers: - -- `Authorization: Bearer ` (recommended) -- `x-openclaw-token: ` -- Query-string tokens are rejected (`?token=...` returns `400`). - -## Endpoints - -### `POST /hooks/wake` - -Payload: - -```json -{ "text": "System line", "mode": "now" } -``` - -- `text` **required** (string): The description of the event (e.g., "New email received"). -- `mode` optional (`now` | `next-heartbeat`): Whether to trigger an immediate heartbeat (default `now`) or wait for the next periodic check. - -Effect: - -- Enqueues a system event for the **main** session -- If `mode=now`, triggers an immediate heartbeat - -### `POST /hooks/agent` - -Payload: - -```json -{ - "message": "Run this", - "name": "Email", - "agentId": "hooks", - "sessionKey": "hook:email:msg-123", - "wakeMode": "now", - "deliver": true, - "channel": "last", - "to": "+15551234567", - "model": "openai/gpt-5.2-mini", - "thinking": "low", - "timeoutSeconds": 120 -} -``` - -- `message` **required** (string): The prompt or message for the agent to process. -- `name` optional (string): Human-readable name for the hook (e.g., "GitHub"), used as a prefix in session summaries. -- `agentId` optional (string): Route this hook to a specific agent. Unknown IDs fall back to the default agent. When set, the hook runs using the resolved agent's workspace and configuration. -- `sessionKey` optional (string): The key used to identify the agent's session. By default this field is rejected unless `hooks.allowRequestSessionKey=true`. -- `wakeMode` optional (`now` | `next-heartbeat`): Whether to trigger an immediate heartbeat (default `now`) or wait for the next periodic check. -- `deliver` optional (boolean): If `true`, the agent's response will be sent to the messaging channel. Defaults to `true`. Responses that are only heartbeat acknowledgments are automatically skipped. -- `channel` optional (string): The messaging channel for delivery. One of: `last`, `whatsapp`, `telegram`, `discord`, `slack`, `mattermost` (plugin), `signal`, `imessage`, `msteams`. Defaults to `last`. -- `to` optional (string): The recipient identifier for the channel (e.g., phone number for WhatsApp/Signal, chat ID for Telegram, channel ID for Discord/Slack/Mattermost (plugin), conversation ID for MS Teams). Defaults to the last recipient in the main session. -- `model` optional (string): Model override (e.g., `anthropic/claude-3-5-sonnet` or an alias). Must be in the allowed model list if restricted. -- `thinking` optional (string): Thinking level override (e.g., `low`, `medium`, `high`). -- `timeoutSeconds` optional (number): Maximum duration for the agent run in seconds. - -Effect: - -- Runs an **isolated** agent turn (own session key) -- Always posts a summary into the **main** session -- If `wakeMode=now`, triggers an immediate heartbeat - -## Session key policy (breaking change) - -`/hooks/agent` payload `sessionKey` overrides are disabled by default. - -- Recommended: set a fixed `hooks.defaultSessionKey` and keep request overrides off. -- Optional: allow request overrides only when needed, and restrict prefixes. - -Recommended config: - -```json5 -{ - hooks: { - enabled: true, - token: "${OPENCLAW_HOOKS_TOKEN}", - defaultSessionKey: "hook:ingress", - allowRequestSessionKey: false, - allowedSessionKeyPrefixes: ["hook:"], - }, -} -``` - -Compatibility config (legacy behavior): - -```json5 -{ - hooks: { - enabled: true, - token: "${OPENCLAW_HOOKS_TOKEN}", - allowRequestSessionKey: true, - allowedSessionKeyPrefixes: ["hook:"], // strongly recommended - }, -} -``` - -### `POST /hooks/` (mapped) - -Custom hook names are resolved via `hooks.mappings` (see configuration). A mapping can -turn arbitrary payloads into `wake` or `agent` actions, with optional templates or -code transforms. - -Mapping options (summary): - -- `hooks.presets: ["gmail"]` enables the built-in Gmail mapping. -- `hooks.mappings` lets you define `match`, `action`, and templates in config. -- `hooks.transformsDir` + `transform.module` loads a JS/TS module for custom logic. - - `hooks.transformsDir` (if set) must stay within the transforms root under your OpenClaw config directory (typically `~/.openclaw/hooks/transforms`). - - `transform.module` must resolve within the effective transforms directory (traversal/escape paths are rejected). -- Use `match.source` to keep a generic ingest endpoint (payload-driven routing). -- TS transforms require a TS loader (e.g. `bun` or `tsx`) or precompiled `.js` at runtime. -- Set `deliver: true` + `channel`/`to` on mappings to route replies to a chat surface - (`channel` defaults to `last` and falls back to WhatsApp). -- `agentId` routes the hook to a specific agent; unknown IDs fall back to the default agent. -- `hooks.allowedAgentIds` restricts explicit `agentId` routing. Omit it (or include `*`) to allow any agent. Set `[]` to deny explicit `agentId` routing. -- `hooks.defaultSessionKey` sets the default session for hook agent runs when no explicit key is provided. -- `hooks.allowRequestSessionKey` controls whether `/hooks/agent` payloads may set `sessionKey` (default: `false`). -- `hooks.allowedSessionKeyPrefixes` optionally restricts explicit `sessionKey` values from request payloads and mappings. -- `allowUnsafeExternalContent: true` disables the external content safety wrapper for that hook - (dangerous; only for trusted internal sources). -- `openclaw webhooks gmail setup` writes `hooks.gmail` config for `openclaw webhooks gmail run`. - See [Gmail Pub/Sub](/automation/gmail-pubsub) for the full Gmail watch flow. - -## Responses - -- `200` for `/hooks/wake` -- `202` for `/hooks/agent` (async run started) -- `401` on auth failure -- `429` after repeated auth failures from the same client (check `Retry-After`) -- `400` on invalid payload -- `413` on oversized payloads - -## Examples - -```bash -curl -X POST http://127.0.0.1:18789/hooks/wake \ - -H 'Authorization: Bearer SECRET' \ - -H 'Content-Type: application/json' \ - -d '{"text":"New email received","mode":"now"}' -``` - -```bash -curl -X POST http://127.0.0.1:18789/hooks/agent \ - -H 'x-openclaw-token: SECRET' \ - -H 'Content-Type: application/json' \ - -d '{"message":"Summarize inbox","name":"Email","wakeMode":"next-heartbeat"}' -``` - -### Use a different model - -Add `model` to the agent payload (or mapping) to override the model for that run: - -```bash -curl -X POST http://127.0.0.1:18789/hooks/agent \ - -H 'x-openclaw-token: SECRET' \ - -H 'Content-Type: application/json' \ - -d '{"message":"Summarize inbox","name":"Email","model":"openai/gpt-5.2-mini"}' -``` - -If you enforce `agents.defaults.models`, make sure the override model is included there. - -```bash -curl -X POST http://127.0.0.1:18789/hooks/gmail \ - -H 'Authorization: Bearer SECRET' \ - -H 'Content-Type: application/json' \ - -d '{"source":"gmail","messages":[{"from":"Ada","subject":"Hello","snippet":"Hi"}]}' -``` - -## Security - -- Keep hook endpoints behind loopback, tailnet, or trusted reverse proxy. -- Use a dedicated hook token; do not reuse gateway auth tokens. -- Repeated auth failures are rate-limited per client address to slow brute-force attempts. -- If you use multi-agent routing, set `hooks.allowedAgentIds` to limit explicit `agentId` selection. -- Keep `hooks.allowRequestSessionKey=false` unless you require caller-selected sessions. -- If you enable request `sessionKey`, restrict `hooks.allowedSessionKeyPrefixes` (for example, `["hook:"]`). -- Avoid including sensitive raw payloads in webhook logs. -- Hook payloads are treated as untrusted and wrapped with safety boundaries by default. - If you must disable this for a specific hook, set `allowUnsafeExternalContent: true` - in that hook's mapping (dangerous). diff --git a/docs/brave-search.md b/docs/brave-search.md deleted file mode 100644 index ba18a6c552..0000000000 --- a/docs/brave-search.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -summary: "Brave Search API setup for web_search" -read_when: - - You want to use Brave Search for web_search - - You need a BRAVE_API_KEY or plan details -title: "Brave Search" ---- - -# Brave Search API - -OpenClaw uses Brave Search as the default provider for `web_search`. - -## Get an API key - -1. Create a Brave Search API account at [https://brave.com/search/api/](https://brave.com/search/api/) -2. In the dashboard, choose the **Data for Search** plan and generate an API key. -3. Store the key in config (recommended) or set `BRAVE_API_KEY` in the Gateway environment. - -## Config example - -```json5 -{ - tools: { - web: { - search: { - provider: "brave", - apiKey: "BRAVE_API_KEY_HERE", - maxResults: 5, - timeoutSeconds: 30, - }, - }, - }, -} -``` - -## Notes - -- The Data for AI plan is **not** compatible with `web_search`. -- Brave provides a free tier plus paid plans; check the Brave API portal for current limits. - -See [Web tools](/tools/web) for the full web_search configuration. diff --git a/docs/channels/bluebubbles.md b/docs/channels/bluebubbles.md deleted file mode 100644 index fd677a1d58..0000000000 --- a/docs/channels/bluebubbles.md +++ /dev/null @@ -1,345 +0,0 @@ ---- -summary: "iMessage via BlueBubbles macOS server (REST send/receive, typing, reactions, pairing, advanced actions)." -read_when: - - Setting up BlueBubbles channel - - Troubleshooting webhook pairing - - Configuring iMessage on macOS -title: "BlueBubbles" ---- - -# BlueBubbles (macOS REST) - -Status: bundled plugin that talks to the BlueBubbles macOS server over HTTP. **Recommended for iMessage integration** due to its richer API and easier setup compared to the legacy imsg channel. - -## Overview - -- Runs on macOS via the BlueBubbles helper app ([bluebubbles.app](https://bluebubbles.app)). -- Recommended/tested: macOS Sequoia (15). macOS Tahoe (26) works; edit is currently broken on Tahoe, and group icon updates may report success but not sync. -- OpenClaw talks to it through its REST API (`GET /api/v1/ping`, `POST /message/text`, `POST /chat/:id/*`). -- Incoming messages arrive via webhooks; outgoing replies, typing indicators, read receipts, and tapbacks are REST calls. -- Attachments and stickers are ingested as inbound media (and surfaced to the agent when possible). -- Pairing/allowlist works the same way as other channels (`/channels/pairing` etc) with `channels.bluebubbles.allowFrom` + pairing codes. -- Reactions are surfaced as system events just like Slack/Telegram so agents can "mention" them before replying. -- Advanced features: edit, unsend, reply threading, message effects, group management. - -## Quick start - -1. Install the BlueBubbles server on your Mac (follow the instructions at [bluebubbles.app/install](https://bluebubbles.app/install)). -2. In the BlueBubbles config, enable the web API and set a password. -3. Run `openclaw onboard` and select BlueBubbles, or configure manually: - - ```json5 - { - channels: { - bluebubbles: { - enabled: true, - serverUrl: "http://192.168.1.100:1234", - password: "example-password", - webhookPath: "/bluebubbles-webhook", - }, - }, - } - ``` - -4. Point BlueBubbles webhooks to your gateway (example: `https://your-gateway-host:3000/bluebubbles-webhook?password=`). -5. Start the gateway; it will register the webhook handler and start pairing. - -Security note: - -- Always set a webhook password. If you expose the gateway through a reverse proxy (Tailscale Serve/Funnel, nginx, Cloudflare Tunnel, ngrok), the proxy may connect to the gateway over loopback. The BlueBubbles webhook handler treats requests with forwarding headers as proxied and will not accept passwordless webhooks. - -## Keeping Messages.app alive (VM / headless setups) - -Some macOS VM / always-on setups can end up with Messages.app going “idle” (incoming events stop until the app is opened/foregrounded). A simple workaround is to **poke Messages every 5 minutes** using an AppleScript + LaunchAgent. - -### 1) Save the AppleScript - -Save this as: - -- `~/Scripts/poke-messages.scpt` - -Example script (non-interactive; does not steal focus): - -```applescript -try - tell application "Messages" - if not running then - launch - end if - - -- Touch the scripting interface to keep the process responsive. - set _chatCount to (count of chats) - end tell -on error - -- Ignore transient failures (first-run prompts, locked session, etc). -end try -``` - -### 2) Install a LaunchAgent - -Save this as: - -- `~/Library/LaunchAgents/com.user.poke-messages.plist` - -```xml - - - - - Label - com.user.poke-messages - - ProgramArguments - - /bin/bash - -lc - /usr/bin/osascript "$HOME/Scripts/poke-messages.scpt" - - - RunAtLoad - - - StartInterval - 300 - - StandardOutPath - /tmp/poke-messages.log - StandardErrorPath - /tmp/poke-messages.err - - -``` - -Notes: - -- This runs **every 300 seconds** and **on login**. -- The first run may trigger macOS **Automation** prompts (`osascript` → Messages). Approve them in the same user session that runs the LaunchAgent. - -Load it: - -```bash -launchctl unload ~/Library/LaunchAgents/com.user.poke-messages.plist 2>/dev/null || true -launchctl load ~/Library/LaunchAgents/com.user.poke-messages.plist -``` - -## Onboarding - -BlueBubbles is available in the interactive setup wizard: - -``` -openclaw onboard -``` - -The wizard prompts for: - -- **Server URL** (required): BlueBubbles server address (e.g., `http://192.168.1.100:1234`) -- **Password** (required): API password from BlueBubbles Server settings -- **Webhook path** (optional): Defaults to `/bluebubbles-webhook` -- **DM policy**: pairing, allowlist, open, or disabled -- **Allow list**: Phone numbers, emails, or chat targets - -You can also add BlueBubbles via CLI: - -``` -openclaw channels add bluebubbles --http-url http://192.168.1.100:1234 --password -``` - -## Access control (DMs + groups) - -DMs: - -- Default: `channels.bluebubbles.dmPolicy = "pairing"`. -- Unknown senders receive a pairing code; messages are ignored until approved (codes expire after 1 hour). -- Approve via: - - `openclaw pairing list bluebubbles` - - `openclaw pairing approve bluebubbles ` -- Pairing is the default token exchange. Details: [Pairing](/channels/pairing) - -Groups: - -- `channels.bluebubbles.groupPolicy = open | allowlist | disabled` (default: `allowlist`). -- `channels.bluebubbles.groupAllowFrom` controls who can trigger in groups when `allowlist` is set. - -### Mention gating (groups) - -BlueBubbles supports mention gating for group chats, matching iMessage/WhatsApp behavior: - -- Uses `agents.list[].groupChat.mentionPatterns` (or `messages.groupChat.mentionPatterns`) to detect mentions. -- When `requireMention` is enabled for a group, the agent only responds when mentioned. -- Control commands from authorized senders bypass mention gating. - -Per-group configuration: - -```json5 -{ - channels: { - bluebubbles: { - groupPolicy: "allowlist", - groupAllowFrom: ["+15555550123"], - groups: { - "*": { requireMention: true }, // default for all groups - "iMessage;-;chat123": { requireMention: false }, // override for specific group - }, - }, - }, -} -``` - -### Command gating - -- Control commands (e.g., `/config`, `/model`) require authorization. -- Uses `allowFrom` and `groupAllowFrom` to determine command authorization. -- Authorized senders can run control commands even without mentioning in groups. - -## Typing + read receipts - -- **Typing indicators**: Sent automatically before and during response generation. -- **Read receipts**: Controlled by `channels.bluebubbles.sendReadReceipts` (default: `true`). -- **Typing indicators**: OpenClaw sends typing start events; BlueBubbles clears typing automatically on send or timeout (manual stop via DELETE is unreliable). - -```json5 -{ - channels: { - bluebubbles: { - sendReadReceipts: false, // disable read receipts - }, - }, -} -``` - -## Advanced actions - -BlueBubbles supports advanced message actions when enabled in config: - -```json5 -{ - channels: { - bluebubbles: { - actions: { - reactions: true, // tapbacks (default: true) - edit: true, // edit sent messages (macOS 13+, broken on macOS 26 Tahoe) - unsend: true, // unsend messages (macOS 13+) - reply: true, // reply threading by message GUID - sendWithEffect: true, // message effects (slam, loud, etc.) - renameGroup: true, // rename group chats - setGroupIcon: true, // set group chat icon/photo (flaky on macOS 26 Tahoe) - addParticipant: true, // add participants to groups - removeParticipant: true, // remove participants from groups - leaveGroup: true, // leave group chats - sendAttachment: true, // send attachments/media - }, - }, - }, -} -``` - -Available actions: - -- **react**: Add/remove tapback reactions (`messageId`, `emoji`, `remove`) -- **edit**: Edit a sent message (`messageId`, `text`) -- **unsend**: Unsend a message (`messageId`) -- **reply**: Reply to a specific message (`messageId`, `text`, `to`) -- **sendWithEffect**: Send with iMessage effect (`text`, `to`, `effectId`) -- **renameGroup**: Rename a group chat (`chatGuid`, `displayName`) -- **setGroupIcon**: Set a group chat's icon/photo (`chatGuid`, `media`) — flaky on macOS 26 Tahoe (API may return success but the icon does not sync). -- **addParticipant**: Add someone to a group (`chatGuid`, `address`) -- **removeParticipant**: Remove someone from a group (`chatGuid`, `address`) -- **leaveGroup**: Leave a group chat (`chatGuid`) -- **sendAttachment**: Send media/files (`to`, `buffer`, `filename`, `asVoice`) - - Voice memos: set `asVoice: true` with **MP3** or **CAF** audio to send as an iMessage voice message. BlueBubbles converts MP3 → CAF when sending voice memos. - -### Message IDs (short vs full) - -OpenClaw may surface _short_ message IDs (e.g., `1`, `2`) to save tokens. - -- `MessageSid` / `ReplyToId` can be short IDs. -- `MessageSidFull` / `ReplyToIdFull` contain the provider full IDs. -- Short IDs are in-memory; they can expire on restart or cache eviction. -- Actions accept short or full `messageId`, but short IDs will error if no longer available. - -Use full IDs for durable automations and storage: - -- Templates: `{{MessageSidFull}}`, `{{ReplyToIdFull}}` -- Context: `MessageSidFull` / `ReplyToIdFull` in inbound payloads - -See [Configuration](/gateway/configuration) for template variables. - -## Block streaming - -Control whether responses are sent as a single message or streamed in blocks: - -```json5 -{ - channels: { - bluebubbles: { - blockStreaming: true, // enable block streaming (off by default) - }, - }, -} -``` - -## Media + limits - -- Inbound attachments are downloaded and stored in the media cache. -- Media cap via `channels.bluebubbles.mediaMaxMb` (default: 8 MB). -- Outbound text is chunked to `channels.bluebubbles.textChunkLimit` (default: 4000 chars). - -## Configuration reference - -Full configuration: [Configuration](/gateway/configuration) - -Provider options: - -- `channels.bluebubbles.enabled`: Enable/disable the channel. -- `channels.bluebubbles.serverUrl`: BlueBubbles REST API base URL. -- `channels.bluebubbles.password`: API password. -- `channels.bluebubbles.webhookPath`: Webhook endpoint path (default: `/bluebubbles-webhook`). -- `channels.bluebubbles.dmPolicy`: `pairing | allowlist | open | disabled` (default: `pairing`). -- `channels.bluebubbles.allowFrom`: DM allowlist (handles, emails, E.164 numbers, `chat_id:*`, `chat_guid:*`). -- `channels.bluebubbles.groupPolicy`: `open | allowlist | disabled` (default: `allowlist`). -- `channels.bluebubbles.groupAllowFrom`: Group sender allowlist. -- `channels.bluebubbles.groups`: Per-group config (`requireMention`, etc.). -- `channels.bluebubbles.sendReadReceipts`: Send read receipts (default: `true`). -- `channels.bluebubbles.blockStreaming`: Enable block streaming (default: `false`; required for streaming replies). -- `channels.bluebubbles.textChunkLimit`: Outbound chunk size in chars (default: 4000). -- `channels.bluebubbles.chunkMode`: `length` (default) splits only when exceeding `textChunkLimit`; `newline` splits on blank lines (paragraph boundaries) before length chunking. -- `channels.bluebubbles.mediaMaxMb`: Inbound media cap in MB (default: 8). -- `channels.bluebubbles.mediaLocalRoots`: Explicit allowlist of absolute local directories permitted for outbound local media paths. Local path sends are denied by default unless this is configured. Per-account override: `channels.bluebubbles.accounts..mediaLocalRoots`. -- `channels.bluebubbles.historyLimit`: Max group messages for context (0 disables). -- `channels.bluebubbles.dmHistoryLimit`: DM history limit. -- `channels.bluebubbles.actions`: Enable/disable specific actions. -- `channels.bluebubbles.accounts`: Multi-account configuration. - -Related global options: - -- `agents.list[].groupChat.mentionPatterns` (or `messages.groupChat.mentionPatterns`). -- `messages.responsePrefix`. - -## Addressing / delivery targets - -Prefer `chat_guid` for stable routing: - -- `chat_guid:iMessage;-;+15555550123` (preferred for groups) -- `chat_id:123` -- `chat_identifier:...` -- Direct handles: `+15555550123`, `user@example.com` - - If a direct handle does not have an existing DM chat, OpenClaw will create one via `POST /api/v1/chat/new`. This requires the BlueBubbles Private API to be enabled. - -## Security - -- Webhook requests are authenticated by comparing `guid`/`password` query params or headers against `channels.bluebubbles.password`. Requests from `localhost` are also accepted. -- Keep the API password and webhook endpoint secret (treat them like credentials). -- Localhost trust means a same-host reverse proxy can unintentionally bypass the password. If you proxy the gateway, require auth at the proxy and configure `gateway.trustedProxies`. See [Gateway security](/gateway/security#reverse-proxy-configuration). -- Enable HTTPS + firewall rules on the BlueBubbles server if exposing it outside your LAN. - -## Troubleshooting - -- If typing/read events stop working, check the BlueBubbles webhook logs and verify the gateway path matches `channels.bluebubbles.webhookPath`. -- Pairing codes expire after one hour; use `openclaw pairing list bluebubbles` and `openclaw pairing approve bluebubbles `. -- Reactions require the BlueBubbles private API (`POST /api/v1/message/react`); ensure the server version exposes it. -- Edit/unsend require macOS 13+ and a compatible BlueBubbles server version. On macOS 26 (Tahoe), edit is currently broken due to private API changes. -- Group icon updates can be flaky on macOS 26 (Tahoe): the API may return success but the new icon does not sync. -- OpenClaw auto-hides known-broken actions based on the BlueBubbles server's macOS version. If edit still appears on macOS 26 (Tahoe), disable it manually with `channels.bluebubbles.actions.edit=false`. -- For status/health info: `openclaw status --all` or `openclaw status --deep`. - -For general channel workflow reference, see [Channels](/channels) and the [Plugins](/tools/plugin) guide. diff --git a/docs/channels/broadcast-groups.md b/docs/channels/broadcast-groups.md deleted file mode 100644 index 2d47d7c594..0000000000 --- a/docs/channels/broadcast-groups.md +++ /dev/null @@ -1,442 +0,0 @@ ---- -summary: "Broadcast a WhatsApp message to multiple agents" -read_when: - - Configuring broadcast groups - - Debugging multi-agent replies in WhatsApp -status: experimental -title: "Broadcast Groups" ---- - -# Broadcast Groups - -**Status:** Experimental -**Version:** Added in 2026.1.9 - -## Overview - -Broadcast Groups enable multiple agents to process and respond to the same message simultaneously. This allows you to create specialized agent teams that work together in a single WhatsApp group or DM — all using one phone number. - -Current scope: **WhatsApp only** (web channel). - -Broadcast groups are evaluated after channel allowlists and group activation rules. In WhatsApp groups, this means broadcasts happen when OpenClaw would normally reply (for example: on mention, depending on your group settings). - -## Use Cases - -### 1. Specialized Agent Teams - -Deploy multiple agents with atomic, focused responsibilities: - -``` -Group: "Development Team" -Agents: - - CodeReviewer (reviews code snippets) - - DocumentationBot (generates docs) - - SecurityAuditor (checks for vulnerabilities) - - TestGenerator (suggests test cases) -``` - -Each agent processes the same message and provides its specialized perspective. - -### 2. Multi-Language Support - -``` -Group: "International Support" -Agents: - - Agent_EN (responds in English) - - Agent_DE (responds in German) - - Agent_ES (responds in Spanish) -``` - -### 3. Quality Assurance Workflows - -``` -Group: "Customer Support" -Agents: - - SupportAgent (provides answer) - - QAAgent (reviews quality, only responds if issues found) -``` - -### 4. Task Automation - -``` -Group: "Project Management" -Agents: - - TaskTracker (updates task database) - - TimeLogger (logs time spent) - - ReportGenerator (creates summaries) -``` - -## Configuration - -### Basic Setup - -Add a top-level `broadcast` section (next to `bindings`). Keys are WhatsApp peer ids: - -- group chats: group JID (e.g. `120363403215116621@g.us`) -- DMs: E.164 phone number (e.g. `+15551234567`) - -```json -{ - "broadcast": { - "120363403215116621@g.us": ["alfred", "baerbel", "assistant3"] - } -} -``` - -**Result:** When OpenClaw would reply in this chat, it will run all three agents. - -### Processing Strategy - -Control how agents process messages: - -#### Parallel (Default) - -All agents process simultaneously: - -```json -{ - "broadcast": { - "strategy": "parallel", - "120363403215116621@g.us": ["alfred", "baerbel"] - } -} -``` - -#### Sequential - -Agents process in order (one waits for previous to finish): - -```json -{ - "broadcast": { - "strategy": "sequential", - "120363403215116621@g.us": ["alfred", "baerbel"] - } -} -``` - -### Complete Example - -```json -{ - "agents": { - "list": [ - { - "id": "code-reviewer", - "name": "Code Reviewer", - "workspace": "/path/to/code-reviewer", - "sandbox": { "mode": "all" } - }, - { - "id": "security-auditor", - "name": "Security Auditor", - "workspace": "/path/to/security-auditor", - "sandbox": { "mode": "all" } - }, - { - "id": "docs-generator", - "name": "Documentation Generator", - "workspace": "/path/to/docs-generator", - "sandbox": { "mode": "all" } - } - ] - }, - "broadcast": { - "strategy": "parallel", - "120363403215116621@g.us": ["code-reviewer", "security-auditor", "docs-generator"], - "120363424282127706@g.us": ["support-en", "support-de"], - "+15555550123": ["assistant", "logger"] - } -} -``` - -## How It Works - -### Message Flow - -1. **Incoming message** arrives in a WhatsApp group -2. **Broadcast check**: System checks if peer ID is in `broadcast` -3. **If in broadcast list**: - - All listed agents process the message - - Each agent has its own session key and isolated context - - Agents process in parallel (default) or sequentially -4. **If not in broadcast list**: - - Normal routing applies (first matching binding) - -Note: broadcast groups do not bypass channel allowlists or group activation rules (mentions/commands/etc). They only change _which agents run_ when a message is eligible for processing. - -### Session Isolation - -Each agent in a broadcast group maintains completely separate: - -- **Session keys** (`agent:alfred:whatsapp:group:120363...` vs `agent:baerbel:whatsapp:group:120363...`) -- **Conversation history** (agent doesn't see other agents' messages) -- **Workspace** (separate sandboxes if configured) -- **Tool access** (different allow/deny lists) -- **Memory/context** (separate IDENTITY.md, SOUL.md, etc.) -- **Group context buffer** (recent group messages used for context) is shared per peer, so all broadcast agents see the same context when triggered - -This allows each agent to have: - -- Different personalities -- Different tool access (e.g., read-only vs. read-write) -- Different models (e.g., opus vs. sonnet) -- Different skills installed - -### Example: Isolated Sessions - -In group `120363403215116621@g.us` with agents `["alfred", "baerbel"]`: - -**Alfred's context:** - -``` -Session: agent:alfred:whatsapp:group:120363403215116621@g.us -History: [user message, alfred's previous responses] -Workspace: /Users/pascal/openclaw-alfred/ -Tools: read, write, exec -``` - -**Bärbel's context:** - -``` -Session: agent:baerbel:whatsapp:group:120363403215116621@g.us -History: [user message, baerbel's previous responses] -Workspace: /Users/pascal/openclaw-baerbel/ -Tools: read only -``` - -## Best Practices - -### 1. Keep Agents Focused - -Design each agent with a single, clear responsibility: - -```json -{ - "broadcast": { - "DEV_GROUP": ["formatter", "linter", "tester"] - } -} -``` - -✅ **Good:** Each agent has one job -❌ **Bad:** One generic "dev-helper" agent - -### 2. Use Descriptive Names - -Make it clear what each agent does: - -```json -{ - "agents": { - "security-scanner": { "name": "Security Scanner" }, - "code-formatter": { "name": "Code Formatter" }, - "test-generator": { "name": "Test Generator" } - } -} -``` - -### 3. Configure Different Tool Access - -Give agents only the tools they need: - -```json -{ - "agents": { - "reviewer": { - "tools": { "allow": ["read", "exec"] } // Read-only - }, - "fixer": { - "tools": { "allow": ["read", "write", "edit", "exec"] } // Read-write - } - } -} -``` - -### 4. Monitor Performance - -With many agents, consider: - -- Using `"strategy": "parallel"` (default) for speed -- Limiting broadcast groups to 5-10 agents -- Using faster models for simpler agents - -### 5. Handle Failures Gracefully - -Agents fail independently. One agent's error doesn't block others: - -``` -Message → [Agent A ✓, Agent B ✗ error, Agent C ✓] -Result: Agent A and C respond, Agent B logs error -``` - -## Compatibility - -### Providers - -Broadcast groups currently work with: - -- ✅ WhatsApp (implemented) -- 🚧 Telegram (planned) -- 🚧 Discord (planned) -- 🚧 Slack (planned) - -### Routing - -Broadcast groups work alongside existing routing: - -```json -{ - "bindings": [ - { - "match": { "channel": "whatsapp", "peer": { "kind": "group", "id": "GROUP_A" } }, - "agentId": "alfred" - } - ], - "broadcast": { - "GROUP_B": ["agent1", "agent2"] - } -} -``` - -- `GROUP_A`: Only alfred responds (normal routing) -- `GROUP_B`: agent1 AND agent2 respond (broadcast) - -**Precedence:** `broadcast` takes priority over `bindings`. - -## Troubleshooting - -### Agents Not Responding - -**Check:** - -1. Agent IDs exist in `agents.list` -2. Peer ID format is correct (e.g., `120363403215116621@g.us`) -3. Agents are not in deny lists - -**Debug:** - -```bash -tail -f ~/.openclaw/logs/gateway.log | grep broadcast -``` - -### Only One Agent Responding - -**Cause:** Peer ID might be in `bindings` but not `broadcast`. - -**Fix:** Add to broadcast config or remove from bindings. - -### Performance Issues - -**If slow with many agents:** - -- Reduce number of agents per group -- Use lighter models (sonnet instead of opus) -- Check sandbox startup time - -## Examples - -### Example 1: Code Review Team - -```json -{ - "broadcast": { - "strategy": "parallel", - "120363403215116621@g.us": [ - "code-formatter", - "security-scanner", - "test-coverage", - "docs-checker" - ] - }, - "agents": { - "list": [ - { - "id": "code-formatter", - "workspace": "~/agents/formatter", - "tools": { "allow": ["read", "write"] } - }, - { - "id": "security-scanner", - "workspace": "~/agents/security", - "tools": { "allow": ["read", "exec"] } - }, - { - "id": "test-coverage", - "workspace": "~/agents/testing", - "tools": { "allow": ["read", "exec"] } - }, - { "id": "docs-checker", "workspace": "~/agents/docs", "tools": { "allow": ["read"] } } - ] - } -} -``` - -**User sends:** Code snippet -**Responses:** - -- code-formatter: "Fixed indentation and added type hints" -- security-scanner: "⚠️ SQL injection vulnerability in line 12" -- test-coverage: "Coverage is 45%, missing tests for error cases" -- docs-checker: "Missing docstring for function `process_data`" - -### Example 2: Multi-Language Support - -```json -{ - "broadcast": { - "strategy": "sequential", - "+15555550123": ["detect-language", "translator-en", "translator-de"] - }, - "agents": { - "list": [ - { "id": "detect-language", "workspace": "~/agents/lang-detect" }, - { "id": "translator-en", "workspace": "~/agents/translate-en" }, - { "id": "translator-de", "workspace": "~/agents/translate-de" } - ] - } -} -``` - -## API Reference - -### Config Schema - -```typescript -interface OpenClawConfig { - broadcast?: { - strategy?: "parallel" | "sequential"; - [peerId: string]: string[]; - }; -} -``` - -### Fields - -- `strategy` (optional): How to process agents - - `"parallel"` (default): All agents process simultaneously - - `"sequential"`: Agents process in array order -- `[peerId]`: WhatsApp group JID, E.164 number, or other peer ID - - Value: Array of agent IDs that should process messages - -## Limitations - -1. **Max agents:** No hard limit, but 10+ agents may be slow -2. **Shared context:** Agents don't see each other's responses (by design) -3. **Message ordering:** Parallel responses may arrive in any order -4. **Rate limits:** All agents count toward WhatsApp rate limits - -## Future Enhancements - -Planned features: - -- [ ] Shared context mode (agents see each other's responses) -- [ ] Agent coordination (agents can signal each other) -- [ ] Dynamic agent selection (choose agents based on message content) -- [ ] Agent priorities (some agents respond before others) - -## See Also - -- [Multi-Agent Configuration](/tools/multi-agent-sandbox-tools) -- [Routing Configuration](/channels/channel-routing) -- [Session Management](/concepts/sessions) diff --git a/docs/channels/channel-routing.md b/docs/channels/channel-routing.md deleted file mode 100644 index 49c4a6120d..0000000000 --- a/docs/channels/channel-routing.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -summary: "Routing rules per channel (WhatsApp, Telegram, Discord, Slack) and shared context" -read_when: - - Changing channel routing or inbox behavior -title: "Channel Routing" ---- - -# Channels & routing - -OpenClaw routes replies **back to the channel where a message came from**. The -model does not choose a channel; routing is deterministic and controlled by the -host configuration. - -## Key terms - -- **Channel**: `whatsapp`, `telegram`, `discord`, `slack`, `signal`, `imessage`, `webchat`. -- **AccountId**: per‑channel account instance (when supported). -- **AgentId**: an isolated workspace + session store (“brain”). -- **SessionKey**: the bucket key used to store context and control concurrency. - -## Session key shapes (examples) - -Direct messages collapse to the agent’s **main** session: - -- `agent::` (default: `agent:main:main`) - -Groups and channels remain isolated per channel: - -- Groups: `agent:::group:` -- Channels/rooms: `agent:::channel:` - -Threads: - -- Slack/Discord threads append `:thread:` to the base key. -- Telegram forum topics embed `:topic:` in the group key. - -Examples: - -- `agent:main:telegram:group:-1001234567890:topic:42` -- `agent:main:discord:channel:123456:thread:987654` - -## Routing rules (how an agent is chosen) - -Routing picks **one agent** for each inbound message: - -1. **Exact peer match** (`bindings` with `peer.kind` + `peer.id`). -2. **Parent peer match** (thread inheritance). -3. **Guild + roles match** (Discord) via `guildId` + `roles`. -4. **Guild match** (Discord) via `guildId`. -5. **Team match** (Slack) via `teamId`. -6. **Account match** (`accountId` on the channel). -7. **Channel match** (any account on that channel, `accountId: "*"`). -8. **Default agent** (`agents.list[].default`, else first list entry, fallback to `main`). - -When a binding includes multiple match fields (`peer`, `guildId`, `teamId`, `roles`), **all provided fields must match** for that binding to apply. - -The matched agent determines which workspace and session store are used. - -## Broadcast groups (run multiple agents) - -Broadcast groups let you run **multiple agents** for the same peer **when OpenClaw would normally reply** (for example: in WhatsApp groups, after mention/activation gating). - -Config: - -```json5 -{ - broadcast: { - strategy: "parallel", - "120363403215116621@g.us": ["alfred", "baerbel"], - "+15555550123": ["support", "logger"], - }, -} -``` - -See: [Broadcast Groups](/channels/broadcast-groups). - -## Config overview - -- `agents.list`: named agent definitions (workspace, model, etc.). -- `bindings`: map inbound channels/accounts/peers to agents. - -Example: - -```json5 -{ - agents: { - list: [{ id: "support", name: "Support", workspace: "~/.openclaw/workspace-support" }], - }, - bindings: [ - { match: { channel: "slack", teamId: "T123" }, agentId: "support" }, - { match: { channel: "telegram", peer: { kind: "group", id: "-100123" } }, agentId: "support" }, - ], -} -``` - -## Session storage - -Session stores live under the state directory (default `~/.openclaw`): - -- `~/.openclaw/agents//sessions/sessions.json` -- JSONL transcripts live alongside the store - -You can override the store path via `session.store` and `{agentId}` templating. - -## WebChat behavior - -WebChat attaches to the **selected agent** and defaults to the agent’s main -session. Because of this, WebChat lets you see cross‑channel context for that -agent in one place. - -## Reply context - -Inbound replies include: - -- `ReplyToId`, `ReplyToBody`, and `ReplyToSender` when available. -- Quoted context is appended to `Body` as a `[Replying to ...]` block. - -This is consistent across channels. diff --git a/docs/channels/discord.md b/docs/channels/discord.md deleted file mode 100644 index 774a0eba1a..0000000000 --- a/docs/channels/discord.md +++ /dev/null @@ -1,884 +0,0 @@ ---- -summary: "Discord bot support status, capabilities, and configuration" -read_when: - - Working on Discord channel features -title: "Discord" ---- - -# Discord (Bot API) - -Status: ready for DMs and guild channels via the official Discord gateway. - - - - Discord DMs default to pairing mode. - - - Native command behavior and command catalog. - - - Cross-channel diagnostics and repair flow. - - - -## Quick setup - -You will need to create a new application with a bot, add the bot to your server, and pair it to OpenClaw. We recommend adding your bot to your own private server. If you don't have one yet, [create one first](https://support.discord.com/hc/en-us/articles/204849977-How-do-I-create-a-server) (choose **Create My Own > For me and my friends**). - - - - Go to the [Discord Developer Portal](https://discord.com/developers/applications) and click **New Application**. Name it something like "OpenClaw". - - Click **Bot** on the sidebar. Set the **Username** to whatever you call your OpenClaw agent. - - - - - Still on the **Bot** page, scroll down to **Privileged Gateway Intents** and enable: - - - **Message Content Intent** (required) - - **Server Members Intent** (recommended; required for role allowlists and name-to-ID matching) - - **Presence Intent** (optional; only needed for presence updates) - - - - - Scroll back up on the **Bot** page and click **Reset Token**. - - - Despite the name, this generates your first token — nothing is being "reset." - - - Copy the token and save it somewhere. This is your **Bot Token** and you will need it shortly. - - - - - Click **OAuth2** on the sidebar. You'll generate an invite URL with the right permissions to add the bot to your server. - - Scroll down to **OAuth2 URL Generator** and enable: - - - `bot` - - `applications.commands` - - A **Bot Permissions** section will appear below. Enable: - - - View Channels - - Send Messages - - Read Message History - - Embed Links - - Attach Files - - Add Reactions (optional) - - Copy the generated URL at the bottom, paste it into your browser, select your server, and click **Continue** to connect. You should now see your bot in the Discord server. - - - - - Back in the Discord app, you need to enable Developer Mode so you can copy internal IDs. - - 1. Click **User Settings** (gear icon next to your avatar) → **Advanced** → toggle on **Developer Mode** - 2. Right-click your **server icon** in the sidebar → **Copy Server ID** - 3. Right-click your **own avatar** → **Copy User ID** - - Save your **Server ID** and **User ID** alongside your Bot Token — you'll send all three to OpenClaw in the next step. - - - - - For pairing to work, Discord needs to allow your bot to DM you. Right-click your **server icon** → **Privacy Settings** → toggle on **Direct Messages**. - - This lets server members (including bots) send you DMs. Keep this enabled if you want to use Discord DMs with OpenClaw. If you only plan to use guild channels, you can disable DMs after pairing. - - - - - Your Discord bot token is a secret (like a password). Set it on the machine running OpenClaw before messaging your agent. - -```bash -openclaw config set channels.discord.token '"YOUR_BOT_TOKEN"' --json -openclaw config set channels.discord.enabled true --json -openclaw gateway -``` - - If OpenClaw is already running as a background service, use `openclaw gateway restart` instead. - - - - - - - - Chat with your OpenClaw agent on any existing channel (e.g. Telegram) and tell it. If Discord is your first channel, use the CLI / config tab instead. - - > "I already set my Discord bot token in config. Please finish Discord setup with User ID `` and Server ID ``." - - - If you prefer file-based config, set: - -```json5 -{ - channels: { - discord: { - enabled: true, - token: "YOUR_BOT_TOKEN", - }, - }, -} -``` - - Env fallback for the default account: - -```bash -DISCORD_BOT_TOKEN=... -``` - - - - - - - - Wait until the gateway is running, then DM your bot in Discord. It will respond with a pairing code. - - - - Send the pairing code to your agent on your existing channel: - - > "Approve this Discord pairing code: ``" - - - -```bash -openclaw pairing list discord -openclaw pairing approve discord -``` - - - - - Pairing codes expire after 1 hour. - - You should now be able to chat with your agent in Discord via DM. - - - - - -Token resolution is account-aware. Config token values win over env fallback. `DISCORD_BOT_TOKEN` is only used for the default account. - - -## Recommended: Set up a guild workspace - -Once DMs are working, you can set up your Discord server as a full workspace where each channel gets its own agent session with its own context. This is recommended for private servers where it's just you and your bot. - - - - This enables your agent to respond in any channel on your server, not just DMs. - - - - > "Add my Discord Server ID `` to the guild allowlist" - - - -```json5 -{ - channels: { - discord: { - groupPolicy: "allowlist", - guilds: { - YOUR_SERVER_ID: { - requireMention: true, - users: ["YOUR_USER_ID"], - }, - }, - }, - }, -} -``` - - - - - - - - By default, your agent only responds in guild channels when @mentioned. For a private server, you probably want it to respond to every message. - - - - > "Allow my agent to respond on this server without having to be @mentioned" - - - Set `requireMention: false` in your guild config: - -```json5 -{ - channels: { - discord: { - guilds: { - YOUR_SERVER_ID: { - requireMention: false, - }, - }, - }, - }, -} -``` - - - - - - - - By default, long-term memory (MEMORY.md) only loads in DM sessions. Guild channels do not auto-load MEMORY.md. - - - - > "When I ask questions in Discord channels, use memory_search or memory_get if you need long-term context from MEMORY.md." - - - If you need shared context in every channel, put the stable instructions in `AGENTS.md` or `USER.md` (they are injected for every session). Keep long-term notes in `MEMORY.md` and access them on demand with memory tools. - - - - - - -Now create some channels on your Discord server and start chatting. Your agent can see the channel name, and each channel gets its own isolated session — so you can set up `#coding`, `#home`, `#research`, or whatever fits your workflow. - -## Runtime model - -- Gateway owns the Discord connection. -- Reply routing is deterministic: Discord inbound replies back to Discord. -- By default (`session.dmScope=main`), direct chats share the agent main session (`agent:main:main`). -- Guild channels are isolated session keys (`agent::discord:channel:`). -- Group DMs are ignored by default (`channels.discord.dm.groupEnabled=false`). -- Native slash commands run in isolated command sessions (`agent::discord:slash:`), while still carrying `CommandTargetSessionKey` to the routed conversation session. - -## Interactive components - -OpenClaw supports Discord components v2 containers for agent messages. Use the message tool with a `components` payload. Interaction results are routed back to the agent as normal inbound messages and follow the existing Discord `replyToMode` settings. - -Supported blocks: - -- `text`, `section`, `separator`, `actions`, `media-gallery`, `file` -- Action rows allow up to 5 buttons or a single select menu -- Select types: `string`, `user`, `role`, `mentionable`, `channel` - -By default, components are single use. Set `components.reusable=true` to allow buttons, selects, and forms to be used multiple times until they expire. - -To restrict who can click a button, set `allowedUsers` on that button (Discord user IDs, tags, or `*`). When configured, unmatched users receive an ephemeral denial. - -File attachments: - -- `file` blocks must point to an attachment reference (`attachment://`) -- Provide the attachment via `media`/`path`/`filePath` (single file); use `media-gallery` for multiple files -- Use `filename` to override the upload name when it should match the attachment reference - -Modal forms: - -- Add `components.modal` with up to 5 fields -- Field types: `text`, `checkbox`, `radio`, `select`, `role-select`, `user-select` -- OpenClaw adds a trigger button automatically - -Example: - -```json5 -{ - channel: "discord", - action: "send", - to: "channel:123456789012345678", - message: "Optional fallback text", - components: { - reusable: true, - text: "Choose a path", - blocks: [ - { - type: "actions", - buttons: [ - { - label: "Approve", - style: "success", - allowedUsers: ["123456789012345678"], - }, - { label: "Decline", style: "danger" }, - ], - }, - { - type: "actions", - select: { - type: "string", - placeholder: "Pick an option", - options: [ - { label: "Option A", value: "a" }, - { label: "Option B", value: "b" }, - ], - }, - }, - ], - modal: { - title: "Details", - triggerLabel: "Open form", - fields: [ - { type: "text", label: "Requester" }, - { - type: "select", - label: "Priority", - options: [ - { label: "Low", value: "low" }, - { label: "High", value: "high" }, - ], - }, - ], - }, - }, -} -``` - -## Access control and routing - - - - `channels.discord.dmPolicy` controls DM access (legacy: `channels.discord.dm.policy`): - - - `pairing` (default) - - `allowlist` - - `open` (requires `channels.discord.allowFrom` to include `"*"`; legacy: `channels.discord.dm.allowFrom`) - - `disabled` - - If DM policy is not open, unknown users are blocked (or prompted for pairing in `pairing` mode). - - DM target format for delivery: - - - `user:` - - `<@id>` mention - - Bare numeric IDs are ambiguous and rejected unless an explicit user/channel target kind is provided. - - - - - Guild handling is controlled by `channels.discord.groupPolicy`: - - - `open` - - `allowlist` - - `disabled` - - Secure baseline when `channels.discord` exists is `allowlist`. - - `allowlist` behavior: - - - guild must match `channels.discord.guilds` (`id` preferred, slug accepted) - - optional sender allowlists: `users` (IDs or names) and `roles` (role IDs only); if either is configured, senders are allowed when they match `users` OR `roles` - - if a guild has `channels` configured, non-listed channels are denied - - if a guild has no `channels` block, all channels in that allowlisted guild are allowed - - Example: - -```json5 -{ - channels: { - discord: { - groupPolicy: "allowlist", - guilds: { - "123456789012345678": { - requireMention: true, - users: ["987654321098765432"], - roles: ["123456789012345678"], - channels: { - general: { allow: true }, - help: { allow: true, requireMention: true }, - }, - }, - }, - }, - }, -} -``` - - If you only set `DISCORD_BOT_TOKEN` and do not create a `channels.discord` block, runtime fallback is `groupPolicy="open"` (with a warning in logs). - - - - - Guild messages are mention-gated by default. - - Mention detection includes: - - - explicit bot mention - - configured mention patterns (`agents.list[].groupChat.mentionPatterns`, fallback `messages.groupChat.mentionPatterns`) - - implicit reply-to-bot behavior in supported cases - - `requireMention` is configured per guild/channel (`channels.discord.guilds...`). - - Group DMs: - - - default: ignored (`dm.groupEnabled=false`) - - optional allowlist via `dm.groupChannels` (channel IDs or slugs) - - - - -### Role-based agent routing - -Use `bindings[].match.roles` to route Discord guild members to different agents by role ID. Role-based bindings accept role IDs only and are evaluated after peer or parent-peer bindings and before guild-only bindings. If a binding also sets other match fields (for example `peer` + `guildId` + `roles`), all configured fields must match. - -```json5 -{ - bindings: [ - { - agentId: "opus", - match: { - channel: "discord", - guildId: "123456789012345678", - roles: ["111111111111111111"], - }, - }, - { - agentId: "sonnet", - match: { - channel: "discord", - guildId: "123456789012345678", - }, - }, - ], -} -``` - -## Developer Portal setup - - - - - 1. Discord Developer Portal -> **Applications** -> **New Application** - 2. **Bot** -> **Add Bot** - 3. Copy bot token - - - - - In **Bot -> Privileged Gateway Intents**, enable: - - - Message Content Intent - - Server Members Intent (recommended) - - Presence intent is optional and only required if you want to receive presence updates. Setting bot presence (`setPresence`) does not require enabling presence updates for members. - - - - - OAuth URL generator: - - - scopes: `bot`, `applications.commands` - - Typical baseline permissions: - - - View Channels - - Send Messages - - Read Message History - - Embed Links - - Attach Files - - Add Reactions (optional) - - Avoid `Administrator` unless explicitly needed. - - - - - Enable Discord Developer Mode, then copy: - - - server ID - - channel ID - - user ID - - Prefer numeric IDs in OpenClaw config for reliable audits and probes. - - - - -## Native commands and command auth - -- `commands.native` defaults to `"auto"` and is enabled for Discord. -- Per-channel override: `channels.discord.commands.native`. -- `commands.native=false` explicitly clears previously registered Discord native commands. -- Native command auth uses the same Discord allowlists/policies as normal message handling. -- Commands may still be visible in Discord UI for users who are not authorized; execution still enforces OpenClaw auth and returns "not authorized". - -See [Slash commands](/tools/slash-commands) for command catalog and behavior. - -## Feature details - - - - Discord supports reply tags in agent output: - - - `[[reply_to_current]]` - - `[[reply_to:]]` - - Controlled by `channels.discord.replyToMode`: - - - `off` (default) - - `first` - - `all` - - Note: `off` disables implicit reply threading. Explicit `[[reply_to_*]]` tags are still honored. - - Message IDs are surfaced in context/history so agents can target specific messages. - - - - - Guild history context: - - - `channels.discord.historyLimit` default `20` - - fallback: `messages.groupChat.historyLimit` - - `0` disables - - DM history controls: - - - `channels.discord.dmHistoryLimit` - - `channels.discord.dms[""].historyLimit` - - Thread behavior: - - - Discord threads are routed as channel sessions - - parent thread metadata can be used for parent-session linkage - - thread config inherits parent channel config unless a thread-specific entry exists - - Channel topics are injected as **untrusted** context (not as system prompt). - - - - - Per-guild reaction notification mode: - - - `off` - - `own` (default) - - `all` - - `allowlist` (uses `guilds..users`) - - Reaction events are turned into system events and attached to the routed Discord session. - - - - - `ackReaction` sends an acknowledgement emoji while OpenClaw is processing an inbound message. - - Resolution order: - - - `channels.discord.accounts..ackReaction` - - `channels.discord.ackReaction` - - `messages.ackReaction` - - agent identity emoji fallback (`agents.list[].identity.emoji`, else "👀") - - Notes: - - - Discord accepts unicode emoji or custom emoji names. - - Use `""` to disable the reaction for a channel or account. - - - - - Channel-initiated config writes are enabled by default. - - This affects `/config set|unset` flows (when command features are enabled). - - Disable: - -```json5 -{ - channels: { - discord: { - configWrites: false, - }, - }, -} -``` - - - - - Route Discord gateway WebSocket traffic and startup REST lookups (application ID + allowlist resolution) through an HTTP(S) proxy with `channels.discord.proxy`. - -```json5 -{ - channels: { - discord: { - proxy: "http://proxy.example:8080", - }, - }, -} -``` - - Per-account override: - -```json5 -{ - channels: { - discord: { - accounts: { - primary: { - proxy: "http://proxy.example:8080", - }, - }, - }, - }, -} -``` - - - - - Enable PluralKit resolution to map proxied messages to system member identity: - -```json5 -{ - channels: { - discord: { - pluralkit: { - enabled: true, - token: "pk_live_...", // optional; needed for private systems - }, - }, - }, -} -``` - - Notes: - - - allowlists can use `pk:` - - member display names are matched by name/slug - - lookups use original message ID and are time-window constrained - - if lookup fails, proxied messages are treated as bot messages and dropped unless `allowBots=true` - - - - - Presence updates are applied only when you set a status or activity field. - - Status only example: - -```json5 -{ - channels: { - discord: { - status: "idle", - }, - }, -} -``` - - Activity example (custom status is the default activity type): - -```json5 -{ - channels: { - discord: { - activity: "Focus time", - activityType: 4, - }, - }, -} -``` - - Streaming example: - -```json5 -{ - channels: { - discord: { - activity: "Live coding", - activityType: 1, - activityUrl: "https://twitch.tv/openclaw", - }, - }, -} -``` - - Activity type map: - - - 0: Playing - - 1: Streaming (requires `activityUrl`) - - 2: Listening - - 3: Watching - - 4: Custom (uses the activity text as the status state; emoji is optional) - - 5: Competing - - - - - Discord supports button-based exec approvals in DMs and can optionally post approval prompts in the originating channel. - - Config path: - - - `channels.discord.execApprovals.enabled` - - `channels.discord.execApprovals.approvers` - - `channels.discord.execApprovals.target` (`dm` | `channel` | `both`, default: `dm`) - - `agentFilter`, `sessionFilter`, `cleanupAfterResolve` - - When `target` is `channel` or `both`, the approval prompt is visible in the channel. Only configured approvers can use the buttons; other users receive an ephemeral denial. Approval prompts include the command text, so only enable channel delivery in trusted channels. If the channel ID cannot be derived from the session key, OpenClaw falls back to DM delivery. - - If approvals fail with unknown approval IDs, verify approver list and feature enablement. - - Related docs: [Exec approvals](/tools/exec-approvals) - - - - -## Tools and action gates - -Discord message actions include messaging, channel admin, moderation, presence, and metadata actions. - -Core examples: - -- messaging: `sendMessage`, `readMessages`, `editMessage`, `deleteMessage`, `threadReply` -- reactions: `react`, `reactions`, `emojiList` -- moderation: `timeout`, `kick`, `ban` -- presence: `setPresence` - -Action gates live under `channels.discord.actions.*`. - -Default gate behavior: - -| Action group | Default | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | -| reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissions | enabled | -| roles | disabled | -| moderation | disabled | -| presence | disabled | - -## Components v2 UI - -OpenClaw uses Discord components v2 for exec approvals and cross-context markers. Discord message actions can also accept `components` for custom UI (advanced; requires Carbon component instances), while legacy `embeds` remain available but are not recommended. - -- `channels.discord.ui.components.accentColor` sets the accent color used by Discord component containers (hex). -- Set per account with `channels.discord.accounts..ui.components.accentColor`. -- `embeds` are ignored when components v2 are present. - -Example: - -```json5 -{ - channels: { - discord: { - ui: { - components: { - accentColor: "#5865F2", - }, - }, - }, - }, -} -``` - -## Voice messages - -Discord voice messages show a waveform preview and require OGG/Opus audio plus metadata. OpenClaw generates the waveform automatically, but it needs `ffmpeg` and `ffprobe` available on the gateway host to inspect and convert audio files. - -Requirements and constraints: - -- Provide a **local file path** (URLs are rejected). -- Omit text content (Discord does not allow text + voice message in the same payload). -- Any audio format is accepted; OpenClaw converts to OGG/Opus when needed. - -Example: - -```bash -message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true) -``` - -## Troubleshooting - - - - - - enable Message Content Intent - - enable Server Members Intent when you depend on user/member resolution - - restart gateway after changing intents - - - - - - - verify `groupPolicy` - - verify guild allowlist under `channels.discord.guilds` - - if guild `channels` map exists, only listed channels are allowed - - verify `requireMention` behavior and mention patterns - - Useful checks: - -```bash -openclaw doctor -openclaw channels status --probe -openclaw logs --follow -``` - - - - - Common causes: - - - `groupPolicy="allowlist"` without matching guild/channel allowlist - - `requireMention` configured in the wrong place (must be under `channels.discord.guilds` or channel entry) - - sender blocked by guild/channel `users` allowlist - - - - - `channels status --probe` permission checks only work for numeric channel IDs. - - If you use slug keys, runtime matching can still work, but probe cannot fully verify permissions. - - - - - - - DM disabled: `channels.discord.dm.enabled=false` - - DM policy disabled: `channels.discord.dmPolicy="disabled"` (legacy: `channels.discord.dm.policy`) - - awaiting pairing approval in `pairing` mode - - - - - By default bot-authored messages are ignored. - - If you set `channels.discord.allowBots=true`, use strict mention and allowlist rules to avoid loop behavior. - - - - -## Configuration reference pointers - -Primary reference: - -- [Configuration reference - Discord](/gateway/configuration-reference#discord) - -High-signal Discord fields: - -- startup/auth: `enabled`, `token`, `accounts.*`, `allowBots` -- policy: `groupPolicy`, `dm.*`, `guilds.*`, `guilds.*.channels.*` -- command: `commands.native`, `commands.useAccessGroups`, `configWrites` -- reply/history: `replyToMode`, `historyLimit`, `dmHistoryLimit`, `dms.*.historyLimit` -- delivery: `textChunkLimit`, `chunkMode`, `maxLinesPerMessage` -- media/retry: `mediaMaxMb`, `retry` -- actions: `actions.*` -- presence: `activity`, `status`, `activityType`, `activityUrl` -- UI: `ui.components.accentColor` -- features: `pluralkit`, `execApprovals`, `intents`, `agentComponents`, `heartbeat`, `responsePrefix` - -## Safety and operations - -- Treat bot tokens as secrets (`DISCORD_BOT_TOKEN` preferred in supervised environments). -- Grant least-privilege Discord permissions. -- If command deploy/state is stale, restart gateway and re-check with `openclaw channels status --probe`. - -## Related - -- [Pairing](/channels/pairing) -- [Channel routing](/channels/channel-routing) -- [Multi-agent routing](/concepts/multi-agent) -- [Troubleshooting](/channels/troubleshooting) -- [Slash commands](/tools/slash-commands) diff --git a/docs/channels/feishu.md b/docs/channels/feishu.md deleted file mode 100644 index e92f84460d..0000000000 --- a/docs/channels/feishu.md +++ /dev/null @@ -1,586 +0,0 @@ ---- -summary: "Feishu bot overview, features, and configuration" -read_when: - - You want to connect a Feishu/Lark bot - - You are configuring the Feishu channel -title: Feishu ---- - -# Feishu bot - -Feishu (Lark) is a team chat platform used by companies for messaging and collaboration. This plugin connects OpenClaw to a Feishu/Lark bot using the platform’s WebSocket event subscription so messages can be received without exposing a public webhook URL. - ---- - -## Plugin required - -Install the Feishu plugin: - -```bash -openclaw plugins install @openclaw/feishu -``` - -Local checkout (when running from a git repo): - -```bash -openclaw plugins install ./extensions/feishu -``` - ---- - -## Quickstart - -There are two ways to add the Feishu channel: - -### Method 1: onboarding wizard (recommended) - -If you just installed OpenClaw, run the wizard: - -```bash -openclaw onboard -``` - -The wizard guides you through: - -1. Creating a Feishu app and collecting credentials -2. Configuring app credentials in OpenClaw -3. Starting the gateway - -✅ **After configuration**, check gateway status: - -- `openclaw gateway status` -- `openclaw logs --follow` - -### Method 2: CLI setup - -If you already completed initial install, add the channel via CLI: - -```bash -openclaw channels add -``` - -Choose **Feishu**, then enter the App ID and App Secret. - -✅ **After configuration**, manage the gateway: - -- `openclaw gateway status` -- `openclaw gateway restart` -- `openclaw logs --follow` - ---- - -## Step 1: Create a Feishu app - -### 1. Open Feishu Open Platform - -Visit [Feishu Open Platform](https://open.feishu.cn/app) and sign in. - -Lark (global) tenants should use [https://open.larksuite.com/app](https://open.larksuite.com/app) and set `domain: "lark"` in the Feishu config. - -### 2. Create an app - -1. Click **Create enterprise app** -2. Fill in the app name + description -3. Choose an app icon - -![Create enterprise app](../images/feishu-step2-create-app.png) - -### 3. Copy credentials - -From **Credentials & Basic Info**, copy: - -- **App ID** (format: `cli_xxx`) -- **App Secret** - -❗ **Important:** keep the App Secret private. - -![Get credentials](../images/feishu-step3-credentials.png) - -### 4. Configure permissions - -On **Permissions**, click **Batch import** and paste: - -```json -{ - "scopes": { - "tenant": [ - "aily:file:read", - "aily:file:write", - "application:application.app_message_stats.overview:readonly", - "application:application:self_manage", - "application:bot.menu:write", - "contact:user.employee_id:readonly", - "corehr:file:download", - "event:ip_list", - "im:chat.access_event.bot_p2p_chat:read", - "im:chat.members:bot_access", - "im:message", - "im:message.group_at_msg:readonly", - "im:message.p2p_msg:readonly", - "im:message:readonly", - "im:message:send_as_bot", - "im:resource" - ], - "user": ["aily:file:read", "aily:file:write", "im:chat.access_event.bot_p2p_chat:read"] - } -} -``` - -![Configure permissions](../images/feishu-step4-permissions.png) - -### 5. Enable bot capability - -In **App Capability** > **Bot**: - -1. Enable bot capability -2. Set the bot name - -![Enable bot capability](../images/feishu-step5-bot-capability.png) - -### 6. Configure event subscription - -⚠️ **Important:** before setting event subscription, make sure: - -1. You already ran `openclaw channels add` for Feishu -2. The gateway is running (`openclaw gateway status`) - -In **Event Subscription**: - -1. Choose **Use long connection to receive events** (WebSocket) -2. Add the event: `im.message.receive_v1` - -⚠️ If the gateway is not running, the long-connection setup may fail to save. - -![Configure event subscription](../images/feishu-step6-event-subscription.png) - -### 7. Publish the app - -1. Create a version in **Version Management & Release** -2. Submit for review and publish -3. Wait for admin approval (enterprise apps usually auto-approve) - ---- - -## Step 2: Configure OpenClaw - -### Configure with the wizard (recommended) - -```bash -openclaw channels add -``` - -Choose **Feishu** and paste your App ID + App Secret. - -### Configure via config file - -Edit `~/.openclaw/openclaw.json`: - -```json5 -{ - channels: { - feishu: { - enabled: true, - dmPolicy: "pairing", - accounts: { - main: { - appId: "cli_xxx", - appSecret: "xxx", - botName: "My AI assistant", - }, - }, - }, - }, -} -``` - -If you use `connectionMode: "webhook"`, set `verificationToken`. The Feishu webhook server binds to `127.0.0.1` by default; set `webhookHost` only if you intentionally need a different bind address. - -### Configure via environment variables - -```bash -export FEISHU_APP_ID="cli_xxx" -export FEISHU_APP_SECRET="xxx" -``` - -### Lark (global) domain - -If your tenant is on Lark (international), set the domain to `lark` (or a full domain string). You can set it at `channels.feishu.domain` or per account (`channels.feishu.accounts..domain`). - -```json5 -{ - channels: { - feishu: { - domain: "lark", - accounts: { - main: { - appId: "cli_xxx", - appSecret: "xxx", - }, - }, - }, - }, -} -``` - ---- - -## Step 3: Start + test - -### 1. Start the gateway - -```bash -openclaw gateway -``` - -### 2. Send a test message - -In Feishu, find your bot and send a message. - -### 3. Approve pairing - -By default, the bot replies with a pairing code. Approve it: - -```bash -openclaw pairing approve feishu -``` - -After approval, you can chat normally. - ---- - -## Overview - -- **Feishu bot channel**: Feishu bot managed by the gateway -- **Deterministic routing**: replies always return to Feishu -- **Session isolation**: DMs share a main session; groups are isolated -- **WebSocket connection**: long connection via Feishu SDK, no public URL needed - ---- - -## Access control - -### Direct messages - -- **Default**: `dmPolicy: "pairing"` (unknown users get a pairing code) -- **Approve pairing**: - - ```bash - openclaw pairing list feishu - openclaw pairing approve feishu - ``` - -- **Allowlist mode**: set `channels.feishu.allowFrom` with allowed Open IDs - -### Group chats - -**1. Group policy** (`channels.feishu.groupPolicy`): - -- `"open"` = allow everyone in groups (default) -- `"allowlist"` = only allow `groupAllowFrom` -- `"disabled"` = disable group messages - -**2. Mention requirement** (`channels.feishu.groups..requireMention`): - -- `true` = require @mention (default) -- `false` = respond without mentions - ---- - -## Group configuration examples - -### Allow all groups, require @mention (default) - -```json5 -{ - channels: { - feishu: { - groupPolicy: "open", - // Default requireMention: true - }, - }, -} -``` - -### Allow all groups, no @mention required - -```json5 -{ - channels: { - feishu: { - groups: { - oc_xxx: { requireMention: false }, - }, - }, - }, -} -``` - -### Allow specific users in groups only - -```json5 -{ - channels: { - feishu: { - groupPolicy: "allowlist", - groupAllowFrom: ["ou_xxx", "ou_yyy"], - }, - }, -} -``` - ---- - -## Get group/user IDs - -### Group IDs (chat_id) - -Group IDs look like `oc_xxx`. - -**Method 1 (recommended)** - -1. Start the gateway and @mention the bot in the group -2. Run `openclaw logs --follow` and look for `chat_id` - -**Method 2** - -Use the Feishu API debugger to list group chats. - -### User IDs (open_id) - -User IDs look like `ou_xxx`. - -**Method 1 (recommended)** - -1. Start the gateway and DM the bot -2. Run `openclaw logs --follow` and look for `open_id` - -**Method 2** - -Check pairing requests for user Open IDs: - -```bash -openclaw pairing list feishu -``` - ---- - -## Common commands - -| Command | Description | -| --------- | ----------------- | -| `/status` | Show bot status | -| `/reset` | Reset the session | -| `/model` | Show/switch model | - -> Note: Feishu does not support native command menus yet, so commands must be sent as text. - -## Gateway management commands - -| Command | Description | -| -------------------------- | ----------------------------- | -| `openclaw gateway status` | Show gateway status | -| `openclaw gateway install` | Install/start gateway service | -| `openclaw gateway stop` | Stop gateway service | -| `openclaw gateway restart` | Restart gateway service | -| `openclaw logs --follow` | Tail gateway logs | - ---- - -## Troubleshooting - -### Bot does not respond in group chats - -1. Ensure the bot is added to the group -2. Ensure you @mention the bot (default behavior) -3. Check `groupPolicy` is not set to `"disabled"` -4. Check logs: `openclaw logs --follow` - -### Bot does not receive messages - -1. Ensure the app is published and approved -2. Ensure event subscription includes `im.message.receive_v1` -3. Ensure **long connection** is enabled -4. Ensure app permissions are complete -5. Ensure the gateway is running: `openclaw gateway status` -6. Check logs: `openclaw logs --follow` - -### App Secret leak - -1. Reset the App Secret in Feishu Open Platform -2. Update the App Secret in your config -3. Restart the gateway - -### Message send failures - -1. Ensure the app has `im:message:send_as_bot` permission -2. Ensure the app is published -3. Check logs for detailed errors - ---- - -## Advanced configuration - -### Multiple accounts - -```json5 -{ - channels: { - feishu: { - accounts: { - main: { - appId: "cli_xxx", - appSecret: "xxx", - botName: "Primary bot", - }, - backup: { - appId: "cli_yyy", - appSecret: "yyy", - botName: "Backup bot", - enabled: false, - }, - }, - }, - }, -} -``` - -### Message limits - -- `textChunkLimit`: outbound text chunk size (default: 2000 chars) -- `mediaMaxMb`: media upload/download limit (default: 30MB) - -### Streaming - -Feishu supports streaming replies via interactive cards. When enabled, the bot updates a card as it generates text. - -```json5 -{ - channels: { - feishu: { - streaming: true, // enable streaming card output (default true) - blockStreaming: true, // enable block-level streaming (default true) - }, - }, -} -``` - -Set `streaming: false` to wait for the full reply before sending. - -### Multi-agent routing - -Use `bindings` to route Feishu DMs or groups to different agents. - -```json5 -{ - agents: { - list: [ - { id: "main" }, - { - id: "clawd-fan", - workspace: "/home/user/clawd-fan", - agentDir: "/home/user/.openclaw/agents/clawd-fan/agent", - }, - { - id: "clawd-xi", - workspace: "/home/user/clawd-xi", - agentDir: "/home/user/.openclaw/agents/clawd-xi/agent", - }, - ], - }, - bindings: [ - { - agentId: "main", - match: { - channel: "feishu", - peer: { kind: "direct", id: "ou_xxx" }, - }, - }, - { - agentId: "clawd-fan", - match: { - channel: "feishu", - peer: { kind: "direct", id: "ou_yyy" }, - }, - }, - { - agentId: "clawd-xi", - match: { - channel: "feishu", - peer: { kind: "group", id: "oc_zzz" }, - }, - }, - ], -} -``` - -Routing fields: - -- `match.channel`: `"feishu"` -- `match.peer.kind`: `"direct"` or `"group"` -- `match.peer.id`: user Open ID (`ou_xxx`) or group ID (`oc_xxx`) - -See [Get group/user IDs](#get-groupuser-ids) for lookup tips. - ---- - -## Configuration reference - -Full configuration: [Gateway configuration](/gateway/configuration) - -Key options: - -| Setting | Description | Default | -| ------------------------------------------------- | ------------------------------- | ---------------- | -| `channels.feishu.enabled` | Enable/disable channel | `true` | -| `channels.feishu.domain` | API domain (`feishu` or `lark`) | `feishu` | -| `channels.feishu.connectionMode` | Event transport mode | `websocket` | -| `channels.feishu.verificationToken` | 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..appId` | App ID | - | -| `channels.feishu.accounts..appSecret` | App Secret | - | -| `channels.feishu.accounts..domain` | Per-account API domain override | `feishu` | -| `channels.feishu.dmPolicy` | DM policy | `pairing` | -| `channels.feishu.allowFrom` | DM allowlist (open_id list) | - | -| `channels.feishu.groupPolicy` | Group policy | `open` | -| `channels.feishu.groupAllowFrom` | Group allowlist | - | -| `channels.feishu.groups..requireMention` | Require @mention | `true` | -| `channels.feishu.groups..enabled` | Enable group | `true` | -| `channels.feishu.textChunkLimit` | Message chunk size | `2000` | -| `channels.feishu.mediaMaxMb` | Media size limit | `30` | -| `channels.feishu.streaming` | Enable streaming card output | `true` | -| `channels.feishu.blockStreaming` | Enable block streaming | `true` | - ---- - -## dmPolicy reference - -| Value | Behavior | -| ------------- | --------------------------------------------------------------- | -| `"pairing"` | **Default.** Unknown users get a pairing code; must be approved | -| `"allowlist"` | Only users in `allowFrom` can chat | -| `"open"` | Allow all users (requires `"*"` in allowFrom) | -| `"disabled"` | Disable DMs | - ---- - -## Supported message types - -### Receive - -- ✅ Text -- ✅ Rich text (post) -- ✅ Images -- ✅ Files -- ✅ Audio -- ✅ Video -- ✅ Stickers - -### Send - -- ✅ Text -- ✅ Images -- ✅ Files -- ✅ Audio -- ⚠️ Rich text (partial support) diff --git a/docs/channels/googlechat.md b/docs/channels/googlechat.md deleted file mode 100644 index 818a8288f5..0000000000 --- a/docs/channels/googlechat.md +++ /dev/null @@ -1,253 +0,0 @@ ---- -summary: "Google Chat app support status, capabilities, and configuration" -read_when: - - Working on Google Chat channel features -title: "Google Chat" ---- - -# Google Chat (Chat API) - -Status: ready for DMs + spaces via Google Chat API webhooks (HTTP only). - -## Quick setup (beginner) - -1. Create a Google Cloud project and enable the **Google Chat API**. - - Go to: [Google Chat API Credentials](https://console.cloud.google.com/apis/api/chat.googleapis.com/credentials) - - Enable the API if it is not already enabled. -2. Create a **Service Account**: - - Press **Create Credentials** > **Service Account**. - - Name it whatever you want (e.g., `openclaw-chat`). - - Leave permissions blank (press **Continue**). - - Leave principals with access blank (press **Done**). -3. Create and download the **JSON Key**: - - In the list of service accounts, click on the one you just created. - - Go to the **Keys** tab. - - Click **Add Key** > **Create new key**. - - Select **JSON** and press **Create**. -4. Store the downloaded JSON file on your gateway host (e.g., `~/.openclaw/googlechat-service-account.json`). -5. Create a Google Chat app in the [Google Cloud Console Chat Configuration](https://console.cloud.google.com/apis/api/chat.googleapis.com/hangouts-chat): - - Fill in the **Application info**: - - **App name**: (e.g. `OpenClaw`) - - **Avatar URL**: (e.g. `https://openclaw.ai/logo.png`) - - **Description**: (e.g. `Personal AI Assistant`) - - Enable **Interactive features**. - - Under **Functionality**, check **Join spaces and group conversations**. - - Under **Connection settings**, select **HTTP endpoint URL**. - - Under **Triggers**, select **Use a common HTTP endpoint URL for all triggers** and set it to your gateway's public URL followed by `/googlechat`. - - _Tip: Run `openclaw status` to find your gateway's public URL._ - - Under **Visibility**, check **Make this Chat app available to specific people and groups in <Your Domain>**. - - Enter your email address (e.g. `user@example.com`) in the text box. - - Click **Save** at the bottom. -6. **Enable the app status**: - - After saving, **refresh the page**. - - Look for the **App status** section (usually near the top or bottom after saving). - - Change the status to **Live - available to users**. - - Click **Save** again. -7. Configure OpenClaw with the service account path + webhook audience: - - Env: `GOOGLE_CHAT_SERVICE_ACCOUNT_FILE=/path/to/service-account.json` - - Or config: `channels.googlechat.serviceAccountFile: "/path/to/service-account.json"`. -8. Set the webhook audience type + value (matches your Chat app config). -9. Start the gateway. Google Chat will POST to your webhook path. - -## Add to Google Chat - -Once the gateway is running and your email is added to the visibility list: - -1. Go to [Google Chat](https://chat.google.com/). -2. Click the **+** (plus) icon next to **Direct Messages**. -3. In the search bar (where you usually add people), type the **App name** you configured in the Google Cloud Console. - - **Note**: The bot will _not_ appear in the "Marketplace" browse list because it is a private app. You must search for it by name. -4. Select your bot from the results. -5. Click **Add** or **Chat** to start a 1:1 conversation. -6. Send "Hello" to trigger the assistant! - -## Public URL (Webhook-only) - -Google Chat webhooks require a public HTTPS endpoint. For security, **only expose the `/googlechat` path** to the internet. Keep the OpenClaw dashboard and other sensitive endpoints on your private network. - -### Option A: Tailscale Funnel (Recommended) - -Use Tailscale Serve for the private dashboard and Funnel for the public webhook path. This keeps `/` private while exposing only `/googlechat`. - -1. **Check what address your gateway is bound to:** - - ```bash - ss -tlnp | grep 18789 - ``` - - Note the IP address (e.g., `127.0.0.1`, `0.0.0.0`, or your Tailscale IP like `100.x.x.x`). - -2. **Expose the dashboard to the tailnet only (port 8443):** - - ```bash - # If bound to localhost (127.0.0.1 or 0.0.0.0): - tailscale serve --bg --https 8443 http://127.0.0.1:18789 - - # If bound to Tailscale IP only (e.g., 100.106.161.80): - tailscale serve --bg --https 8443 http://100.106.161.80:18789 - ``` - -3. **Expose only the webhook path publicly:** - - ```bash - # If bound to localhost (127.0.0.1 or 0.0.0.0): - tailscale funnel --bg --set-path /googlechat http://127.0.0.1:18789/googlechat - - # If bound to Tailscale IP only (e.g., 100.106.161.80): - tailscale funnel --bg --set-path /googlechat http://100.106.161.80:18789/googlechat - ``` - -4. **Authorize the node for Funnel access:** - If prompted, visit the authorization URL shown in the output to enable Funnel for this node in your tailnet policy. - -5. **Verify the configuration:** - - ```bash - tailscale serve status - tailscale funnel status - ``` - -Your public webhook URL will be: -`https://..ts.net/googlechat` - -Your private dashboard stays tailnet-only: -`https://..ts.net:8443/` - -Use the public URL (without `:8443`) in the Google Chat app config. - -> Note: This configuration persists across reboots. To remove it later, run `tailscale funnel reset` and `tailscale serve reset`. - -### Option B: Reverse Proxy (Caddy) - -If you use a reverse proxy like Caddy, only proxy the specific path: - -```caddy -your-domain.com { - reverse_proxy /googlechat* localhost:18789 -} -``` - -With this config, any request to `your-domain.com/` will be ignored or returned as 404, while `your-domain.com/googlechat` is safely routed to OpenClaw. - -### Option C: Cloudflare Tunnel - -Configure your tunnel's ingress rules to only route the webhook path: - -- **Path**: `/googlechat` -> `http://localhost:18789/googlechat` -- **Default Rule**: HTTP 404 (Not Found) - -## How it works - -1. Google Chat sends webhook POSTs to the gateway. Each request includes an `Authorization: Bearer ` header. -2. OpenClaw verifies the token against the configured `audienceType` + `audience`: - - `audienceType: "app-url"` → audience is your HTTPS webhook URL. - - `audienceType: "project-number"` → audience is the Cloud project number. -3. Messages are routed by space: - - DMs use session key `agent::googlechat:dm:`. - - Spaces use session key `agent::googlechat:group:`. -4. DM access is pairing by default. Unknown senders receive a pairing code; approve with: - - `openclaw pairing approve googlechat ` -5. Group spaces require @-mention by default. Use `botUser` if mention detection needs the app’s user name. - -## Targets - -Use these identifiers for delivery and allowlists: - -- Direct messages: `users/` (recommended) or raw email `name@example.com` (mutable principal). -- Deprecated: `users/` is treated as a user id, not an email allowlist. -- Spaces: `spaces/`. - -## Config highlights - -```json5 -{ - channels: { - googlechat: { - enabled: true, - serviceAccountFile: "/path/to/service-account.json", - audienceType: "app-url", - audience: "https://gateway.example.com/googlechat", - webhookPath: "/googlechat", - botUser: "users/1234567890", // optional; helps mention detection - dm: { - policy: "pairing", - allowFrom: ["users/1234567890", "name@example.com"], - }, - groupPolicy: "allowlist", - groups: { - "spaces/AAAA": { - allow: true, - requireMention: true, - users: ["users/1234567890"], - systemPrompt: "Short answers only.", - }, - }, - actions: { reactions: true }, - typingIndicator: "message", - mediaMaxMb: 20, - }, - }, -} -``` - -Notes: - -- Service account credentials can also be passed inline with `serviceAccount` (JSON string). -- Default webhook path is `/googlechat` if `webhookPath` isn’t set. -- Reactions are available via the `reactions` tool and `channels action` when `actions.reactions` is enabled. -- `typingIndicator` supports `none`, `message` (default), and `reaction` (reaction requires user OAuth). -- Attachments are downloaded through the Chat API and stored in the media pipeline (size capped by `mediaMaxMb`). - -## Troubleshooting - -### 405 Method Not Allowed - -If Google Cloud Logs Explorer shows errors like: - -``` -status code: 405, reason phrase: HTTP error response: HTTP/1.1 405 Method Not Allowed -``` - -This means the webhook handler isn't registered. Common causes: - -1. **Channel not configured**: The `channels.googlechat` section is missing from your config. Verify with: - - ```bash - openclaw config get channels.googlechat - ``` - - If it returns "Config path not found", add the configuration (see [Config highlights](#config-highlights)). - -2. **Plugin not enabled**: Check plugin status: - - ```bash - openclaw plugins list | grep googlechat - ``` - - If it shows "disabled", add `plugins.entries.googlechat.enabled: true` to your config. - -3. **Gateway not restarted**: After adding config, restart the gateway: - - ```bash - openclaw gateway restart - ``` - -Verify the channel is running: - -```bash -openclaw channels status -# Should show: Google Chat default: enabled, configured, ... -``` - -### Other issues - -- Check `openclaw channels status --probe` for auth errors or missing audience config. -- If no messages arrive, confirm the Chat app's webhook URL + event subscriptions. -- If mention gating blocks replies, set `botUser` to the app's user resource name and verify `requireMention`. -- Use `openclaw logs --follow` while sending a test message to see if requests reach the gateway. - -Related docs: - -- [Gateway configuration](/gateway/configuration) -- [Security](/gateway/security) -- [Reactions](/tools/reactions) diff --git a/docs/channels/grammy.md b/docs/channels/grammy.md deleted file mode 100644 index ae92c5292b..0000000000 --- a/docs/channels/grammy.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -summary: "Telegram Bot API integration via grammY with setup notes" -read_when: - - Working on Telegram or grammY pathways -title: grammY ---- - -# grammY Integration (Telegram Bot API) - -# Why grammY - -- TS-first Bot API client with built-in long-poll + webhook helpers, middleware, error handling, rate limiter. -- Cleaner media helpers than hand-rolling fetch + FormData; supports all Bot API methods. -- Extensible: proxy support via custom fetch, session middleware (optional), type-safe context. - -# What we shipped - -- **Single client path:** fetch-based implementation removed; grammY is now the sole Telegram client (send + gateway) with the grammY throttler enabled by default. -- **Gateway:** `monitorTelegramProvider` builds a grammY `Bot`, wires mention/allowlist gating, media download via `getFile`/`download`, and delivers replies with `sendMessage/sendPhoto/sendVideo/sendAudio/sendDocument`. Supports long-poll or webhook via `webhookCallback`. -- **Proxy:** optional `channels.telegram.proxy` uses `undici.ProxyAgent` through grammY’s `client.baseFetch`. -- **Webhook support:** `webhook-set.ts` wraps `setWebhook/deleteWebhook`; `webhook.ts` hosts the callback with health + graceful shutdown. Gateway enables webhook mode when `channels.telegram.webhookUrl` + `channels.telegram.webhookSecret` are set (otherwise it long-polls). -- **Sessions:** direct chats collapse into the agent main session (`agent::`); groups use `agent::telegram:group:`; replies route back to the same channel. -- **Config knobs:** `channels.telegram.botToken`, `channels.telegram.dmPolicy`, `channels.telegram.groups` (allowlist + mention defaults), `channels.telegram.allowFrom`, `channels.telegram.groupAllowFrom`, `channels.telegram.groupPolicy`, `channels.telegram.mediaMaxMb`, `channels.telegram.linkPreview`, `channels.telegram.proxy`, `channels.telegram.webhookSecret`, `channels.telegram.webhookUrl`, `channels.telegram.webhookHost`. -- **Live stream preview:** optional `channels.telegram.streamMode` sends a temporary message and updates it with `editMessageText`. This is separate from channel block streaming. -- **Tests:** grammy mocks cover DM + group mention gating and outbound send; more media/webhook fixtures still welcome. - -Open questions - -- Optional grammY plugins (throttler) if we hit Bot API 429s. -- Add more structured media tests (stickers, voice notes). -- Make webhook listen port configurable (currently fixed to 8787 unless wired through the gateway). diff --git a/docs/channels/group-messages.md b/docs/channels/group-messages.md deleted file mode 100644 index e6a00ab5c5..0000000000 --- a/docs/channels/group-messages.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -summary: "Behavior and config for WhatsApp group message handling (mentionPatterns are shared across surfaces)" -read_when: - - Changing group message rules or mentions -title: "Group Messages" ---- - -# Group messages (WhatsApp web channel) - -Goal: let Clawd sit in WhatsApp groups, wake up only when pinged, and keep that thread separate from the personal DM session. - -Note: `agents.list[].groupChat.mentionPatterns` is now used by Telegram/Discord/Slack/iMessage as well; this doc focuses on WhatsApp-specific behavior. For multi-agent setups, set `agents.list[].groupChat.mentionPatterns` per agent (or use `messages.groupChat.mentionPatterns` as a global fallback). - -## What’s implemented (2025-12-03) - -- Activation modes: `mention` (default) or `always`. `mention` requires a ping (real WhatsApp @-mentions via `mentionedJids`, regex patterns, or the bot’s E.164 anywhere in the text). `always` wakes the agent on every message but it should reply only when it can add meaningful value; otherwise it returns the silent token `NO_REPLY`. Defaults can be set in config (`channels.whatsapp.groups`) and overridden per group via `/activation`. When `channels.whatsapp.groups` is set, it also acts as a group allowlist (include `"*"` to allow all). -- Group policy: `channels.whatsapp.groupPolicy` controls whether group messages are accepted (`open|disabled|allowlist`). `allowlist` uses `channels.whatsapp.groupAllowFrom` (fallback: explicit `channels.whatsapp.allowFrom`). Default is `allowlist` (blocked until you add senders). -- Per-group sessions: session keys look like `agent::whatsapp:group:` so commands such as `/verbose on` or `/think high` (sent as standalone messages) are scoped to that group; personal DM state is untouched. Heartbeats are skipped for group threads. -- Context injection: **pending-only** group messages (default 50) that _did not_ trigger a run are prefixed under `[Chat messages since your last reply - for context]`, with the triggering line under `[Current message - respond to this]`. Messages already in the session are not re-injected. -- Sender surfacing: every group batch now ends with `[from: Sender Name (+E164)]` so Pi knows who is speaking. -- Ephemeral/view-once: we unwrap those before extracting text/mentions, so pings inside them still trigger. -- Group system prompt: on the first turn of a group session (and whenever `/activation` changes the mode) we inject a short blurb into the system prompt like `You are replying inside the WhatsApp group "". Group members: Alice (+44...), Bob (+43...), … Activation: trigger-only … Address the specific sender noted in the message context.` If metadata isn’t available we still tell the agent it’s a group chat. - -## Config example (WhatsApp) - -Add a `groupChat` block to `~/.openclaw/openclaw.json` so display-name pings work even when WhatsApp strips the visual `@` in the text body: - -```json5 -{ - channels: { - whatsapp: { - groups: { - "*": { requireMention: true }, - }, - }, - }, - agents: { - list: [ - { - id: "main", - groupChat: { - historyLimit: 50, - mentionPatterns: ["@?openclaw", "\\+?15555550123"], - }, - }, - ], - }, -} -``` - -Notes: - -- The regexes are case-insensitive; they cover a display-name ping like `@openclaw` and the raw number with or without `+`/spaces. -- WhatsApp still sends canonical mentions via `mentionedJids` when someone taps the contact, so the number fallback is rarely needed but is a useful safety net. - -### Activation command (owner-only) - -Use the group chat command: - -- `/activation mention` -- `/activation always` - -Only the owner number (from `channels.whatsapp.allowFrom`, or the bot’s own E.164 when unset) can change this. Send `/status` as a standalone message in the group to see the current activation mode. - -## How to use - -1. Add your WhatsApp account (the one running OpenClaw) to the group. -2. Say `@openclaw …` (or include the number). Only allowlisted senders can trigger it unless you set `groupPolicy: "open"`. -3. The agent prompt will include recent group context plus the trailing `[from: …]` marker so it can address the right person. -4. Session-level directives (`/verbose on`, `/think high`, `/new` or `/reset`, `/compact`) apply only to that group’s session; send them as standalone messages so they register. Your personal DM session remains independent. - -## Testing / verification - -- Manual smoke: - - Send an `@openclaw` ping in the group and confirm a reply that references the sender name. - - Send a second ping and verify the history block is included then cleared on the next turn. -- Check gateway logs (run with `--verbose`) to see `inbound web message` entries showing `from: ` and the `[from: …]` suffix. - -## Known considerations - -- Heartbeats are intentionally skipped for groups to avoid noisy broadcasts. -- Echo suppression uses the combined batch string; if you send identical text twice without mentions, only the first will get a response. -- Session store entries will appear as `agent::whatsapp:group:` in the session store (`~/.openclaw/agents//sessions/sessions.json` by default); a missing entry just means the group hasn’t triggered a run yet. -- Typing indicators in groups follow `agents.defaults.typingMode` (default: `message` when unmentioned). diff --git a/docs/channels/groups.md b/docs/channels/groups.md deleted file mode 100644 index 6bd278846c..0000000000 --- a/docs/channels/groups.md +++ /dev/null @@ -1,374 +0,0 @@ ---- -summary: "Group chat behavior across surfaces (WhatsApp/Telegram/Discord/Slack/Signal/iMessage/Microsoft Teams)" -read_when: - - Changing group chat behavior or mention gating -title: "Groups" ---- - -# Groups - -OpenClaw treats group chats consistently across surfaces: WhatsApp, Telegram, Discord, Slack, Signal, iMessage, Microsoft Teams. - -## Beginner intro (2 minutes) - -OpenClaw “lives” on your own messaging accounts. There is no separate WhatsApp bot user. -If **you** are in a group, OpenClaw can see that group and respond there. - -Default behavior: - -- Groups are restricted (`groupPolicy: "allowlist"`). -- Replies require a mention unless you explicitly disable mention gating. - -Translation: allowlisted senders can trigger OpenClaw by mentioning it. - -> TL;DR -> -> - **DM access** is controlled by `*.allowFrom`. -> - **Group access** is controlled by `*.groupPolicy` + allowlists (`*.groups`, `*.groupAllowFrom`). -> - **Reply triggering** is controlled by mention gating (`requireMention`, `/activation`). - -Quick flow (what happens to a group message): - -``` -groupPolicy? disabled -> drop -groupPolicy? allowlist -> group allowed? no -> drop -requireMention? yes -> mentioned? no -> store for context only -otherwise -> reply -``` - -![Group message flow](/images/groups-flow.svg) - -If you want... - -| Goal | What to set | -| -------------------------------------------- | ---------------------------------------------------------- | -| Allow all groups but only reply on @mentions | `groups: { "*": { requireMention: true } }` | -| Disable all group replies | `groupPolicy: "disabled"` | -| Only specific groups | `groups: { "": { ... } }` (no `"*"` key) | -| Only you can trigger in groups | `groupPolicy: "allowlist"`, `groupAllowFrom: ["+1555..."]` | - -## Session keys - -- Group sessions use `agent:::group:` session keys (rooms/channels use `agent:::channel:`). -- Telegram forum topics add `:topic:` to the group id so each topic has its own session. -- Direct chats use the main session (or per-sender if configured). -- Heartbeats are skipped for group sessions. - -## Pattern: personal DMs + public groups (single agent) - -Yes — this works well if your “personal” traffic is **DMs** and your “public” traffic is **groups**. - -Why: in single-agent mode, DMs typically land in the **main** session key (`agent:main:main`), while groups always use **non-main** session keys (`agent:main::group:`). If you enable sandboxing with `mode: "non-main"`, those group sessions run in Docker while your main DM session stays on-host. - -This gives you one agent “brain” (shared workspace + memory), but two execution postures: - -- **DMs**: full tools (host) -- **Groups**: sandbox + restricted tools (Docker) - -> If you need truly separate workspaces/personas (“personal” and “public” must never mix), use a second agent + bindings. See [Multi-Agent Routing](/concepts/multi-agent). - -Example (DMs on host, groups sandboxed + messaging-only tools): - -```json5 -{ - agents: { - defaults: { - sandbox: { - mode: "non-main", // groups/channels are non-main -> sandboxed - scope: "session", // strongest isolation (one container per group/channel) - workspaceAccess: "none", - }, - }, - }, - tools: { - sandbox: { - tools: { - // If allow is non-empty, everything else is blocked (deny still wins). - allow: ["group:messaging", "group:sessions"], - deny: ["group:runtime", "group:fs", "group:ui", "nodes", "cron", "gateway"], - }, - }, - }, -} -``` - -Want “groups can only see folder X” instead of “no host access”? Keep `workspaceAccess: "none"` and mount only allowlisted paths into the sandbox: - -```json5 -{ - agents: { - defaults: { - sandbox: { - mode: "non-main", - scope: "session", - workspaceAccess: "none", - docker: { - binds: [ - // hostPath:containerPath:mode - "/home/user/FriendsShared:/data:ro", - ], - }, - }, - }, - }, -} -``` - -Related: - -- Configuration keys and defaults: [Gateway configuration](/gateway/configuration#agentsdefaultssandbox) -- Debugging why a tool is blocked: [Sandbox vs Tool Policy vs Elevated](/gateway/sandbox-vs-tool-policy-vs-elevated) -- Bind mounts details: [Sandboxing](/gateway/sandboxing#custom-bind-mounts) - -## Display labels - -- UI labels use `displayName` when available, formatted as `:`. -- `#room` is reserved for rooms/channels; group chats use `g-` (lowercase, spaces -> `-`, keep `#@+._-`). - -## Group policy - -Control how group/room messages are handled per channel: - -```json5 -{ - channels: { - whatsapp: { - groupPolicy: "disabled", // "open" | "disabled" | "allowlist" - groupAllowFrom: ["+15551234567"], - }, - telegram: { - groupPolicy: "disabled", - groupAllowFrom: ["123456789"], // numeric Telegram user id (wizard can resolve @username) - }, - signal: { - groupPolicy: "disabled", - groupAllowFrom: ["+15551234567"], - }, - imessage: { - groupPolicy: "disabled", - groupAllowFrom: ["chat_id:123"], - }, - msteams: { - groupPolicy: "disabled", - groupAllowFrom: ["user@org.com"], - }, - discord: { - groupPolicy: "allowlist", - guilds: { - GUILD_ID: { channels: { help: { allow: true } } }, - }, - }, - slack: { - groupPolicy: "allowlist", - channels: { "#general": { allow: true } }, - }, - matrix: { - groupPolicy: "allowlist", - groupAllowFrom: ["@owner:example.org"], - groups: { - "!roomId:example.org": { allow: true }, - "#alias:example.org": { allow: true }, - }, - }, - }, -} -``` - -| Policy | Behavior | -| ------------- | ------------------------------------------------------------ | -| `"open"` | Groups bypass allowlists; mention-gating still applies. | -| `"disabled"` | Block all group messages entirely. | -| `"allowlist"` | Only allow groups/rooms that match the configured allowlist. | - -Notes: - -- `groupPolicy` is separate from mention-gating (which requires @mentions). -- WhatsApp/Telegram/Signal/iMessage/Microsoft Teams: use `groupAllowFrom` (fallback: explicit `allowFrom`). -- Discord: allowlist uses `channels.discord.guilds..channels`. -- Slack: allowlist uses `channels.slack.channels`. -- Matrix: allowlist uses `channels.matrix.groups` (room IDs, aliases, or names). Use `channels.matrix.groupAllowFrom` to restrict senders; per-room `users` allowlists are also supported. -- Group DMs are controlled separately (`channels.discord.dm.*`, `channels.slack.dm.*`). -- Telegram allowlist can match user IDs (`"123456789"`, `"telegram:123456789"`, `"tg:123456789"`) or usernames (`"@alice"` or `"alice"`); prefixes are case-insensitive. -- Default is `groupPolicy: "allowlist"`; if your group allowlist is empty, group messages are blocked. - -Quick mental model (evaluation order for group messages): - -1. `groupPolicy` (open/disabled/allowlist) -2. group allowlists (`*.groups`, `*.groupAllowFrom`, channel-specific allowlist) -3. mention gating (`requireMention`, `/activation`) - -## Mention gating (default) - -Group messages require a mention unless overridden per group. Defaults live per subsystem under `*.groups."*"`. - -Replying to a bot message counts as an implicit mention (when the channel supports reply metadata). This applies to Telegram, WhatsApp, Slack, Discord, and Microsoft Teams. - -```json5 -{ - channels: { - whatsapp: { - groups: { - "*": { requireMention: true }, - "123@g.us": { requireMention: false }, - }, - }, - telegram: { - groups: { - "*": { requireMention: true }, - "123456789": { requireMention: false }, - }, - }, - imessage: { - groups: { - "*": { requireMention: true }, - "123": { requireMention: false }, - }, - }, - }, - agents: { - list: [ - { - id: "main", - groupChat: { - mentionPatterns: ["@openclaw", "openclaw", "\\+15555550123"], - historyLimit: 50, - }, - }, - ], - }, -} -``` - -Notes: - -- `mentionPatterns` are case-insensitive regexes. -- Surfaces that provide explicit mentions still pass; patterns are a fallback. -- Per-agent override: `agents.list[].groupChat.mentionPatterns` (useful when multiple agents share a group). -- Mention gating is only enforced when mention detection is possible (native mentions or `mentionPatterns` are configured). -- Discord defaults live in `channels.discord.guilds."*"` (overridable per guild/channel). -- Group history context is wrapped uniformly across channels and is **pending-only** (messages skipped due to mention gating); use `messages.groupChat.historyLimit` for the global default and `channels..historyLimit` (or `channels..accounts.*.historyLimit`) for overrides. Set `0` to disable. - -## Group/channel tool restrictions (optional) - -Some channel configs support restricting which tools are available **inside a specific group/room/channel**. - -- `tools`: allow/deny tools for the whole group. -- `toolsBySender`: per-sender overrides within the group (keys are sender IDs/usernames/emails/phone numbers depending on the channel). Use `"*"` as a wildcard. - -Resolution order (most specific wins): - -1. group/channel `toolsBySender` match -2. group/channel `tools` -3. default (`"*"`) `toolsBySender` match -4. default (`"*"`) `tools` - -Example (Telegram): - -```json5 -{ - channels: { - telegram: { - groups: { - "*": { tools: { deny: ["exec"] } }, - "-1001234567890": { - tools: { deny: ["exec", "read", "write"] }, - toolsBySender: { - "123456789": { alsoAllow: ["exec"] }, - }, - }, - }, - }, - }, -} -``` - -Notes: - -- Group/channel tool restrictions are applied in addition to global/agent tool policy (deny still wins). -- Some channels use different nesting for rooms/channels (e.g., Discord `guilds.*.channels.*`, Slack `channels.*`, MS Teams `teams.*.channels.*`). - -## Group allowlists - -When `channels.whatsapp.groups`, `channels.telegram.groups`, or `channels.imessage.groups` is configured, the keys act as a group allowlist. Use `"*"` to allow all groups while still setting default mention behavior. - -Common intents (copy/paste): - -1. Disable all group replies - -```json5 -{ - channels: { whatsapp: { groupPolicy: "disabled" } }, -} -``` - -2. Allow only specific groups (WhatsApp) - -```json5 -{ - channels: { - whatsapp: { - groups: { - "123@g.us": { requireMention: true }, - "456@g.us": { requireMention: false }, - }, - }, - }, -} -``` - -3. Allow all groups but require mention (explicit) - -```json5 -{ - channels: { - whatsapp: { - groups: { "*": { requireMention: true } }, - }, - }, -} -``` - -4. Only the owner can trigger in groups (WhatsApp) - -```json5 -{ - channels: { - whatsapp: { - groupPolicy: "allowlist", - groupAllowFrom: ["+15551234567"], - groups: { "*": { requireMention: true } }, - }, - }, -} -``` - -## Activation (owner-only) - -Group owners can toggle per-group activation: - -- `/activation mention` -- `/activation always` - -Owner is determined by `channels.whatsapp.allowFrom` (or the bot’s self E.164 when unset). Send the command as a standalone message. Other surfaces currently ignore `/activation`. - -## Context fields - -Group inbound payloads set: - -- `ChatType=group` -- `GroupSubject` (if known) -- `GroupMembers` (if known) -- `WasMentioned` (mention gating result) -- Telegram forum topics also include `MessageThreadId` and `IsForum`. - -The agent system prompt includes a group intro on the first turn of a new group session. It reminds the model to respond like a human, avoid Markdown tables, and avoid typing literal `\n` sequences. - -## iMessage specifics - -- Prefer `chat_id:` when routing or allowlisting. -- List chats: `imsg chats --limit 20`. -- Group replies always go back to the same `chat_id`. - -## WhatsApp specifics - -See [Group messages](/channels/group-messages) for WhatsApp-only behavior (history injection, mention handling details). diff --git a/docs/channels/imessage.md b/docs/channels/imessage.md deleted file mode 100644 index d7a1b63359..0000000000 --- a/docs/channels/imessage.md +++ /dev/null @@ -1,366 +0,0 @@ ---- -summary: "Legacy iMessage support via imsg (JSON-RPC over stdio). New setups should use BlueBubbles." -read_when: - - Setting up iMessage support - - Debugging iMessage send/receive -title: "iMessage" ---- - -# iMessage (legacy: imsg) - - -For new iMessage deployments, use BlueBubbles. - -The `imsg` integration is legacy and may be removed in a future release. - - -Status: legacy external CLI integration. Gateway spawns `imsg rpc` and communicates over JSON-RPC on stdio (no separate daemon/port). - - - - Preferred iMessage path for new setups. - - - iMessage DMs default to pairing mode. - - - Full iMessage field reference. - - - -## Quick setup - - - - - - -```bash -brew install steipete/tap/imsg -imsg rpc --help -``` - - - - - -```json5 -{ - channels: { - imessage: { - enabled: true, - cliPath: "/usr/local/bin/imsg", - dbPath: "/Users//Library/Messages/chat.db", - }, - }, -} -``` - - - - - -```bash -openclaw gateway -``` - - - - - -```bash -openclaw pairing list imessage -openclaw pairing approve imessage -``` - - Pairing requests expire after 1 hour. - - - - - - - OpenClaw only requires a stdio-compatible `cliPath`, so you can point `cliPath` at a wrapper script that SSHes to a remote Mac and runs `imsg`. - -```bash -#!/usr/bin/env bash -exec ssh -T gateway-host imsg "$@" -``` - - Recommended config when attachments are enabled: - -```json5 -{ - channels: { - imessage: { - enabled: true, - cliPath: "~/.openclaw/scripts/imsg-ssh", - remoteHost: "user@gateway-host", // used for SCP attachment fetches - includeAttachments: true, - // Optional: override allowed attachment roots. - // Defaults include /Users/*/Library/Messages/Attachments - attachmentRoots: ["/Users/*/Library/Messages/Attachments"], - remoteAttachmentRoots: ["/Users/*/Library/Messages/Attachments"], - }, - }, -} -``` - - If `remoteHost` is not set, OpenClaw attempts to auto-detect it by parsing the SSH wrapper script. - `remoteHost` must be `host` or `user@host` (no spaces or SSH options). - OpenClaw uses strict host-key checking for SCP, so the relay host key must already exist in `~/.ssh/known_hosts`. - Attachment paths are validated against allowed roots (`attachmentRoots` / `remoteAttachmentRoots`). - - - - -## Requirements and permissions (macOS) - -- Messages must be signed in on the Mac running `imsg`. -- Full Disk Access is required for the process context running OpenClaw/`imsg` (Messages DB access). -- Automation permission is required to send messages through Messages.app. - - -Permissions are granted per process context. If gateway runs headless (LaunchAgent/SSH), run a one-time interactive command in that same context to trigger prompts: - -```bash -imsg chats --limit 1 -# or -imsg send "test" -``` - - - -## Access control and routing - - - - `channels.imessage.dmPolicy` controls direct messages: - - - `pairing` (default) - - `allowlist` - - `open` (requires `allowFrom` to include `"*"`) - - `disabled` - - Allowlist field: `channels.imessage.allowFrom`. - - Allowlist entries can be handles or chat targets (`chat_id:*`, `chat_guid:*`, `chat_identifier:*`). - - - - - `channels.imessage.groupPolicy` controls group handling: - - - `allowlist` (default when configured) - - `open` - - `disabled` - - Group sender allowlist: `channels.imessage.groupAllowFrom`. - - Runtime fallback: if `groupAllowFrom` is unset, iMessage group sender checks fall back to `allowFrom` when available. - - Mention gating for groups: - - - iMessage has no native mention metadata - - mention detection uses regex patterns (`agents.list[].groupChat.mentionPatterns`, fallback `messages.groupChat.mentionPatterns`) - - with no configured patterns, mention gating cannot be enforced - - Control commands from authorized senders can bypass mention gating in groups. - - - - - - DMs use direct routing; groups use group routing. - - With default `session.dmScope=main`, iMessage DMs collapse into the agent main session. - - Group sessions are isolated (`agent::imessage:group:`). - - Replies route back to iMessage using originating channel/target metadata. - - Group-ish thread behavior: - - Some multi-participant iMessage threads can arrive with `is_group=false`. - If that `chat_id` is explicitly configured under `channels.imessage.groups`, OpenClaw treats it as group traffic (group gating + group session isolation). - - - - -## Deployment patterns - - - - Use a dedicated Apple ID and macOS user so bot traffic is isolated from your personal Messages profile. - - Typical flow: - - 1. Create/sign in a dedicated macOS user. - 2. Sign into Messages with the bot Apple ID in that user. - 3. Install `imsg` in that user. - 4. Create SSH wrapper so OpenClaw can run `imsg` in that user context. - 5. Point `channels.imessage.accounts..cliPath` and `.dbPath` to that user profile. - - First run may require GUI approvals (Automation + Full Disk Access) in that bot user session. - - - - - Common topology: - - - gateway runs on Linux/VM - - iMessage + `imsg` runs on a Mac in your tailnet - - `cliPath` wrapper uses SSH to run `imsg` - - `remoteHost` enables SCP attachment fetches - - Example: - -```json5 -{ - channels: { - imessage: { - enabled: true, - cliPath: "~/.openclaw/scripts/imsg-ssh", - remoteHost: "bot@mac-mini.tailnet-1234.ts.net", - includeAttachments: true, - dbPath: "/Users/bot/Library/Messages/chat.db", - }, - }, -} -``` - -```bash -#!/usr/bin/env bash -exec ssh -T bot@mac-mini.tailnet-1234.ts.net imsg "$@" -``` - - Use SSH keys so both SSH and SCP are non-interactive. - Ensure the host key is trusted first (for example `ssh bot@mac-mini.tailnet-1234.ts.net`) so `known_hosts` is populated. - - - - - iMessage supports per-account config under `channels.imessage.accounts`. - - Each account can override fields such as `cliPath`, `dbPath`, `allowFrom`, `groupPolicy`, `mediaMaxMb`, history settings, and attachment root allowlists. - - - - -## Media, chunking, and delivery targets - - - - - inbound attachment ingestion is optional: `channels.imessage.includeAttachments` - - remote attachment paths can be fetched via SCP when `remoteHost` is set - - attachment paths must match allowed roots: - - `channels.imessage.attachmentRoots` (local) - - `channels.imessage.remoteAttachmentRoots` (remote SCP mode) - - default root pattern: `/Users/*/Library/Messages/Attachments` - - SCP uses strict host-key checking (`StrictHostKeyChecking=yes`) - - outbound media size uses `channels.imessage.mediaMaxMb` (default 16 MB) - - - - - text chunk limit: `channels.imessage.textChunkLimit` (default 4000) - - chunk mode: `channels.imessage.chunkMode` - - `length` (default) - - `newline` (paragraph-first splitting) - - - - Preferred explicit targets: - - - `chat_id:123` (recommended for stable routing) - - `chat_guid:...` - - `chat_identifier:...` - - Handle targets are also supported: - - - `imessage:+1555...` - - `sms:+1555...` - - `user@example.com` - -```bash -imsg chats --limit 20 -``` - - - - -## Config writes - -iMessage allows channel-initiated config writes by default (for `/config set|unset` when `commands.config: true`). - -Disable: - -```json5 -{ - channels: { - imessage: { - configWrites: false, - }, - }, -} -``` - -## Troubleshooting - - - - Validate the binary and RPC support: - -```bash -imsg rpc --help -openclaw channels status --probe -``` - - If probe reports RPC unsupported, update `imsg`. - - - - - Check: - - - `channels.imessage.dmPolicy` - - `channels.imessage.allowFrom` - - pairing approvals (`openclaw pairing list imessage`) - - - - - Check: - - - `channels.imessage.groupPolicy` - - `channels.imessage.groupAllowFrom` - - `channels.imessage.groups` allowlist behavior - - mention pattern configuration (`agents.list[].groupChat.mentionPatterns`) - - - - - Check: - - - `channels.imessage.remoteHost` - - `channels.imessage.remoteAttachmentRoots` - - SSH/SCP key auth from the gateway host - - host key exists in `~/.ssh/known_hosts` on the gateway host - - remote path readability on the Mac running Messages - - - - - Re-run in an interactive GUI terminal in the same user/session context and approve prompts: - -```bash -imsg chats --limit 1 -imsg send "test" -``` - - Confirm Full Disk Access + Automation are granted for the process context that runs OpenClaw/`imsg`. - - - - -## Configuration reference pointers - -- [Configuration reference - iMessage](/gateway/configuration-reference#imessage) -- [Gateway configuration](/gateway/configuration) -- [Pairing](/channels/pairing) -- [BlueBubbles](/channels/bluebubbles) diff --git a/docs/channels/index.md b/docs/channels/index.md deleted file mode 100644 index 181b8d080a..0000000000 --- a/docs/channels/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -summary: "Messaging platforms OpenClaw can connect to" -read_when: - - You want to choose a chat channel for OpenClaw - - You need a quick overview of supported messaging platforms -title: "Chat Channels" ---- - -# Chat Channels - -OpenClaw can talk to you on any chat app you already use. Each channel connects via the Gateway. -Text is supported everywhere; media and reactions vary by channel. - -## Supported channels - -- [WhatsApp](/channels/whatsapp) — Most popular; uses Baileys and requires QR pairing. -- [Telegram](/channels/telegram) — Bot API via grammY; supports groups. -- [Discord](/channels/discord) — Discord Bot API + Gateway; supports servers, channels, and DMs. -- [IRC](/channels/irc) — Classic IRC servers; channels + DMs with pairing/allowlist controls. -- [Slack](/channels/slack) — Bolt SDK; workspace apps. -- [Feishu](/channels/feishu) — Feishu/Lark bot via WebSocket (plugin, installed separately). -- [Google Chat](/channels/googlechat) — Google Chat API app via HTTP webhook. -- [Mattermost](/channels/mattermost) — Bot API + WebSocket; channels, groups, DMs (plugin, installed separately). -- [Signal](/channels/signal) — signal-cli; privacy-focused. -- [BlueBubbles](/channels/bluebubbles) — **Recommended for iMessage**; uses the BlueBubbles macOS server REST API with full feature support (edit, unsend, effects, reactions, group management — edit currently broken on macOS 26 Tahoe). -- [iMessage (legacy)](/channels/imessage) — Legacy macOS integration via imsg CLI (deprecated, use BlueBubbles for new setups). -- [Microsoft Teams](/channels/msteams) — Bot Framework; enterprise support (plugin, installed separately). -- [LINE](/channels/line) — LINE Messaging API bot (plugin, installed separately). -- [Nextcloud Talk](/channels/nextcloud-talk) — Self-hosted chat via Nextcloud Talk (plugin, installed separately). -- [Matrix](/channels/matrix) — Matrix protocol (plugin, installed separately). -- [Nostr](/channels/nostr) — Decentralized DMs via NIP-04 (plugin, installed separately). -- [Tlon](/channels/tlon) — Urbit-based messenger (plugin, installed separately). -- [Twitch](/channels/twitch) — Twitch chat via IRC connection (plugin, installed separately). -- [Zalo](/channels/zalo) — Zalo Bot API; Vietnam's popular messenger (plugin, installed separately). -- [Zalo Personal](/channels/zalouser) — Zalo personal account via QR login (plugin, installed separately). -- [WebChat](/web/webchat) — Gateway WebChat UI over WebSocket. - -## Notes - -- Channels can run simultaneously; configure multiple and OpenClaw will route per chat. -- Fastest setup is usually **Telegram** (simple bot token). WhatsApp requires QR pairing and - stores more state on disk. -- Group behavior varies by channel; see [Groups](/channels/groups). -- DM pairing and allowlists are enforced for safety; see [Security](/gateway/security). -- Telegram internals: [grammY notes](/channels/grammy). -- Troubleshooting: [Channel troubleshooting](/channels/troubleshooting). -- Model providers are documented separately; see [Model Providers](/providers/models). diff --git a/docs/channels/irc.md b/docs/channels/irc.md deleted file mode 100644 index 2bf6fb4eb4..0000000000 --- a/docs/channels/irc.md +++ /dev/null @@ -1,234 +0,0 @@ ---- -title: IRC -description: Connect OpenClaw to IRC channels and direct messages. ---- - -Use IRC when you want OpenClaw in classic channels (`#room`) and direct messages. -IRC ships as an extension plugin, but it is configured in the main config under `channels.irc`. - -## Quick start - -1. Enable IRC config in `~/.openclaw/openclaw.json`. -2. Set at least: - -```json -{ - "channels": { - "irc": { - "enabled": true, - "host": "irc.libera.chat", - "port": 6697, - "tls": true, - "nick": "openclaw-bot", - "channels": ["#openclaw"] - } - } -} -``` - -3. Start/restart gateway: - -```bash -openclaw gateway run -``` - -## Security defaults - -- `channels.irc.dmPolicy` defaults to `"pairing"`. -- `channels.irc.groupPolicy` defaults to `"allowlist"`. -- With `groupPolicy="allowlist"`, set `channels.irc.groups` to define allowed channels. -- Use TLS (`channels.irc.tls=true`) unless you intentionally accept plaintext transport. - -## Access control - -There are two separate “gates” for IRC channels: - -1. **Channel access** (`groupPolicy` + `groups`): whether the bot accepts messages from a channel at all. -2. **Sender access** (`groupAllowFrom` / per-channel `groups["#channel"].allowFrom`): who is allowed to trigger the bot inside that channel. - -Config keys: - -- DM allowlist (DM sender access): `channels.irc.allowFrom` -- Group sender allowlist (channel sender access): `channels.irc.groupAllowFrom` -- Per-channel controls (channel + sender + mention rules): `channels.irc.groups["#channel"]` -- `channels.irc.groupPolicy="open"` allows unconfigured channels (**still mention-gated by default**) - -Allowlist entries can use nick or `nick!user@host` forms. - -### Common gotcha: `allowFrom` is for DMs, not channels - -If you see logs like: - -- `irc: drop group sender alice!ident@host (policy=allowlist)` - -…it means the sender wasn’t allowed for **group/channel** messages. Fix it by either: - -- setting `channels.irc.groupAllowFrom` (global for all channels), or -- setting per-channel sender allowlists: `channels.irc.groups["#channel"].allowFrom` - -Example (allow anyone in `#tuirc-dev` to talk to the bot): - -```json5 -{ - channels: { - irc: { - groupPolicy: "allowlist", - groups: { - "#tuirc-dev": { allowFrom: ["*"] }, - }, - }, - }, -} -``` - -## Reply triggering (mentions) - -Even if a channel is allowed (via `groupPolicy` + `groups`) and the sender is allowed, OpenClaw defaults to **mention-gating** in group contexts. - -That means you may see logs like `drop channel … (missing-mention)` unless the message includes a mention pattern that matches the bot. - -To make the bot reply in an IRC channel **without needing a mention**, disable mention gating for that channel: - -```json5 -{ - channels: { - irc: { - groupPolicy: "allowlist", - groups: { - "#tuirc-dev": { - requireMention: false, - allowFrom: ["*"], - }, - }, - }, - }, -} -``` - -Or to allow **all** IRC channels (no per-channel allowlist) and still reply without mentions: - -```json5 -{ - channels: { - irc: { - groupPolicy: "open", - groups: { - "*": { requireMention: false, allowFrom: ["*"] }, - }, - }, - }, -} -``` - -## Security note (recommended for public channels) - -If you allow `allowFrom: ["*"]` in a public channel, anyone can prompt the bot. -To reduce risk, restrict tools for that channel. - -### Same tools for everyone in the channel - -```json5 -{ - channels: { - irc: { - groups: { - "#tuirc-dev": { - allowFrom: ["*"], - tools: { - deny: ["group:runtime", "group:fs", "gateway", "nodes", "cron", "browser"], - }, - }, - }, - }, - }, -} -``` - -### Different tools per sender (owner gets more power) - -Use `toolsBySender` to apply a stricter policy to `"*"` and a looser one to your nick: - -```json5 -{ - channels: { - irc: { - groups: { - "#tuirc-dev": { - allowFrom: ["*"], - toolsBySender: { - "*": { - deny: ["group:runtime", "group:fs", "gateway", "nodes", "cron", "browser"], - }, - eigen: { - deny: ["gateway", "nodes", "cron"], - }, - }, - }, - }, - }, - }, -} -``` - -Notes: - -- `toolsBySender` keys can be a nick (e.g. `"eigen"`) or a full hostmask (`"eigen!~eigen@174.127.248.171"`) for stronger identity matching. -- The first matching sender policy wins; `"*"` is the wildcard fallback. - -For more on group access vs mention-gating (and how they interact), see: [/channels/groups](/channels/groups). - -## NickServ - -To identify with NickServ after connect: - -```json -{ - "channels": { - "irc": { - "nickserv": { - "enabled": true, - "service": "NickServ", - "password": "your-nickserv-password" - } - } - } -} -``` - -Optional one-time registration on connect: - -```json -{ - "channels": { - "irc": { - "nickserv": { - "register": true, - "registerEmail": "bot@example.com" - } - } - } -} -``` - -Disable `register` after the nick is registered to avoid repeated REGISTER attempts. - -## Environment variables - -Default account supports: - -- `IRC_HOST` -- `IRC_PORT` -- `IRC_TLS` -- `IRC_NICK` -- `IRC_USERNAME` -- `IRC_REALNAME` -- `IRC_PASSWORD` -- `IRC_CHANNELS` (comma-separated) -- `IRC_NICKSERV_PASSWORD` -- `IRC_NICKSERV_REGISTER_EMAIL` - -## Troubleshooting - -- If the bot connects but never replies in channels, verify `channels.irc.groups` **and** whether mention-gating is dropping messages (`missing-mention`). If you want it to reply without pings, set `requireMention:false` for the channel. -- If login fails, verify nick availability and server password. -- If TLS fails on a custom network, verify host/port and certificate setup. diff --git a/docs/channels/line.md b/docs/channels/line.md deleted file mode 100644 index d32e683fbe..0000000000 --- a/docs/channels/line.md +++ /dev/null @@ -1,186 +0,0 @@ ---- -summary: "LINE Messaging API plugin setup, config, and usage" -read_when: - - You want to connect OpenClaw to LINE - - You need LINE webhook + credential setup - - You want LINE-specific message options -title: LINE ---- - -# LINE (plugin) - -LINE connects to OpenClaw via the LINE Messaging API. The plugin runs as a webhook -receiver on the gateway and uses your channel access token + channel secret for -authentication. - -Status: supported via plugin. Direct messages, group chats, media, locations, Flex -messages, template messages, and quick replies are supported. Reactions and threads -are not supported. - -## Plugin required - -Install the LINE plugin: - -```bash -openclaw plugins install @openclaw/line -``` - -Local checkout (when running from a git repo): - -```bash -openclaw plugins install ./extensions/line -``` - -## Setup - -1. Create a LINE Developers account and open the Console: - [https://developers.line.biz/console/](https://developers.line.biz/console/) -2. Create (or pick) a Provider and add a **Messaging API** channel. -3. Copy the **Channel access token** and **Channel secret** from the channel settings. -4. Enable **Use webhook** in the Messaging API settings. -5. Set the webhook URL to your gateway endpoint (HTTPS required): - -``` -https://gateway-host/line/webhook -``` - -The gateway responds to LINE’s webhook verification (GET) and inbound events (POST). -If you need a custom path, set `channels.line.webhookPath` or -`channels.line.accounts..webhookPath` and update the URL accordingly. - -## Configure - -Minimal config: - -```json5 -{ - channels: { - line: { - enabled: true, - channelAccessToken: "LINE_CHANNEL_ACCESS_TOKEN", - channelSecret: "LINE_CHANNEL_SECRET", - dmPolicy: "pairing", - }, - }, -} -``` - -Env vars (default account only): - -- `LINE_CHANNEL_ACCESS_TOKEN` -- `LINE_CHANNEL_SECRET` - -Token/secret files: - -```json5 -{ - channels: { - line: { - tokenFile: "/path/to/line-token.txt", - secretFile: "/path/to/line-secret.txt", - }, - }, -} -``` - -Multiple accounts: - -```json5 -{ - channels: { - line: { - accounts: { - marketing: { - channelAccessToken: "...", - channelSecret: "...", - webhookPath: "/line/marketing", - }, - }, - }, - }, -} -``` - -## Access control - -Direct messages default to pairing. Unknown senders get a pairing code and their -messages are ignored until approved. - -```bash -openclaw pairing list line -openclaw pairing approve line -``` - -Allowlists and policies: - -- `channels.line.dmPolicy`: `pairing | allowlist | open | disabled` -- `channels.line.allowFrom`: allowlisted LINE user IDs for DMs -- `channels.line.groupPolicy`: `allowlist | open | disabled` -- `channels.line.groupAllowFrom`: allowlisted LINE user IDs for groups -- Per-group overrides: `channels.line.groups..allowFrom` - -LINE IDs are case-sensitive. Valid IDs look like: - -- User: `U` + 32 hex chars -- Group: `C` + 32 hex chars -- Room: `R` + 32 hex chars - -## Message behavior - -- Text is chunked at 5000 characters. -- Markdown formatting is stripped; code blocks and tables are converted into Flex - cards when possible. -- Streaming responses are buffered; LINE receives full chunks with a loading - animation while the agent works. -- Media downloads are capped by `channels.line.mediaMaxMb` (default 10). - -## Channel data (rich messages) - -Use `channelData.line` to send quick replies, locations, Flex cards, or template -messages. - -```json5 -{ - text: "Here you go", - channelData: { - line: { - quickReplies: ["Status", "Help"], - location: { - title: "Office", - address: "123 Main St", - latitude: 35.681236, - longitude: 139.767125, - }, - flexMessage: { - altText: "Status card", - contents: { - /* Flex payload */ - }, - }, - templateMessage: { - type: "confirm", - text: "Proceed?", - confirmLabel: "Yes", - confirmData: "yes", - cancelLabel: "No", - cancelData: "no", - }, - }, - }, -} -``` - -The LINE plugin also ships a `/card` command for Flex message presets: - -``` -/card info "Welcome" "Thanks for joining!" -``` - -## Troubleshooting - -- **Webhook verification fails:** ensure the webhook URL is HTTPS and the - `channelSecret` matches the LINE console. -- **No inbound events:** confirm the webhook path matches `channels.line.webhookPath` - and that the gateway is reachable from LINE. -- **Media download errors:** raise `channels.line.mediaMaxMb` if media exceeds the - default limit. diff --git a/docs/channels/location.md b/docs/channels/location.md deleted file mode 100644 index 103f57663c..0000000000 --- a/docs/channels/location.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -summary: "Inbound channel location parsing (Telegram + WhatsApp) and context fields" -read_when: - - Adding or modifying channel location parsing - - Using location context fields in agent prompts or tools -title: "Channel Location Parsing" ---- - -# Channel location parsing - -OpenClaw normalizes shared locations from chat channels into: - -- human-readable text appended to the inbound body, and -- structured fields in the auto-reply context payload. - -Currently supported: - -- **Telegram** (location pins + venues + live locations) -- **WhatsApp** (locationMessage + liveLocationMessage) -- **Matrix** (`m.location` with `geo_uri`) - -## Text formatting - -Locations are rendered as friendly lines without brackets: - -- Pin: - - `📍 48.858844, 2.294351 ±12m` -- Named place: - - `📍 Eiffel Tower — Champ de Mars, Paris (48.858844, 2.294351 ±12m)` -- Live share: - - `🛰 Live location: 48.858844, 2.294351 ±12m` - -If the channel includes a caption/comment, it is appended on the next line: - -``` -📍 48.858844, 2.294351 ±12m -Meet here -``` - -## Context fields - -When a location is present, these fields are added to `ctx`: - -- `LocationLat` (number) -- `LocationLon` (number) -- `LocationAccuracy` (number, meters; optional) -- `LocationName` (string; optional) -- `LocationAddress` (string; optional) -- `LocationSource` (`pin | place | live`) -- `LocationIsLive` (boolean) - -## Channel notes - -- **Telegram**: venues map to `LocationName/LocationAddress`; live locations use `live_period`. -- **WhatsApp**: `locationMessage.comment` and `liveLocationMessage.caption` are appended as the caption line. -- **Matrix**: `geo_uri` is parsed as a pin location; altitude is ignored and `LocationIsLive` is always false. diff --git a/docs/channels/matrix.md b/docs/channels/matrix.md deleted file mode 100644 index 04205d9497..0000000000 --- a/docs/channels/matrix.md +++ /dev/null @@ -1,302 +0,0 @@ ---- -summary: "Matrix support status, capabilities, and configuration" -read_when: - - Working on Matrix channel features -title: "Matrix" ---- - -# Matrix (plugin) - -Matrix is an open, decentralized messaging protocol. OpenClaw connects as a Matrix **user** -on any homeserver, so you need a Matrix account for the bot. Once it is logged in, you can DM -the bot directly or invite it to rooms (Matrix "groups"). Beeper is a valid client option too, -but it requires E2EE to be enabled. - -Status: supported via plugin (@vector-im/matrix-bot-sdk). Direct messages, rooms, threads, media, reactions, -polls (send + poll-start as text), location, and E2EE (with crypto support). - -## Plugin required - -Matrix ships as a plugin and is not bundled with the core install. - -Install via CLI (npm registry): - -```bash -openclaw plugins install @openclaw/matrix -``` - -Local checkout (when running from a git repo): - -```bash -openclaw plugins install ./extensions/matrix -``` - -If you choose Matrix during configure/onboarding and a git checkout is detected, -OpenClaw will offer the local install path automatically. - -Details: [Plugins](/tools/plugin) - -## Setup - -1. Install the Matrix plugin: - - From npm: `openclaw plugins install @openclaw/matrix` - - From a local checkout: `openclaw plugins install ./extensions/matrix` -2. Create a Matrix account on a homeserver: - - Browse hosting options at [https://matrix.org/ecosystem/hosting/](https://matrix.org/ecosystem/hosting/) - - Or host it yourself. -3. Get an access token for the bot account: - - Use the Matrix login API with `curl` at your home server: - - ```bash - curl --request POST \ - --url https://matrix.example.org/_matrix/client/v3/login \ - --header 'Content-Type: application/json' \ - --data '{ - "type": "m.login.password", - "identifier": { - "type": "m.id.user", - "user": "your-user-name" - }, - "password": "your-password" - }' - ``` - - - Replace `matrix.example.org` with your homeserver URL. - - Or set `channels.matrix.userId` + `channels.matrix.password`: OpenClaw calls the same - login endpoint, stores the access token in `~/.openclaw/credentials/matrix/credentials.json`, - and reuses it on next start. - -4. Configure credentials: - - Env: `MATRIX_HOMESERVER`, `MATRIX_ACCESS_TOKEN` (or `MATRIX_USER_ID` + `MATRIX_PASSWORD`) - - Or config: `channels.matrix.*` - - If both are set, config takes precedence. - - With access token: user ID is fetched automatically via `/whoami`. - - When set, `channels.matrix.userId` should be the full Matrix ID (example: `@bot:example.org`). -5. Restart the gateway (or finish onboarding). -6. Start a DM with the bot or invite it to a room from any Matrix client - (Element, Beeper, etc.; see [https://matrix.org/ecosystem/clients/](https://matrix.org/ecosystem/clients/)). Beeper requires E2EE, - so set `channels.matrix.encryption: true` and verify the device. - -Minimal config (access token, user ID auto-fetched): - -```json5 -{ - channels: { - matrix: { - enabled: true, - homeserver: "https://matrix.example.org", - accessToken: "syt_***", - dm: { policy: "pairing" }, - }, - }, -} -``` - -E2EE config (end to end encryption enabled): - -```json5 -{ - channels: { - matrix: { - enabled: true, - homeserver: "https://matrix.example.org", - accessToken: "syt_***", - encryption: true, - dm: { policy: "pairing" }, - }, - }, -} -``` - -## Encryption (E2EE) - -End-to-end encryption is **supported** via the Rust crypto SDK. - -Enable with `channels.matrix.encryption: true`: - -- If the crypto module loads, encrypted rooms are decrypted automatically. -- Outbound media is encrypted when sending to encrypted rooms. -- On first connection, OpenClaw requests device verification from your other sessions. -- Verify the device in another Matrix client (Element, etc.) to enable key sharing. -- If the crypto module cannot be loaded, E2EE is disabled and encrypted rooms will not decrypt; - OpenClaw logs a warning. -- If you see missing crypto module errors (for example, `@matrix-org/matrix-sdk-crypto-nodejs-*`), - allow build scripts for `@matrix-org/matrix-sdk-crypto-nodejs` and run - `pnpm rebuild @matrix-org/matrix-sdk-crypto-nodejs` or fetch the binary with - `node node_modules/@matrix-org/matrix-sdk-crypto-nodejs/download-lib.js`. - -Crypto state is stored per account + access token in -`~/.openclaw/matrix/accounts//__//crypto/` -(SQLite database). Sync state lives alongside it in `bot-storage.json`. -If the access token (device) changes, a new store is created and the bot must be -re-verified for encrypted rooms. - -**Device verification:** -When E2EE is enabled, the bot will request verification from your other sessions on startup. -Open Element (or another client) and approve the verification request to establish trust. -Once verified, the bot can decrypt messages in encrypted rooms. - -## Multi-account - -Multi-account support: use `channels.matrix.accounts` with per-account credentials and optional `name`. See [`gateway/configuration`](/gateway/configuration#telegramaccounts--discordaccounts--slackaccounts--signalaccounts--imessageaccounts) for the shared pattern. - -Each account runs as a separate Matrix user on any homeserver. Per-account config -inherits from the top-level `channels.matrix` settings and can override any option -(DM policy, groups, encryption, etc.). - -```json5 -{ - channels: { - matrix: { - enabled: true, - dm: { policy: "pairing" }, - accounts: { - assistant: { - name: "Main assistant", - homeserver: "https://matrix.example.org", - accessToken: "syt_assistant_***", - encryption: true, - }, - alerts: { - name: "Alerts bot", - homeserver: "https://matrix.example.org", - accessToken: "syt_alerts_***", - dm: { policy: "allowlist", allowFrom: ["@admin:example.org"] }, - }, - }, - }, - }, -} -``` - -Notes: - -- Account startup is serialized to avoid race conditions with concurrent module imports. -- Env variables (`MATRIX_HOMESERVER`, `MATRIX_ACCESS_TOKEN`, etc.) only apply to the **default** account. -- Base channel settings (DM policy, group policy, mention gating, etc.) apply to all accounts unless overridden per account. -- Use `bindings[].match.accountId` to route each account to a different agent. -- Crypto state is stored per account + access token (separate key stores per account). - -## Routing model - -- Replies always go back to Matrix. -- DMs share the agent's main session; rooms map to group sessions. - -## Access control (DMs) - -- Default: `channels.matrix.dm.policy = "pairing"`. Unknown senders get a pairing code. -- Approve via: - - `openclaw pairing list matrix` - - `openclaw pairing approve matrix ` -- Public DMs: `channels.matrix.dm.policy="open"` plus `channels.matrix.dm.allowFrom=["*"]`. -- `channels.matrix.dm.allowFrom` accepts full Matrix user IDs (example: `@user:server`). The wizard resolves display names to user IDs when directory search finds a single exact match. -- Do not use display names or bare localparts (example: `"Alice"` or `"alice"`). They are ambiguous and are ignored for allowlist matching. Use full `@user:server` IDs. - -## Rooms (groups) - -- Default: `channels.matrix.groupPolicy = "allowlist"` (mention-gated). Use `channels.defaults.groupPolicy` to override the default when unset. -- Allowlist rooms with `channels.matrix.groups` (room IDs or aliases; names are resolved to IDs when directory search finds a single exact match): - -```json5 -{ - channels: { - matrix: { - groupPolicy: "allowlist", - groups: { - "!roomId:example.org": { allow: true }, - "#alias:example.org": { allow: true }, - }, - groupAllowFrom: ["@owner:example.org"], - }, - }, -} -``` - -- `requireMention: false` enables auto-reply in that room. -- `groups."*"` can set defaults for mention gating across rooms. -- `groupAllowFrom` restricts which senders can trigger the bot in rooms (full Matrix user IDs). -- Per-room `users` allowlists can further restrict senders inside a specific room (use full Matrix user IDs). -- The configure wizard prompts for room allowlists (room IDs, aliases, or names) and resolves names only on an exact, unique match. -- On startup, OpenClaw resolves room/user names in allowlists to IDs and logs the mapping; unresolved entries are ignored for allowlist matching. -- Invites are auto-joined by default; control with `channels.matrix.autoJoin` and `channels.matrix.autoJoinAllowlist`. -- To allow **no rooms**, set `channels.matrix.groupPolicy: "disabled"` (or keep an empty allowlist). -- Legacy key: `channels.matrix.rooms` (same shape as `groups`). - -## Threads - -- Reply threading is supported. -- `channels.matrix.threadReplies` controls whether replies stay in threads: - - `off`, `inbound` (default), `always` -- `channels.matrix.replyToMode` controls reply-to metadata when not replying in a thread: - - `off` (default), `first`, `all` - -## Capabilities - -| Feature | Status | -| --------------- | ------------------------------------------------------------------------------------- | -| Direct messages | ✅ Supported | -| Rooms | ✅ Supported | -| Threads | ✅ Supported | -| Media | ✅ Supported | -| E2EE | ✅ Supported (crypto module required) | -| Reactions | ✅ Supported (send/read via tools) | -| Polls | ✅ Send supported; inbound poll starts are converted to text (responses/ends ignored) | -| Location | ✅ Supported (geo URI; altitude ignored) | -| Native commands | ✅ Supported | - -## Troubleshooting - -Run this ladder first: - -```bash -openclaw status -openclaw gateway status -openclaw logs --follow -openclaw doctor -openclaw channels status --probe -``` - -Then confirm DM pairing state if needed: - -```bash -openclaw pairing list matrix -``` - -Common failures: - -- Logged in but room messages ignored: room blocked by `groupPolicy` or room allowlist. -- DMs ignored: sender pending approval when `channels.matrix.dm.policy="pairing"`. -- Encrypted rooms fail: crypto support or encryption settings mismatch. - -For triage flow: [/channels/troubleshooting](/channels/troubleshooting). - -## Configuration reference (Matrix) - -Full configuration: [Configuration](/gateway/configuration) - -Provider options: - -- `channels.matrix.enabled`: enable/disable channel startup. -- `channels.matrix.homeserver`: homeserver URL. -- `channels.matrix.userId`: Matrix user ID (optional with access token). -- `channels.matrix.accessToken`: access token. -- `channels.matrix.password`: password for login (token stored). -- `channels.matrix.deviceName`: device display name. -- `channels.matrix.encryption`: enable E2EE (default: false). -- `channels.matrix.initialSyncLimit`: initial sync limit. -- `channels.matrix.threadReplies`: `off | inbound | always` (default: inbound). -- `channels.matrix.textChunkLimit`: outbound text chunk size (chars). -- `channels.matrix.chunkMode`: `length` (default) or `newline` to split on blank lines (paragraph boundaries) before length chunking. -- `channels.matrix.dm.policy`: `pairing | allowlist | open | disabled` (default: pairing). -- `channels.matrix.dm.allowFrom`: DM allowlist (full Matrix user IDs). `open` requires `"*"`. The wizard resolves names to IDs when possible. -- `channels.matrix.groupPolicy`: `allowlist | open | disabled` (default: allowlist). -- `channels.matrix.groupAllowFrom`: allowlisted senders for group messages (full Matrix user IDs). -- `channels.matrix.allowlistOnly`: force allowlist rules for DMs + rooms. -- `channels.matrix.groups`: group allowlist + per-room settings map. -- `channels.matrix.rooms`: legacy group allowlist/config. -- `channels.matrix.replyToMode`: reply-to mode for threads/tags. -- `channels.matrix.mediaMaxMb`: inbound/outbound media cap (MB). -- `channels.matrix.autoJoin`: invite handling (`always | allowlist | off`, default: always). -- `channels.matrix.autoJoinAllowlist`: allowed room IDs/aliases for auto-join. -- `channels.matrix.accounts`: multi-account configuration keyed by account ID (each account inherits top-level settings). -- `channels.matrix.actions`: per-action tool gating (reactions/messages/pins/memberInfo/channelInfo). diff --git a/docs/channels/mattermost.md b/docs/channels/mattermost.md deleted file mode 100644 index fa0d9393e0..0000000000 --- a/docs/channels/mattermost.md +++ /dev/null @@ -1,158 +0,0 @@ ---- -summary: "Mattermost bot setup and OpenClaw config" -read_when: - - Setting up Mattermost - - Debugging Mattermost routing -title: "Mattermost" ---- - -# Mattermost (plugin) - -Status: supported via plugin (bot token + WebSocket events). Channels, groups, and DMs are supported. -Mattermost is a self-hostable team messaging platform; see the official site at -[mattermost.com](https://mattermost.com) for product details and downloads. - -## Plugin required - -Mattermost ships as a plugin and is not bundled with the core install. - -Install via CLI (npm registry): - -```bash -openclaw plugins install @openclaw/mattermost -``` - -Local checkout (when running from a git repo): - -```bash -openclaw plugins install ./extensions/mattermost -``` - -If you choose Mattermost during configure/onboarding and a git checkout is detected, -OpenClaw will offer the local install path automatically. - -Details: [Plugins](/tools/plugin) - -## Quick setup - -1. Install the Mattermost plugin. -2. Create a Mattermost bot account and copy the **bot token**. -3. Copy the Mattermost **base URL** (e.g., `https://chat.example.com`). -4. Configure OpenClaw and start the gateway. - -Minimal config: - -```json5 -{ - channels: { - mattermost: { - enabled: true, - botToken: "mm-token", - baseUrl: "https://chat.example.com", - dmPolicy: "pairing", - }, - }, -} -``` - -## Environment variables (default account) - -Set these on the gateway host if you prefer env vars: - -- `MATTERMOST_BOT_TOKEN=...` -- `MATTERMOST_URL=https://chat.example.com` - -Env vars apply only to the **default** account (`default`). Other accounts must use config values. - -## Chat modes - -Mattermost responds to DMs automatically. Channel behavior is controlled by `chatmode`: - -- `oncall` (default): respond only when @mentioned in channels. -- `onmessage`: respond to every channel message. -- `onchar`: respond when a message starts with a trigger prefix. - -Config example: - -```json5 -{ - channels: { - mattermost: { - chatmode: "onchar", - oncharPrefixes: [">", "!"], - }, - }, -} -``` - -Notes: - -- `onchar` still responds to explicit @mentions. -- `channels.mattermost.requireMention` is honored for legacy configs but `chatmode` is preferred. - -## Access control (DMs) - -- Default: `channels.mattermost.dmPolicy = "pairing"` (unknown senders get a pairing code). -- Approve via: - - `openclaw pairing list mattermost` - - `openclaw pairing approve mattermost ` -- Public DMs: `channels.mattermost.dmPolicy="open"` plus `channels.mattermost.allowFrom=["*"]`. - -## Channels (groups) - -- Default: `channels.mattermost.groupPolicy = "allowlist"` (mention-gated). -- Allowlist senders with `channels.mattermost.groupAllowFrom` (user IDs or `@username`). -- Open channels: `channels.mattermost.groupPolicy="open"` (mention-gated). - -## Targets for outbound delivery - -Use these target formats with `openclaw message send` or cron/webhooks: - -- `channel:` for a channel -- `user:` for a DM -- `@username` for a DM (resolved via the Mattermost API) - -Bare IDs are treated as channels. - -## Reactions (message tool) - -- Use `message action=react` with `channel=mattermost`. -- `messageId` is the Mattermost post id. -- `emoji` accepts names like `thumbsup` or `:+1:` (colons are optional). -- Set `remove=true` (boolean) to remove a reaction. -- Reaction add/remove events are forwarded as system events to the routed agent session. - -Examples: - -``` -message action=react channel=mattermost target=channel: messageId= emoji=thumbsup -message action=react channel=mattermost target=channel: messageId= emoji=thumbsup remove=true -``` - -Config: - -- `channels.mattermost.actions.reactions`: enable/disable reaction actions (default true). -- Per-account override: `channels.mattermost.accounts..actions.reactions`. - -## Multi-account - -Mattermost supports multiple accounts under `channels.mattermost.accounts`: - -```json5 -{ - channels: { - mattermost: { - accounts: { - default: { name: "Primary", botToken: "mm-token", baseUrl: "https://chat.example.com" }, - alerts: { name: "Alerts", botToken: "mm-token-2", baseUrl: "https://alerts.example.com" }, - }, - }, - }, -} -``` - -## Troubleshooting - -- No replies in channels: ensure the bot is in the channel and mention it (oncall), use a trigger prefix (onchar), or set `chatmode: "onmessage"`. -- Auth errors: check the bot token, base URL, and whether the account is enabled. -- Multi-account issues: env vars only apply to the `default` account. diff --git a/docs/channels/msteams.md b/docs/channels/msteams.md deleted file mode 100644 index 2232582610..0000000000 --- a/docs/channels/msteams.md +++ /dev/null @@ -1,771 +0,0 @@ ---- -summary: "Microsoft Teams bot support status, capabilities, and configuration" -read_when: - - Working on MS Teams channel features -title: "Microsoft Teams" ---- - -# Microsoft Teams (plugin) - -> "Abandon all hope, ye who enter here." - -Updated: 2026-01-21 - -Status: text + DM attachments are supported; channel/group file sending requires `sharePointSiteId` + Graph permissions (see [Sending files in group chats](#sending-files-in-group-chats)). Polls are sent via Adaptive Cards. - -## Plugin required - -Microsoft Teams ships as a plugin and is not bundled with the core install. - -**Breaking change (2026.1.15):** MS Teams moved out of core. If you use it, you must install the plugin. - -Explainable: keeps core installs lighter and lets MS Teams dependencies update independently. - -Install via CLI (npm registry): - -```bash -openclaw plugins install @openclaw/msteams -``` - -Local checkout (when running from a git repo): - -```bash -openclaw plugins install ./extensions/msteams -``` - -If you choose Teams during configure/onboarding and a git checkout is detected, -OpenClaw will offer the local install path automatically. - -Details: [Plugins](/tools/plugin) - -## Quick setup (beginner) - -1. Install the Microsoft Teams plugin. -2. Create an **Azure Bot** (App ID + client secret + tenant ID). -3. Configure OpenClaw with those credentials. -4. Expose `/api/messages` (port 3978 by default) via a public URL or tunnel. -5. Install the Teams app package and start the gateway. - -Minimal config: - -```json5 -{ - channels: { - msteams: { - enabled: true, - appId: "", - appPassword: "", - tenantId: "", - webhook: { port: 3978, path: "/api/messages" }, - }, - }, -} -``` - -Note: group chats are blocked by default (`channels.msteams.groupPolicy: "allowlist"`). To allow group replies, set `channels.msteams.groupAllowFrom` (or use `groupPolicy: "open"` to allow any member, mention-gated). - -## Goals - -- Talk to OpenClaw via Teams DMs, group chats, or channels. -- Keep routing deterministic: replies always go back to the channel they arrived on. -- Default to safe channel behavior (mentions required unless configured otherwise). - -## Config writes - -By default, Microsoft Teams is allowed to write config updates triggered by `/config set|unset` (requires `commands.config: true`). - -Disable with: - -```json5 -{ - channels: { msteams: { configWrites: false } }, -} -``` - -## Access control (DMs + groups) - -**DM access** - -- Default: `channels.msteams.dmPolicy = "pairing"`. Unknown senders are ignored until approved. -- `channels.msteams.allowFrom` accepts AAD object IDs, UPNs, or display names. The wizard resolves names to IDs via Microsoft Graph when credentials allow. - -**Group access** - -- Default: `channels.msteams.groupPolicy = "allowlist"` (blocked unless you add `groupAllowFrom`). Use `channels.defaults.groupPolicy` to override the default when unset. -- `channels.msteams.groupAllowFrom` controls which senders can trigger in group chats/channels (falls back to `channels.msteams.allowFrom`). -- Set `groupPolicy: "open"` to allow any member (still mention‑gated by default). -- To allow **no channels**, set `channels.msteams.groupPolicy: "disabled"`. - -Example: - -```json5 -{ - channels: { - msteams: { - groupPolicy: "allowlist", - groupAllowFrom: ["user@org.com"], - }, - }, -} -``` - -**Teams + channel allowlist** - -- Scope group/channel replies by listing teams and channels under `channels.msteams.teams`. -- Keys can be team IDs or names; channel keys can be conversation IDs or names. -- When `groupPolicy="allowlist"` and a teams allowlist is present, only listed teams/channels are accepted (mention‑gated). -- The configure wizard accepts `Team/Channel` entries and stores them for you. -- On startup, OpenClaw resolves team/channel and user allowlist names to IDs (when Graph permissions allow) - and logs the mapping; unresolved entries are kept as typed. - -Example: - -```json5 -{ - channels: { - msteams: { - groupPolicy: "allowlist", - teams: { - "My Team": { - channels: { - General: { requireMention: true }, - }, - }, - }, - }, - }, -} -``` - -## How it works - -1. Install the Microsoft Teams plugin. -2. Create an **Azure Bot** (App ID + secret + tenant ID). -3. Build a **Teams app package** that references the bot and includes the RSC permissions below. -4. Upload/install the Teams app into a team (or personal scope for DMs). -5. Configure `msteams` in `~/.openclaw/openclaw.json` (or env vars) and start the gateway. -6. The gateway listens for Bot Framework webhook traffic on `/api/messages` by default. - -## Azure Bot Setup (Prerequisites) - -Before configuring OpenClaw, you need to create an Azure Bot resource. - -### Step 1: Create Azure Bot - -1. Go to [Create Azure Bot](https://portal.azure.com/#create/Microsoft.AzureBot) -2. Fill in the **Basics** tab: - - | Field | Value | - | ------------------ | -------------------------------------------------------- | - | **Bot handle** | Your bot name, e.g., `openclaw-msteams` (must be unique) | - | **Subscription** | Select your Azure subscription | - | **Resource group** | Create new or use existing | - | **Pricing tier** | **Free** for dev/testing | - | **Type of App** | **Single Tenant** (recommended - see note below) | - | **Creation type** | **Create new Microsoft App ID** | - -> **Deprecation notice:** Creation of new multi-tenant bots was deprecated after 2025-07-31. Use **Single Tenant** for new bots. - -3. Click **Review + create** → **Create** (wait ~1-2 minutes) - -### Step 2: Get Credentials - -1. Go to your Azure Bot resource → **Configuration** -2. Copy **Microsoft App ID** → this is your `appId` -3. Click **Manage Password** → go to the App Registration -4. Under **Certificates & secrets** → **New client secret** → copy the **Value** → this is your `appPassword` -5. Go to **Overview** → copy **Directory (tenant) ID** → this is your `tenantId` - -### Step 3: Configure Messaging Endpoint - -1. In Azure Bot → **Configuration** -2. Set **Messaging endpoint** to your webhook URL: - - Production: `https://your-domain.com/api/messages` - - Local dev: Use a tunnel (see [Local Development](#local-development-tunneling) below) - -### Step 4: Enable Teams Channel - -1. In Azure Bot → **Channels** -2. Click **Microsoft Teams** → Configure → Save -3. Accept the Terms of Service - -## Local Development (Tunneling) - -Teams can't reach `localhost`. Use a tunnel for local development: - -**Option A: ngrok** - -```bash -ngrok http 3978 -# Copy the https URL, e.g., https://abc123.ngrok.io -# Set messaging endpoint to: https://abc123.ngrok.io/api/messages -``` - -**Option B: Tailscale Funnel** - -```bash -tailscale funnel 3978 -# Use your Tailscale funnel URL as the messaging endpoint -``` - -## Teams Developer Portal (Alternative) - -Instead of manually creating a manifest ZIP, you can use the [Teams Developer Portal](https://dev.teams.microsoft.com/apps): - -1. Click **+ New app** -2. Fill in basic info (name, description, developer info) -3. Go to **App features** → **Bot** -4. Select **Enter a bot ID manually** and paste your Azure Bot App ID -5. Check scopes: **Personal**, **Team**, **Group Chat** -6. Click **Distribute** → **Download app package** -7. In Teams: **Apps** → **Manage your apps** → **Upload a custom app** → select the ZIP - -This is often easier than hand-editing JSON manifests. - -## Testing the Bot - -**Option A: Azure Web Chat (verify webhook first)** - -1. In Azure Portal → your Azure Bot resource → **Test in Web Chat** -2. Send a message - you should see a response -3. This confirms your webhook endpoint works before Teams setup - -**Option B: Teams (after app installation)** - -1. Install the Teams app (sideload or org catalog) -2. Find the bot in Teams and send a DM -3. Check gateway logs for incoming activity - -## Setup (minimal text-only) - -1. **Install the Microsoft Teams plugin** - - From npm: `openclaw plugins install @openclaw/msteams` - - From a local checkout: `openclaw plugins install ./extensions/msteams` - -2. **Bot registration** - - Create an Azure Bot (see above) and note: - - App ID - - Client secret (App password) - - Tenant ID (single-tenant) - -3. **Teams app manifest** - - Include a `bot` entry with `botId = `. - - Scopes: `personal`, `team`, `groupChat`. - - `supportsFiles: true` (required for personal scope file handling). - - Add RSC permissions (below). - - Create icons: `outline.png` (32x32) and `color.png` (192x192). - - Zip all three files together: `manifest.json`, `outline.png`, `color.png`. - -4. **Configure OpenClaw** - - ```json - { - "msteams": { - "enabled": true, - "appId": "", - "appPassword": "", - "tenantId": "", - "webhook": { "port": 3978, "path": "/api/messages" } - } - } - ``` - - You can also use environment variables instead of config keys: - - `MSTEAMS_APP_ID` - - `MSTEAMS_APP_PASSWORD` - - `MSTEAMS_TENANT_ID` - -5. **Bot endpoint** - - Set the Azure Bot Messaging Endpoint to: - - `https://:3978/api/messages` (or your chosen path/port). - -6. **Run the gateway** - - The Teams channel starts automatically when the plugin is installed and `msteams` config exists with credentials. - -## History context - -- `channels.msteams.historyLimit` controls how many recent channel/group messages are wrapped into the prompt. -- Falls back to `messages.groupChat.historyLimit`. Set `0` to disable (default 50). -- DM history can be limited with `channels.msteams.dmHistoryLimit` (user turns). Per-user overrides: `channels.msteams.dms[""].historyLimit`. - -## Current Teams RSC Permissions (Manifest) - -These are the **existing resourceSpecific permissions** in our Teams app manifest. They only apply inside the team/chat where the app is installed. - -**For channels (team scope):** - -- `ChannelMessage.Read.Group` (Application) - receive all channel messages without @mention -- `ChannelMessage.Send.Group` (Application) -- `Member.Read.Group` (Application) -- `Owner.Read.Group` (Application) -- `ChannelSettings.Read.Group` (Application) -- `TeamMember.Read.Group` (Application) -- `TeamSettings.Read.Group` (Application) - -**For group chats:** - -- `ChatMessage.Read.Chat` (Application) - receive all group chat messages without @mention - -## Example Teams Manifest (redacted) - -Minimal, valid example with the required fields. Replace IDs and URLs. - -```json -{ - "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.23/MicrosoftTeams.schema.json", - "manifestVersion": "1.23", - "version": "1.0.0", - "id": "00000000-0000-0000-0000-000000000000", - "name": { "short": "OpenClaw" }, - "developer": { - "name": "Your Org", - "websiteUrl": "https://example.com", - "privacyUrl": "https://example.com/privacy", - "termsOfUseUrl": "https://example.com/terms" - }, - "description": { "short": "OpenClaw in Teams", "full": "OpenClaw in Teams" }, - "icons": { "outline": "outline.png", "color": "color.png" }, - "accentColor": "#5B6DEF", - "bots": [ - { - "botId": "11111111-1111-1111-1111-111111111111", - "scopes": ["personal", "team", "groupChat"], - "isNotificationOnly": false, - "supportsCalling": false, - "supportsVideo": false, - "supportsFiles": true - } - ], - "webApplicationInfo": { - "id": "11111111-1111-1111-1111-111111111111" - }, - "authorization": { - "permissions": { - "resourceSpecific": [ - { "name": "ChannelMessage.Read.Group", "type": "Application" }, - { "name": "ChannelMessage.Send.Group", "type": "Application" }, - { "name": "Member.Read.Group", "type": "Application" }, - { "name": "Owner.Read.Group", "type": "Application" }, - { "name": "ChannelSettings.Read.Group", "type": "Application" }, - { "name": "TeamMember.Read.Group", "type": "Application" }, - { "name": "TeamSettings.Read.Group", "type": "Application" }, - { "name": "ChatMessage.Read.Chat", "type": "Application" } - ] - } - } -} -``` - -### Manifest caveats (must-have fields) - -- `bots[].botId` **must** match the Azure Bot App ID. -- `webApplicationInfo.id` **must** match the Azure Bot App ID. -- `bots[].scopes` must include the surfaces you plan to use (`personal`, `team`, `groupChat`). -- `bots[].supportsFiles: true` is required for file handling in personal scope. -- `authorization.permissions.resourceSpecific` must include channel read/send if you want channel traffic. - -### Updating an existing app - -To update an already-installed Teams app (e.g., to add RSC permissions): - -1. Update your `manifest.json` with the new settings -2. **Increment the `version` field** (e.g., `1.0.0` → `1.1.0`) -3. **Re-zip** the manifest with icons (`manifest.json`, `outline.png`, `color.png`) -4. Upload the new zip: - - **Option A (Teams Admin Center):** Teams Admin Center → Teams apps → Manage apps → find your app → Upload new version - - **Option B (Sideload):** In Teams → Apps → Manage your apps → Upload a custom app -5. **For team channels:** Reinstall the app in each team for new permissions to take effect -6. **Fully quit and relaunch Teams** (not just close the window) to clear cached app metadata - -## Capabilities: RSC only vs Graph - -### With **Teams RSC only** (app installed, no Graph API permissions) - -Works: - -- Read channel message **text** content. -- Send channel message **text** content. -- Receive **personal (DM)** file attachments. - -Does NOT work: - -- Channel/group **image or file contents** (payload only includes HTML stub). -- Downloading attachments stored in SharePoint/OneDrive. -- Reading message history (beyond the live webhook event). - -### With **Teams RSC + Microsoft Graph Application permissions** - -Adds: - -- Downloading hosted contents (images pasted into messages). -- Downloading file attachments stored in SharePoint/OneDrive. -- Reading channel/chat message history via Graph. - -### RSC vs Graph API - -| Capability | RSC Permissions | Graph API | -| ----------------------- | -------------------- | ----------------------------------- | -| **Real-time messages** | Yes (via webhook) | No (polling only) | -| **Historical messages** | No | Yes (can query history) | -| **Setup complexity** | App manifest only | Requires admin consent + token flow | -| **Works offline** | No (must be running) | Yes (query anytime) | - -**Bottom line:** RSC is for real-time listening; Graph API is for historical access. For catching up on missed messages while offline, you need Graph API with `ChannelMessage.Read.All` (requires admin consent). - -## Graph-enabled media + history (required for channels) - -If you need images/files in **channels** or want to fetch **message history**, you must enable Microsoft Graph permissions and grant admin consent. - -1. In Entra ID (Azure AD) **App Registration**, add Microsoft Graph **Application permissions**: - - `ChannelMessage.Read.All` (channel attachments + history) - - `Chat.Read.All` or `ChatMessage.Read.All` (group chats) -2. **Grant admin consent** for the tenant. -3. Bump the Teams app **manifest version**, re-upload, and **reinstall the app in Teams**. -4. **Fully quit and relaunch Teams** to clear cached app metadata. - -**Additional permission for user mentions:** User @mentions work out of the box for users in the conversation. However, if you want to dynamically search and mention users who are **not in the current conversation**, add `User.Read.All` (Application) permission and grant admin consent. - -## Known Limitations - -### Webhook timeouts - -Teams delivers messages via HTTP webhook. If processing takes too long (e.g., slow LLM responses), you may see: - -- Gateway timeouts -- Teams retrying the message (causing duplicates) -- Dropped replies - -OpenClaw handles this by returning quickly and sending replies proactively, but very slow responses may still cause issues. - -### Formatting - -Teams markdown is more limited than Slack or Discord: - -- Basic formatting works: **bold**, _italic_, `code`, links -- Complex markdown (tables, nested lists) may not render correctly -- Adaptive Cards are supported for polls and arbitrary card sends (see below) - -## Configuration - -Key settings (see `/gateway/configuration` for shared channel patterns): - -- `channels.msteams.enabled`: enable/disable the channel. -- `channels.msteams.appId`, `channels.msteams.appPassword`, `channels.msteams.tenantId`: bot credentials. -- `channels.msteams.webhook.port` (default `3978`) -- `channels.msteams.webhook.path` (default `/api/messages`) -- `channels.msteams.dmPolicy`: `pairing | allowlist | open | disabled` (default: pairing) -- `channels.msteams.allowFrom`: allowlist for DMs (AAD object IDs, UPNs, or display names). The wizard resolves names to IDs during setup when Graph access is available. -- `channels.msteams.textChunkLimit`: outbound text chunk size. -- `channels.msteams.chunkMode`: `length` (default) or `newline` to split on blank lines (paragraph boundaries) before length chunking. -- `channels.msteams.mediaAllowHosts`: allowlist for inbound attachment hosts (defaults to Microsoft/Teams domains). -- `channels.msteams.mediaAuthAllowHosts`: allowlist for attaching Authorization headers on media retries (defaults to Graph + Bot Framework hosts). -- `channels.msteams.requireMention`: require @mention in channels/groups (default true). -- `channels.msteams.replyStyle`: `thread | top-level` (see [Reply Style](#reply-style-threads-vs-posts)). -- `channels.msteams.teams..replyStyle`: per-team override. -- `channels.msteams.teams..requireMention`: per-team override. -- `channels.msteams.teams..tools`: default per-team tool policy overrides (`allow`/`deny`/`alsoAllow`) used when a channel override is missing. -- `channels.msteams.teams..toolsBySender`: default per-team per-sender tool policy overrides (`"*"` wildcard supported). -- `channels.msteams.teams..channels..replyStyle`: per-channel override. -- `channels.msteams.teams..channels..requireMention`: per-channel override. -- `channels.msteams.teams..channels..tools`: per-channel tool policy overrides (`allow`/`deny`/`alsoAllow`). -- `channels.msteams.teams..channels..toolsBySender`: per-channel per-sender tool policy overrides (`"*"` wildcard supported). -- `channels.msteams.sharePointSiteId`: SharePoint site ID for file uploads in group chats/channels (see [Sending files in group chats](#sending-files-in-group-chats)). - -## Routing & Sessions - -- Session keys follow the standard agent format (see [/concepts/session](/concepts/session)): - - Direct messages share the main session (`agent::`). - - Channel/group messages use conversation id: - - `agent::msteams:channel:` - - `agent::msteams:group:` - -## Reply Style: Threads vs Posts - -Teams recently introduced two channel UI styles over the same underlying data model: - -| Style | Description | Recommended `replyStyle` | -| ------------------------ | --------------------------------------------------------- | ------------------------ | -| **Posts** (classic) | Messages appear as cards with threaded replies underneath | `thread` (default) | -| **Threads** (Slack-like) | Messages flow linearly, more like Slack | `top-level` | - -**The problem:** The Teams API does not expose which UI style a channel uses. If you use the wrong `replyStyle`: - -- `thread` in a Threads-style channel → replies appear nested awkwardly -- `top-level` in a Posts-style channel → replies appear as separate top-level posts instead of in-thread - -**Solution:** Configure `replyStyle` per-channel based on how the channel is set up: - -```json -{ - "msteams": { - "replyStyle": "thread", - "teams": { - "19:abc...@thread.tacv2": { - "channels": { - "19:xyz...@thread.tacv2": { - "replyStyle": "top-level" - } - } - } - } - } -} -``` - -## Attachments & Images - -**Current limitations:** - -- **DMs:** Images and file attachments work via Teams bot file APIs. -- **Channels/groups:** Attachments live in M365 storage (SharePoint/OneDrive). The webhook payload only includes an HTML stub, not the actual file bytes. **Graph API permissions are required** to download channel attachments. - -Without Graph permissions, channel messages with images will be received as text-only (the image content is not accessible to the bot). -By default, OpenClaw only downloads media from Microsoft/Teams hostnames. Override with `channels.msteams.mediaAllowHosts` (use `["*"]` to allow any host). -Authorization headers are only attached for hosts in `channels.msteams.mediaAuthAllowHosts` (defaults to Graph + Bot Framework hosts). Keep this list strict (avoid multi-tenant suffixes). - -## Sending files in group chats - -Bots can send files in DMs using the FileConsentCard flow (built-in). However, **sending files in group chats/channels** requires additional setup: - -| Context | How files are sent | Setup needed | -| ------------------------ | -------------------------------------------- | ----------------------------------------------- | -| **DMs** | FileConsentCard → user accepts → bot uploads | Works out of the box | -| **Group chats/channels** | Upload to SharePoint → share link | Requires `sharePointSiteId` + Graph permissions | -| **Images (any context)** | Base64-encoded inline | Works out of the box | - -### Why group chats need SharePoint - -Bots don't have a personal OneDrive drive (the `/me/drive` Graph API endpoint doesn't work for application identities). To send files in group chats/channels, the bot uploads to a **SharePoint site** and creates a sharing link. - -### Setup - -1. **Add Graph API permissions** in Entra ID (Azure AD) → App Registration: - - `Sites.ReadWrite.All` (Application) - upload files to SharePoint - - `Chat.Read.All` (Application) - optional, enables per-user sharing links - -2. **Grant admin consent** for the tenant. - -3. **Get your SharePoint site ID:** - - ```bash - # Via Graph Explorer or curl with a valid token: - curl -H "Authorization: Bearer $TOKEN" \ - "https://graph.microsoft.com/v1.0/sites/{hostname}:/{site-path}" - - # Example: for a site at "contoso.sharepoint.com/sites/BotFiles" - curl -H "Authorization: Bearer $TOKEN" \ - "https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com:/sites/BotFiles" - - # Response includes: "id": "contoso.sharepoint.com,guid1,guid2" - ``` - -4. **Configure OpenClaw:** - - ```json5 - { - channels: { - msteams: { - // ... other config ... - sharePointSiteId: "contoso.sharepoint.com,guid1,guid2", - }, - }, - } - ``` - -### Sharing behavior - -| Permission | Sharing behavior | -| --------------------------------------- | --------------------------------------------------------- | -| `Sites.ReadWrite.All` only | Organization-wide sharing link (anyone in org can access) | -| `Sites.ReadWrite.All` + `Chat.Read.All` | Per-user sharing link (only chat members can access) | - -Per-user sharing is more secure as only the chat participants can access the file. If `Chat.Read.All` permission is missing, the bot falls back to organization-wide sharing. - -### Fallback behavior - -| Scenario | Result | -| ------------------------------------------------- | -------------------------------------------------- | -| Group chat + file + `sharePointSiteId` configured | Upload to SharePoint, send sharing link | -| Group chat + file + no `sharePointSiteId` | Attempt OneDrive upload (may fail), send text only | -| Personal chat + file | FileConsentCard flow (works without SharePoint) | -| Any context + image | Base64-encoded inline (works without SharePoint) | - -### Files stored location - -Uploaded files are stored in a `/OpenClawShared/` folder in the configured SharePoint site's default document library. - -## Polls (Adaptive Cards) - -OpenClaw sends Teams polls as Adaptive Cards (there is no native Teams poll API). - -- CLI: `openclaw message poll --channel msteams --target conversation: ...` -- Votes are recorded by the gateway in `~/.openclaw/msteams-polls.json`. -- The gateway must stay online to record votes. -- Polls do not auto-post result summaries yet (inspect the store file if needed). - -## Adaptive Cards (arbitrary) - -Send any Adaptive Card JSON to Teams users or conversations using the `message` tool or CLI. - -The `card` parameter accepts an Adaptive Card JSON object. When `card` is provided, the message text is optional. - -**Agent tool:** - -```json -{ - "action": "send", - "channel": "msteams", - "target": "user:", - "card": { - "type": "AdaptiveCard", - "version": "1.5", - "body": [{ "type": "TextBlock", "text": "Hello!" }] - } -} -``` - -**CLI:** - -```bash -openclaw message send --channel msteams \ - --target "conversation:19:abc...@thread.tacv2" \ - --card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello!"}]}' -``` - -See [Adaptive Cards documentation](https://adaptivecards.io/) for card schema and examples. For target format details, see [Target formats](#target-formats) below. - -## Target formats - -MSTeams targets use prefixes to distinguish between users and conversations: - -| Target type | Format | Example | -| ------------------- | -------------------------------- | --------------------------------------------------- | -| User (by ID) | `user:` | `user:40a1a0ed-4ff2-4164-a219-55518990c197` | -| User (by name) | `user:` | `user:John Smith` (requires Graph API) | -| Group/channel | `conversation:` | `conversation:19:abc123...@thread.tacv2` | -| Group/channel (raw) | `` | `19:abc123...@thread.tacv2` (if contains `@thread`) | - -**CLI examples:** - -```bash -# Send to a user by ID -openclaw message send --channel msteams --target "user:40a1a0ed-..." --message "Hello" - -# Send to a user by display name (triggers Graph API lookup) -openclaw message send --channel msteams --target "user:John Smith" --message "Hello" - -# Send to a group chat or channel -openclaw message send --channel msteams --target "conversation:19:abc...@thread.tacv2" --message "Hello" - -# Send an Adaptive Card to a conversation -openclaw message send --channel msteams --target "conversation:19:abc...@thread.tacv2" \ - --card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello"}]}' -``` - -**Agent tool examples:** - -```json -{ - "action": "send", - "channel": "msteams", - "target": "user:John Smith", - "message": "Hello!" -} -``` - -```json -{ - "action": "send", - "channel": "msteams", - "target": "conversation:19:abc...@thread.tacv2", - "card": { - "type": "AdaptiveCard", - "version": "1.5", - "body": [{ "type": "TextBlock", "text": "Hello" }] - } -} -``` - -Note: Without the `user:` prefix, names default to group/team resolution. Always use `user:` when targeting people by display name. - -## Proactive messaging - -- Proactive messages are only possible **after** a user has interacted, because we store conversation references at that point. -- See `/gateway/configuration` for `dmPolicy` and allowlist gating. - -## Team and Channel IDs (Common Gotcha) - -The `groupId` query parameter in Teams URLs is **NOT** the team ID used for configuration. Extract IDs from the URL path instead: - -**Team URL:** - -``` -https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=... - └────────────────────────────┘ - Team ID (URL-decode this) -``` - -**Channel URL:** - -``` -https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?groupId=... - └─────────────────────────┘ - Channel ID (URL-decode this) -``` - -**For config:** - -- Team ID = path segment after `/team/` (URL-decoded, e.g., `19:Bk4j...@thread.tacv2`) -- Channel ID = path segment after `/channel/` (URL-decoded) -- **Ignore** the `groupId` query parameter - -## Private Channels - -Bots have limited support in private channels: - -| Feature | Standard Channels | Private Channels | -| ---------------------------- | ----------------- | ---------------------- | -| Bot installation | Yes | Limited | -| Real-time messages (webhook) | Yes | May not work | -| RSC permissions | Yes | May behave differently | -| @mentions | Yes | If bot is accessible | -| Graph API history | Yes | Yes (with permissions) | - -**Workarounds if private channels don't work:** - -1. Use standard channels for bot interactions -2. Use DMs - users can always message the bot directly -3. Use Graph API for historical access (requires `ChannelMessage.Read.All`) - -## Troubleshooting - -### Common issues - -- **Images not showing in channels:** Graph permissions or admin consent missing. Reinstall the Teams app and fully quit/reopen Teams. -- **No responses in channel:** mentions are required by default; set `channels.msteams.requireMention=false` or configure per team/channel. -- **Version mismatch (Teams still shows old manifest):** remove + re-add the app and fully quit Teams to refresh. -- **401 Unauthorized from webhook:** Expected when testing manually without Azure JWT - means endpoint is reachable but auth failed. Use Azure Web Chat to test properly. - -### Manifest upload errors - -- **"Icon file cannot be empty":** The manifest references icon files that are 0 bytes. Create valid PNG icons (32x32 for `outline.png`, 192x192 for `color.png`). -- **"webApplicationInfo.Id already in use":** The app is still installed in another team/chat. Find and uninstall it first, or wait 5-10 minutes for propagation. -- **"Something went wrong" on upload:** Upload via [https://admin.teams.microsoft.com](https://admin.teams.microsoft.com) instead, open browser DevTools (F12) → Network tab, and check the response body for the actual error. -- **Sideload failing:** Try "Upload an app to your org's app catalog" instead of "Upload a custom app" - this often bypasses sideload restrictions. - -### RSC permissions not working - -1. Verify `webApplicationInfo.id` matches your bot's App ID exactly -2. Re-upload the app and reinstall in the team/chat -3. Check if your org admin has blocked RSC permissions -4. Confirm you're using the right scope: `ChannelMessage.Read.Group` for teams, `ChatMessage.Read.Chat` for group chats - -## References - -- [Create Azure Bot](https://learn.microsoft.com/en-us/azure/bot-service/bot-service-quickstart-registration) - Azure Bot setup guide -- [Teams Developer Portal](https://dev.teams.microsoft.com/apps) - create/manage Teams apps -- [Teams app manifest schema](https://learn.microsoft.com/en-us/microsoftteams/platform/resources/schema/manifest-schema) -- [Receive channel messages with RSC](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/channel-messages-with-rsc) -- [RSC permissions reference](https://learn.microsoft.com/en-us/microsoftteams/platform/graph-api/rsc/resource-specific-consent) -- [Teams bot file handling](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/bots-filesv4) (channel/group requires Graph) -- [Proactive messaging](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/send-proactive-messages) diff --git a/docs/channels/nextcloud-talk.md b/docs/channels/nextcloud-talk.md deleted file mode 100644 index d4ab9e2c39..0000000000 --- a/docs/channels/nextcloud-talk.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -summary: "Nextcloud Talk support status, capabilities, and configuration" -read_when: - - Working on Nextcloud Talk channel features -title: "Nextcloud Talk" ---- - -# Nextcloud Talk (plugin) - -Status: supported via plugin (webhook bot). Direct messages, rooms, reactions, and markdown messages are supported. - -## Plugin required - -Nextcloud Talk ships as a plugin and is not bundled with the core install. - -Install via CLI (npm registry): - -```bash -openclaw plugins install @openclaw/nextcloud-talk -``` - -Local checkout (when running from a git repo): - -```bash -openclaw plugins install ./extensions/nextcloud-talk -``` - -If you choose Nextcloud Talk during configure/onboarding and a git checkout is detected, -OpenClaw will offer the local install path automatically. - -Details: [Plugins](/tools/plugin) - -## Quick setup (beginner) - -1. Install the Nextcloud Talk plugin. -2. On your Nextcloud server, create a bot: - - ```bash - ./occ talk:bot:install "OpenClaw" "" "" --feature reaction - ``` - -3. Enable the bot in the target room settings. -4. Configure OpenClaw: - - Config: `channels.nextcloud-talk.baseUrl` + `channels.nextcloud-talk.botSecret` - - Or env: `NEXTCLOUD_TALK_BOT_SECRET` (default account only) -5. Restart the gateway (or finish onboarding). - -Minimal config: - -```json5 -{ - channels: { - "nextcloud-talk": { - enabled: true, - baseUrl: "https://cloud.example.com", - botSecret: "shared-secret", - dmPolicy: "pairing", - }, - }, -} -``` - -## Notes - -- Bots cannot initiate DMs. The user must message the bot first. -- Webhook URL must be reachable by the Gateway; set `webhookPublicUrl` if behind a proxy. -- Media uploads are not supported by the bot API; media is sent as URLs. -- The webhook payload does not distinguish DMs vs rooms; set `apiUser` + `apiPassword` to enable room-type lookups (otherwise DMs are treated as rooms). - -## Access control (DMs) - -- Default: `channels.nextcloud-talk.dmPolicy = "pairing"`. Unknown senders get a pairing code. -- Approve via: - - `openclaw pairing list nextcloud-talk` - - `openclaw pairing approve nextcloud-talk ` -- Public DMs: `channels.nextcloud-talk.dmPolicy="open"` plus `channels.nextcloud-talk.allowFrom=["*"]`. -- `allowFrom` matches Nextcloud user IDs only; display names are ignored. - -## Rooms (groups) - -- Default: `channels.nextcloud-talk.groupPolicy = "allowlist"` (mention-gated). -- Allowlist rooms with `channels.nextcloud-talk.rooms`: - -```json5 -{ - channels: { - "nextcloud-talk": { - rooms: { - "room-token": { requireMention: true }, - }, - }, - }, -} -``` - -- To allow no rooms, keep the allowlist empty or set `channels.nextcloud-talk.groupPolicy="disabled"`. - -## Capabilities - -| Feature | Status | -| --------------- | ------------- | -| Direct messages | Supported | -| Rooms | Supported | -| Threads | Not supported | -| Media | URL-only | -| Reactions | Supported | -| Native commands | Not supported | - -## Configuration reference (Nextcloud Talk) - -Full configuration: [Configuration](/gateway/configuration) - -Provider options: - -- `channels.nextcloud-talk.enabled`: enable/disable channel startup. -- `channels.nextcloud-talk.baseUrl`: Nextcloud instance URL. -- `channels.nextcloud-talk.botSecret`: bot shared secret. -- `channels.nextcloud-talk.botSecretFile`: secret file path. -- `channels.nextcloud-talk.apiUser`: API user for room lookups (DM detection). -- `channels.nextcloud-talk.apiPassword`: API/app password for room lookups. -- `channels.nextcloud-talk.apiPasswordFile`: API password file path. -- `channels.nextcloud-talk.webhookPort`: webhook listener port (default: 8788). -- `channels.nextcloud-talk.webhookHost`: webhook host (default: 0.0.0.0). -- `channels.nextcloud-talk.webhookPath`: webhook path (default: /nextcloud-talk-webhook). -- `channels.nextcloud-talk.webhookPublicUrl`: externally reachable webhook URL. -- `channels.nextcloud-talk.dmPolicy`: `pairing | allowlist | open | disabled`. -- `channels.nextcloud-talk.allowFrom`: DM allowlist (user IDs). `open` requires `"*"`. -- `channels.nextcloud-talk.groupPolicy`: `allowlist | open | disabled`. -- `channels.nextcloud-talk.groupAllowFrom`: group allowlist (user IDs). -- `channels.nextcloud-talk.rooms`: per-room settings and allowlist. -- `channels.nextcloud-talk.historyLimit`: group history limit (0 disables). -- `channels.nextcloud-talk.dmHistoryLimit`: DM history limit (0 disables). -- `channels.nextcloud-talk.dms`: per-DM overrides (historyLimit). -- `channels.nextcloud-talk.textChunkLimit`: outbound text chunk size (chars). -- `channels.nextcloud-talk.chunkMode`: `length` (default) or `newline` to split on blank lines (paragraph boundaries) before length chunking. -- `channels.nextcloud-talk.blockStreaming`: disable block streaming for this channel. -- `channels.nextcloud-talk.blockStreamingCoalesce`: block streaming coalesce tuning. -- `channels.nextcloud-talk.mediaMaxMb`: inbound media cap (MB). diff --git a/docs/channels/nostr.md b/docs/channels/nostr.md deleted file mode 100644 index 3368933d6c..0000000000 --- a/docs/channels/nostr.md +++ /dev/null @@ -1,233 +0,0 @@ ---- -summary: "Nostr DM channel via NIP-04 encrypted messages" -read_when: - - You want OpenClaw to receive DMs via Nostr - - You're setting up decentralized messaging -title: "Nostr" ---- - -# Nostr - -**Status:** Optional plugin (disabled by default). - -Nostr is a decentralized protocol for social networking. This channel enables OpenClaw to receive and respond to encrypted direct messages (DMs) via NIP-04. - -## Install (on demand) - -### Onboarding (recommended) - -- The onboarding wizard (`openclaw onboard`) and `openclaw channels add` list optional channel plugins. -- Selecting Nostr prompts you to install the plugin on demand. - -Install defaults: - -- **Dev channel + git checkout available:** uses the local plugin path. -- **Stable/Beta:** downloads from npm. - -You can always override the choice in the prompt. - -### Manual install - -```bash -openclaw plugins install @openclaw/nostr -``` - -Use a local checkout (dev workflows): - -```bash -openclaw plugins install --link /extensions/nostr -``` - -Restart the Gateway after installing or enabling plugins. - -## Quick setup - -1. Generate a Nostr keypair (if needed): - -```bash -# Using nak -nak key generate -``` - -2. Add to config: - -```json -{ - "channels": { - "nostr": { - "privateKey": "${NOSTR_PRIVATE_KEY}" - } - } -} -``` - -3. Export the key: - -```bash -export NOSTR_PRIVATE_KEY="nsec1..." -``` - -4. Restart the Gateway. - -## Configuration reference - -| Key | Type | Default | Description | -| ------------ | -------- | ------------------------------------------- | ----------------------------------- | -| `privateKey` | string | required | Private key in `nsec` or hex format | -| `relays` | string[] | `['wss://relay.damus.io', 'wss://nos.lol']` | Relay URLs (WebSocket) | -| `dmPolicy` | string | `pairing` | DM access policy | -| `allowFrom` | string[] | `[]` | Allowed sender pubkeys | -| `enabled` | boolean | `true` | Enable/disable channel | -| `name` | string | - | Display name | -| `profile` | object | - | NIP-01 profile metadata | - -## Profile metadata - -Profile data is published as a NIP-01 `kind:0` event. You can manage it from the Control UI (Channels -> Nostr -> Profile) or set it directly in config. - -Example: - -```json -{ - "channels": { - "nostr": { - "privateKey": "${NOSTR_PRIVATE_KEY}", - "profile": { - "name": "openclaw", - "displayName": "OpenClaw", - "about": "Personal assistant DM bot", - "picture": "https://example.com/avatar.png", - "banner": "https://example.com/banner.png", - "website": "https://example.com", - "nip05": "openclaw@example.com", - "lud16": "openclaw@example.com" - } - } - } -} -``` - -Notes: - -- Profile URLs must use `https://`. -- Importing from relays merges fields and preserves local overrides. - -## Access control - -### DM policies - -- **pairing** (default): unknown senders get a pairing code. -- **allowlist**: only pubkeys in `allowFrom` can DM. -- **open**: public inbound DMs (requires `allowFrom: ["*"]`). -- **disabled**: ignore inbound DMs. - -### Allowlist example - -```json -{ - "channels": { - "nostr": { - "privateKey": "${NOSTR_PRIVATE_KEY}", - "dmPolicy": "allowlist", - "allowFrom": ["npub1abc...", "npub1xyz..."] - } - } -} -``` - -## Key formats - -Accepted formats: - -- **Private key:** `nsec...` or 64-char hex -- **Pubkeys (`allowFrom`):** `npub...` or hex - -## Relays - -Defaults: `relay.damus.io` and `nos.lol`. - -```json -{ - "channels": { - "nostr": { - "privateKey": "${NOSTR_PRIVATE_KEY}", - "relays": ["wss://relay.damus.io", "wss://relay.primal.net", "wss://nostr.wine"] - } - } -} -``` - -Tips: - -- Use 2-3 relays for redundancy. -- Avoid too many relays (latency, duplication). -- Paid relays can improve reliability. -- Local relays are fine for testing (`ws://localhost:7777`). - -## Protocol support - -| NIP | Status | Description | -| ------ | --------- | ------------------------------------- | -| NIP-01 | Supported | Basic event format + profile metadata | -| NIP-04 | Supported | Encrypted DMs (`kind:4`) | -| NIP-17 | Planned | Gift-wrapped DMs | -| NIP-44 | Planned | Versioned encryption | - -## Testing - -### Local relay - -```bash -# Start strfry -docker run -p 7777:7777 ghcr.io/hoytech/strfry -``` - -```json -{ - "channels": { - "nostr": { - "privateKey": "${NOSTR_PRIVATE_KEY}", - "relays": ["ws://localhost:7777"] - } - } -} -``` - -### Manual test - -1. Note the bot pubkey (npub) from logs. -2. Open a Nostr client (Damus, Amethyst, etc.). -3. DM the bot pubkey. -4. Verify the response. - -## Troubleshooting - -### Not receiving messages - -- Verify the private key is valid. -- Ensure relay URLs are reachable and use `wss://` (or `ws://` for local). -- Confirm `enabled` is not `false`. -- Check Gateway logs for relay connection errors. - -### Not sending responses - -- Check relay accepts writes. -- Verify outbound connectivity. -- Watch for relay rate limits. - -### Duplicate responses - -- Expected when using multiple relays. -- Messages are deduplicated by event ID; only the first delivery triggers a response. - -## Security - -- Never commit private keys. -- Use environment variables for keys. -- Consider `allowlist` for production bots. - -## Limitations (MVP) - -- Direct messages only (no group chats). -- No media attachments. -- NIP-04 only (NIP-17 gift-wrap planned). diff --git a/docs/channels/pairing.md b/docs/channels/pairing.md deleted file mode 100644 index 4b575eb87c..0000000000 --- a/docs/channels/pairing.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -summary: "Pairing overview: approve who can DM you + which nodes can join" -read_when: - - Setting up DM access control - - Pairing a new iOS/Android node - - Reviewing OpenClaw security posture -title: "Pairing" ---- - -# Pairing - -“Pairing” is OpenClaw’s explicit **owner approval** step. -It is used in two places: - -1. **DM pairing** (who is allowed to talk to the bot) -2. **Node pairing** (which devices/nodes are allowed to join the gateway network) - -Security context: [Security](/gateway/security) - -## 1) DM pairing (inbound chat access) - -When a channel is configured with DM policy `pairing`, unknown senders get a short code and their message is **not processed** until you approve. - -Default DM policies are documented in: [Security](/gateway/security) - -Pairing codes: - -- 8 characters, uppercase, no ambiguous chars (`0O1I`). -- **Expire after 1 hour**. The bot only sends the pairing message when a new request is created (roughly once per hour per sender). -- Pending DM pairing requests are capped at **3 per channel** by default; additional requests are ignored until one expires or is approved. - -### Approve a sender - -```bash -openclaw pairing list telegram -openclaw pairing approve telegram -``` - -Supported channels: `telegram`, `whatsapp`, `signal`, `imessage`, `discord`, `slack`, `feishu`. - -### Where the state lives - -Stored under `~/.openclaw/credentials/`: - -- Pending requests: `-pairing.json` -- Approved allowlist store: `-allowFrom.json` - -Treat these as sensitive (they gate access to your assistant). - -## 2) Node device pairing (iOS/Android/macOS/headless nodes) - -Nodes connect to the Gateway as **devices** with `role: node`. The Gateway -creates a device pairing request that must be approved. - -### Pair via Telegram (recommended for iOS) - -If you use the `device-pair` plugin, you can do first-time device pairing entirely from Telegram: - -1. In Telegram, message your bot: `/pair` -2. The bot replies with two messages: an instruction message and a separate **setup code** message (easy to copy/paste in Telegram). -3. On your phone, open the OpenClaw iOS app → Settings → Gateway. -4. Paste the setup code and connect. -5. Back in Telegram: `/pair approve` - -The setup code is a base64-encoded JSON payload that contains: - -- `url`: the Gateway WebSocket URL (`ws://...` or `wss://...`) -- `token`: a short-lived pairing token - -Treat the setup code like a password while it is valid. - -### Approve a node device - -```bash -openclaw devices list -openclaw devices approve -openclaw devices reject -``` - -### Node pairing state storage - -Stored under `~/.openclaw/devices/`: - -- `pending.json` (short-lived; pending requests expire) -- `paired.json` (paired devices + tokens) - -### Notes - -- The legacy `node.pair.*` API (CLI: `openclaw nodes pending/approve`) is a - separate gateway-owned pairing store. WS nodes still require device pairing. - -## Related docs - -- Security model + prompt injection: [Security](/gateway/security) -- Updating safely (run doctor): [Updating](/install/updating) -- Channel configs: - - Telegram: [Telegram](/channels/telegram) - - WhatsApp: [WhatsApp](/channels/whatsapp) - - Signal: [Signal](/channels/signal) - - BlueBubbles (iMessage): [BlueBubbles](/channels/bluebubbles) - - iMessage (legacy): [iMessage](/channels/imessage) - - Discord: [Discord](/channels/discord) - - Slack: [Slack](/channels/slack) diff --git a/docs/channels/signal.md b/docs/channels/signal.md deleted file mode 100644 index 60bb5f7ce9..0000000000 --- a/docs/channels/signal.md +++ /dev/null @@ -1,324 +0,0 @@ ---- -summary: "Signal support via signal-cli (JSON-RPC + SSE), setup paths, and number model" -read_when: - - Setting up Signal support - - Debugging Signal send/receive -title: "Signal" ---- - -# Signal (signal-cli) - -Status: external CLI integration. Gateway talks to `signal-cli` over HTTP JSON-RPC + SSE. - -## Prerequisites - -- OpenClaw installed on your server (Linux flow below tested on Ubuntu 24). -- `signal-cli` available on the host where the gateway runs. -- A phone number that can receive one verification SMS (for SMS registration path). -- Browser access for Signal captcha (`signalcaptchas.org`) during registration. - -## Quick setup (beginner) - -1. Use a **separate Signal number** for the bot (recommended). -2. Install `signal-cli` (Java required if you use the JVM build). -3. Choose one setup path: - - **Path A (QR link):** `signal-cli link -n "OpenClaw"` and scan with Signal. - - **Path B (SMS register):** register a dedicated number with captcha + SMS verification. -4. Configure OpenClaw and restart the gateway. -5. Send a first DM and approve pairing (`openclaw pairing approve signal `). - -Minimal config: - -```json5 -{ - channels: { - signal: { - enabled: true, - account: "+15551234567", - cliPath: "signal-cli", - dmPolicy: "pairing", - allowFrom: ["+15557654321"], - }, - }, -} -``` - -Field reference: - -| Field | Description | -| ----------- | ------------------------------------------------- | -| `account` | Bot phone number in E.164 format (`+15551234567`) | -| `cliPath` | Path to `signal-cli` (`signal-cli` if on `PATH`) | -| `dmPolicy` | DM access policy (`pairing` recommended) | -| `allowFrom` | Phone numbers or `uuid:` values allowed to DM | - -## What it is - -- Signal channel via `signal-cli` (not embedded libsignal). -- Deterministic routing: replies always go back to Signal. -- DMs share the agent's main session; groups are isolated (`agent::signal:group:`). - -## Config writes - -By default, Signal is allowed to write config updates triggered by `/config set|unset` (requires `commands.config: true`). - -Disable with: - -```json5 -{ - channels: { signal: { configWrites: false } }, -} -``` - -## The number model (important) - -- The gateway connects to a **Signal device** (the `signal-cli` account). -- If you run the bot on **your personal Signal account**, it will ignore your own messages (loop protection). -- For "I text the bot and it replies," use a **separate bot number**. - -## Setup path A: link existing Signal account (QR) - -1. Install `signal-cli` (JVM or native build). -2. Link a bot account: - - `signal-cli link -n "OpenClaw"` then scan the QR in Signal. -3. Configure Signal and start the gateway. - -Example: - -```json5 -{ - channels: { - signal: { - enabled: true, - account: "+15551234567", - cliPath: "signal-cli", - dmPolicy: "pairing", - allowFrom: ["+15557654321"], - }, - }, -} -``` - -Multi-account support: use `channels.signal.accounts` with per-account config and optional `name`. See [`gateway/configuration`](/gateway/configuration#telegramaccounts--discordaccounts--slackaccounts--signalaccounts--imessageaccounts) for the shared pattern. - -## Setup path B: register dedicated bot number (SMS, Linux) - -Use this when you want a dedicated bot number instead of linking an existing Signal app account. - -1. Get a number that can receive SMS (or voice verification for landlines). - - Use a dedicated bot number to avoid account/session conflicts. -2. Install `signal-cli` on the gateway host: - -```bash -VERSION=$(curl -Ls -o /dev/null -w %{url_effective} https://github.com/AsamK/signal-cli/releases/latest | sed -e 's/^.*\/v//') -curl -L -O "https://github.com/AsamK/signal-cli/releases/download/v${VERSION}/signal-cli-${VERSION}-Linux-native.tar.gz" -sudo tar xf "signal-cli-${VERSION}-Linux-native.tar.gz" -C /opt -sudo ln -sf /opt/signal-cli /usr/local/bin/ -signal-cli --version -``` - -If you use the JVM build (`signal-cli-${VERSION}.tar.gz`), install JRE 25+ first. -Keep `signal-cli` updated; upstream notes that old releases can break as Signal server APIs change. - -3. Register and verify the number: - -```bash -signal-cli -a + register -``` - -If captcha is required: - -1. Open `https://signalcaptchas.org/registration/generate.html`. -2. Complete captcha, copy the `signalcaptcha://...` link target from "Open Signal". -3. Run from the same external IP as the browser session when possible. -4. Run registration again immediately (captcha tokens expire quickly): - -```bash -signal-cli -a + register --captcha '' -signal-cli -a + verify -``` - -4. Configure OpenClaw, restart gateway, verify channel: - -```bash -# If you run the gateway as a user systemd service: -systemctl --user restart openclaw-gateway - -# Then verify: -openclaw doctor -openclaw channels status --probe -``` - -5. Pair your DM sender: - - Send any message to the bot number. - - Approve code on the server: `openclaw pairing approve signal `. - - Save the bot number as a contact on your phone to avoid "Unknown contact". - -Important: registering a phone number account with `signal-cli` can de-authenticate the main Signal app session for that number. Prefer a dedicated bot number, or use QR link mode if you need to keep your existing phone app setup. - -Upstream references: - -- `signal-cli` README: `https://github.com/AsamK/signal-cli` -- Captcha flow: `https://github.com/AsamK/signal-cli/wiki/Registration-with-captcha` -- Linking flow: `https://github.com/AsamK/signal-cli/wiki/Linking-other-devices-(Provisioning)` - -## External daemon mode (httpUrl) - -If you want to manage `signal-cli` yourself (slow JVM cold starts, container init, or shared CPUs), run the daemon separately and point OpenClaw at it: - -```json5 -{ - channels: { - signal: { - httpUrl: "http://127.0.0.1:8080", - autoStart: false, - }, - }, -} -``` - -This skips auto-spawn and the startup wait inside OpenClaw. For slow starts when auto-spawning, set `channels.signal.startupTimeoutMs`. - -## Access control (DMs + groups) - -DMs: - -- Default: `channels.signal.dmPolicy = "pairing"`. -- Unknown senders receive a pairing code; messages are ignored until approved (codes expire after 1 hour). -- Approve via: - - `openclaw pairing list signal` - - `openclaw pairing approve signal ` -- Pairing is the default token exchange for Signal DMs. Details: [Pairing](/channels/pairing) -- UUID-only senders (from `sourceUuid`) are stored as `uuid:` in `channels.signal.allowFrom`. - -Groups: - -- `channels.signal.groupPolicy = open | allowlist | disabled`. -- `channels.signal.groupAllowFrom` controls who can trigger in groups when `allowlist` is set. - -## How it works (behavior) - -- `signal-cli` runs as a daemon; the gateway reads events via SSE. -- Inbound messages are normalized into the shared channel envelope. -- Replies always route back to the same number or group. - -## Media + limits - -- Outbound text is chunked to `channels.signal.textChunkLimit` (default 4000). -- Optional newline chunking: set `channels.signal.chunkMode="newline"` to split on blank lines (paragraph boundaries) before length chunking. -- Attachments supported (base64 fetched from `signal-cli`). -- Default media cap: `channels.signal.mediaMaxMb` (default 8). -- Use `channels.signal.ignoreAttachments` to skip downloading media. -- Group history context uses `channels.signal.historyLimit` (or `channels.signal.accounts.*.historyLimit`), falling back to `messages.groupChat.historyLimit`. Set `0` to disable (default 50). - -## Typing + read receipts - -- **Typing indicators**: OpenClaw sends typing signals via `signal-cli sendTyping` and refreshes them while a reply is running. -- **Read receipts**: when `channels.signal.sendReadReceipts` is true, OpenClaw forwards read receipts for allowed DMs. -- Signal-cli does not expose read receipts for groups. - -## Reactions (message tool) - -- Use `message action=react` with `channel=signal`. -- Targets: sender E.164 or UUID (use `uuid:` from pairing output; bare UUID works too). -- `messageId` is the Signal timestamp for the message you’re reacting to. -- Group reactions require `targetAuthor` or `targetAuthorUuid`. - -Examples: - -``` -message action=react channel=signal target=uuid:123e4567-e89b-12d3-a456-426614174000 messageId=1737630212345 emoji=🔥 -message action=react channel=signal target=+15551234567 messageId=1737630212345 emoji=🔥 remove=true -message action=react channel=signal target=signal:group: targetAuthor=uuid: messageId=1737630212345 emoji=✅ -``` - -Config: - -- `channels.signal.actions.reactions`: enable/disable reaction actions (default true). -- `channels.signal.reactionLevel`: `off | ack | minimal | extensive`. - - `off`/`ack` disables agent reactions (message tool `react` will error). - - `minimal`/`extensive` enables agent reactions and sets the guidance level. -- Per-account overrides: `channels.signal.accounts..actions.reactions`, `channels.signal.accounts..reactionLevel`. - -## Delivery targets (CLI/cron) - -- DMs: `signal:+15551234567` (or plain E.164). -- UUID DMs: `uuid:` (or bare UUID). -- Groups: `signal:group:`. -- Usernames: `username:` (if supported by your Signal account). - -## Troubleshooting - -Run this ladder first: - -```bash -openclaw status -openclaw gateway status -openclaw logs --follow -openclaw doctor -openclaw channels status --probe -``` - -Then confirm DM pairing state if needed: - -```bash -openclaw pairing list signal -``` - -Common failures: - -- Daemon reachable but no replies: verify account/daemon settings (`httpUrl`, `account`) and receive mode. -- DMs ignored: sender is pending pairing approval. -- Group messages ignored: group sender/mention gating blocks delivery. -- Config validation errors after edits: run `openclaw doctor --fix`. -- Signal missing from diagnostics: confirm `channels.signal.enabled: true`. - -Extra checks: - -```bash -openclaw pairing list signal -pgrep -af signal-cli -grep -i "signal" "/tmp/openclaw/openclaw-$(date +%Y-%m-%d).log" | tail -20 -``` - -For triage flow: [/channels/troubleshooting](/channels/troubleshooting). - -## Security notes - -- `signal-cli` stores account keys locally (typically `~/.local/share/signal-cli/data/`). -- Back up Signal account state before server migration or rebuild. -- Keep `channels.signal.dmPolicy: "pairing"` unless you explicitly want broader DM access. -- SMS verification is only needed for registration or recovery flows, but losing control of the number/account can complicate re-registration. - -## Configuration reference (Signal) - -Full configuration: [Configuration](/gateway/configuration) - -Provider options: - -- `channels.signal.enabled`: enable/disable channel startup. -- `channels.signal.account`: E.164 for the bot account. -- `channels.signal.cliPath`: path to `signal-cli`. -- `channels.signal.httpUrl`: full daemon URL (overrides host/port). -- `channels.signal.httpHost`, `channels.signal.httpPort`: daemon bind (default 127.0.0.1:8080). -- `channels.signal.autoStart`: auto-spawn daemon (default true if `httpUrl` unset). -- `channels.signal.startupTimeoutMs`: startup wait timeout in ms (cap 120000). -- `channels.signal.receiveMode`: `on-start | manual`. -- `channels.signal.ignoreAttachments`: skip attachment downloads. -- `channels.signal.ignoreStories`: ignore stories from the daemon. -- `channels.signal.sendReadReceipts`: forward read receipts. -- `channels.signal.dmPolicy`: `pairing | allowlist | open | disabled` (default: pairing). -- `channels.signal.allowFrom`: DM allowlist (E.164 or `uuid:`). `open` requires `"*"`. Signal has no usernames; use phone/UUID ids. -- `channels.signal.groupPolicy`: `open | allowlist | disabled` (default: allowlist). -- `channels.signal.groupAllowFrom`: group sender allowlist. -- `channels.signal.historyLimit`: max group messages to include as context (0 disables). -- `channels.signal.dmHistoryLimit`: DM history limit in user turns. Per-user overrides: `channels.signal.dms[""].historyLimit`. -- `channels.signal.textChunkLimit`: outbound chunk size (chars). -- `channels.signal.chunkMode`: `length` (default) or `newline` to split on blank lines (paragraph boundaries) before length chunking. -- `channels.signal.mediaMaxMb`: inbound/outbound media cap (MB). - -Related global options: - -- `agents.list[].groupChat.mentionPatterns` (Signal does not support native mentions). -- `messages.groupChat.mentionPatterns` (global fallback). -- `messages.responsePrefix`. diff --git a/docs/channels/slack.md b/docs/channels/slack.md deleted file mode 100644 index 9fdd3fb89a..0000000000 --- a/docs/channels/slack.md +++ /dev/null @@ -1,510 +0,0 @@ ---- -summary: "Slack setup and runtime behavior (Socket Mode + HTTP Events API)" -read_when: - - Setting up Slack or debugging Slack socket/HTTP mode -title: "Slack" ---- - -# Slack - -Status: production-ready for DMs + channels via Slack app integrations. Default mode is Socket Mode; HTTP Events API mode is also supported. - - - - Slack DMs default to pairing mode. - - - Native command behavior and command catalog. - - - Cross-channel diagnostics and repair playbooks. - - - -## Quick setup - - - - - - In Slack app settings: - - - enable **Socket Mode** - - create **App Token** (`xapp-...`) with `connections:write` - - install app and copy **Bot Token** (`xoxb-...`) - - - - -```json5 -{ - channels: { - slack: { - enabled: true, - mode: "socket", - appToken: "xapp-...", - botToken: "xoxb-...", - }, - }, -} -``` - - Env fallback (default account only): - -```bash -SLACK_APP_TOKEN=xapp-... -SLACK_BOT_TOKEN=xoxb-... -``` - - - - - Subscribe bot events for: - - - `app_mention` - - `message.channels`, `message.groups`, `message.im`, `message.mpim` - - `reaction_added`, `reaction_removed` - - `member_joined_channel`, `member_left_channel` - - `channel_rename` - - `pin_added`, `pin_removed` - - Also enable App Home **Messages Tab** for DMs. - - - - -```bash -openclaw gateway -``` - - - - - - - - - - - - set mode to HTTP (`channels.slack.mode="http"`) - - copy Slack **Signing Secret** - - set Event Subscriptions + Interactivity + Slash command Request URL to the same webhook path (default `/slack/events`) - - - - - -```json5 -{ - channels: { - slack: { - enabled: true, - mode: "http", - botToken: "xoxb-...", - signingSecret: "your-signing-secret", - webhookPath: "/slack/events", - }, - }, -} -``` - - - - - Per-account HTTP mode is supported. - - Give each account a distinct `webhookPath` so registrations do not collide. - - - - - - -## Token model - -- `botToken` + `appToken` are required for Socket Mode. -- HTTP mode requires `botToken` + `signingSecret`. -- Config tokens override env fallback. -- `SLACK_BOT_TOKEN` / `SLACK_APP_TOKEN` env fallback applies only to the default account. -- `userToken` (`xoxp-...`) is config-only (no env fallback) and defaults to read-only behavior (`userTokenReadOnly: true`). -- Optional: add `chat:write.customize` if you want outgoing messages to use the active agent identity (custom `username` and icon). `icon_emoji` uses `:emoji_name:` syntax. - - -For actions/directory reads, user token can be preferred when configured. For writes, bot token remains preferred; user-token writes are only allowed when `userTokenReadOnly: false` and bot token is unavailable. - - -## Access control and routing - - - - `channels.slack.dmPolicy` controls DM access (legacy: `channels.slack.dm.policy`): - - - `pairing` (default) - - `allowlist` - - `open` (requires `channels.slack.allowFrom` to include `"*"`; legacy: `channels.slack.dm.allowFrom`) - - `disabled` - - DM flags: - - - `dm.enabled` (default true) - - `channels.slack.allowFrom` (preferred) - - `dm.allowFrom` (legacy) - - `dm.groupEnabled` (group DMs default false) - - `dm.groupChannels` (optional MPIM allowlist) - - Pairing in DMs uses `openclaw pairing approve slack `. - - - - - `channels.slack.groupPolicy` controls channel handling: - - - `open` - - `allowlist` - - `disabled` - - Channel allowlist lives under `channels.slack.channels`. - - Runtime note: if `channels.slack` is completely missing (env-only setup) and `channels.defaults.groupPolicy` is unset, runtime falls back to `groupPolicy="open"` and logs a warning. - - Name/ID resolution: - - - channel allowlist entries and DM allowlist entries are resolved at startup when token access allows - - unresolved entries are kept as configured - - - - - Channel messages are mention-gated by default. - - Mention sources: - - - explicit app mention (`<@botId>`) - - mention regex patterns (`agents.list[].groupChat.mentionPatterns`, fallback `messages.groupChat.mentionPatterns`) - - implicit reply-to-bot thread behavior - - Per-channel controls (`channels.slack.channels.`): - - - `requireMention` - - `users` (allowlist) - - `allowBots` - - `skills` - - `systemPrompt` - - `tools`, `toolsBySender` - - - - -## Commands and slash behavior - -- Native command auto-mode is **off** for Slack (`commands.native: "auto"` does not enable Slack native commands). -- Enable native Slack command handlers with `channels.slack.commands.native: true` (or global `commands.native: true`). -- When native commands are enabled, register matching slash commands in Slack (`/` names). -- If native commands are not enabled, you can run a single configured slash command via `channels.slack.slashCommand`. -- Native arg menus now adapt their rendering strategy: - - up to 5 options: button blocks - - 6-100 options: static select menu - - more than 100 options: external select with async option filtering when interactivity options handlers are available - - if encoded option values exceed Slack limits, the flow falls back to buttons -- For long option payloads, Slash command argument menus use a confirm dialog before dispatching a selected value. - -Default slash command settings: - -- `enabled: false` -- `name: "openclaw"` -- `sessionPrefix: "slack:slash"` -- `ephemeral: true` - -Slash sessions use isolated keys: - -- `agent::slack:slash:` - -and still route command execution against the target conversation session (`CommandTargetSessionKey`). - -## Threading, sessions, and reply tags - -- DMs route as `direct`; channels as `channel`; MPIMs as `group`. -- With default `session.dmScope=main`, Slack DMs collapse to agent main session. -- Channel sessions: `agent::slack:channel:`. -- Thread replies can create thread session suffixes (`:thread:`) when applicable. -- `channels.slack.thread.historyScope` default is `thread`; `thread.inheritParent` default is `false`. -- `channels.slack.thread.initialHistoryLimit` controls how many existing thread messages are fetched when a new thread session starts (default `20`; set `0` to disable). - -Reply threading controls: - -- `channels.slack.replyToMode`: `off|first|all` (default `off`) -- `channels.slack.replyToModeByChatType`: per `direct|group|channel` -- legacy fallback for direct chats: `channels.slack.dm.replyToMode` - -Manual reply tags are supported: - -- `[[reply_to_current]]` -- `[[reply_to:]]` - -Note: `replyToMode="off"` disables implicit reply threading. Explicit `[[reply_to_*]]` tags are still honored. - -## Media, chunking, and delivery - - - - Slack file attachments are downloaded from Slack-hosted private URLs (token-authenticated request flow) and written to the media store when fetch succeeds and size limits permit. - - Runtime inbound size cap defaults to `20MB` unless overridden by `channels.slack.mediaMaxMb`. - - - - - - text chunks use `channels.slack.textChunkLimit` (default 4000) - - `channels.slack.chunkMode="newline"` enables paragraph-first splitting - - file sends use Slack upload APIs and can include thread replies (`thread_ts`) - - outbound media cap follows `channels.slack.mediaMaxMb` when configured; otherwise channel sends use MIME-kind defaults from media pipeline - - - - Preferred explicit targets: - - - `user:` for DMs - - `channel:` for channels - - Slack DMs are opened via Slack conversation APIs when sending to user targets. - - - - -## Actions and gates - -Slack actions are controlled by `channels.slack.actions.*`. - -Available action groups in current Slack tooling: - -| Group | Default | -| ---------- | ------- | -| messages | enabled | -| reactions | enabled | -| pins | enabled | -| memberInfo | enabled | -| emojiList | enabled | - -## Events and operational behavior - -- Message edits/deletes/thread broadcasts are mapped into system events. -- Reaction add/remove events are mapped into system events. -- Member join/leave, channel created/renamed, and pin add/remove events are mapped into system events. -- Assistant thread status updates (for "is typing..." indicators in threads) use `assistant.threads.setStatus` and require bot scope `assistant:write`. -- `channel_id_changed` can migrate channel config keys when `configWrites` is enabled. -- Channel topic/purpose metadata is treated as untrusted context and can be injected into routing context. -- Block actions and modal interactions emit structured `Slack interaction: ...` system events with rich payload fields: - - block actions: selected values, labels, picker values, and `workflow_*` metadata - - modal `view_submission` and `view_closed` events with routed channel metadata and form inputs - -## Ack reactions - -`ackReaction` sends an acknowledgement emoji while OpenClaw is processing an inbound message. - -Resolution order: - -- `channels.slack.accounts..ackReaction` -- `channels.slack.ackReaction` -- `messages.ackReaction` -- agent identity emoji fallback (`agents.list[].identity.emoji`, else "👀") - -Notes: - -- Slack expects shortcodes (for example `"eyes"`). -- Use `""` to disable the reaction for a channel or account. - -## Manifest and scope checklist - - - - -```json -{ - "display_information": { - "name": "OpenClaw", - "description": "Slack connector for OpenClaw" - }, - "features": { - "bot_user": { - "display_name": "OpenClaw", - "always_online": false - }, - "app_home": { - "messages_tab_enabled": true, - "messages_tab_read_only_enabled": false - }, - "slash_commands": [ - { - "command": "/openclaw", - "description": "Send a message to OpenClaw", - "should_escape": false - } - ] - }, - "oauth_config": { - "scopes": { - "bot": [ - "chat:write", - "channels:history", - "channels:read", - "groups:history", - "im:history", - "mpim:history", - "users:read", - "app_mentions:read", - "assistant:write", - "reactions:read", - "reactions:write", - "pins:read", - "pins:write", - "emoji:read", - "commands", - "files:read", - "files:write" - ] - } - }, - "settings": { - "socket_mode_enabled": true, - "event_subscriptions": { - "bot_events": [ - "app_mention", - "message.channels", - "message.groups", - "message.im", - "message.mpim", - "reaction_added", - "reaction_removed", - "member_joined_channel", - "member_left_channel", - "channel_rename", - "pin_added", - "pin_removed" - ] - } - } -} -``` - - - - - If you configure `channels.slack.userToken`, typical read scopes are: - - - `channels:history`, `groups:history`, `im:history`, `mpim:history` - - `channels:read`, `groups:read`, `im:read`, `mpim:read` - - `users:read` - - `reactions:read` - - `pins:read` - - `emoji:read` - - `search:read` (if you depend on Slack search reads) - - - - -## Troubleshooting - - - - Check, in order: - - - `groupPolicy` - - channel allowlist (`channels.slack.channels`) - - `requireMention` - - per-channel `users` allowlist - - Useful commands: - -```bash -openclaw channels status --probe -openclaw logs --follow -openclaw doctor -``` - - - - - Check: - - - `channels.slack.dm.enabled` - - `channels.slack.dmPolicy` (or legacy `channels.slack.dm.policy`) - - pairing approvals / allowlist entries - -```bash -openclaw pairing list slack -``` - - - - - Validate bot + app tokens and Socket Mode enablement in Slack app settings. - - - - Validate: - - - signing secret - - webhook path - - Slack Request URLs (Events + Interactivity + Slash Commands) - - unique `webhookPath` per HTTP account - - - - - Verify whether you intended: - - - native command mode (`channels.slack.commands.native: true`) with matching slash commands registered in Slack - - or single slash command mode (`channels.slack.slashCommand.enabled: true`) - - Also check `commands.useAccessGroups` and channel/user allowlists. - - - - -## Text streaming - -OpenClaw supports Slack native text streaming via the Agents and AI Apps API. - -By default, streaming is enabled. Disable it per account: - -```yaml -channels: - slack: - streaming: false -``` - -### Requirements - -1. Enable **Agents and AI Apps** in your Slack app settings. -2. Ensure the app has the `assistant:write` scope. -3. A reply thread must be available for that message. Thread selection still follows `replyToMode`. - -### Behavior - -- First text chunk starts a stream (`chat.startStream`). -- Later text chunks append to the same stream (`chat.appendStream`). -- End of reply finalizes stream (`chat.stopStream`). -- Media and non-text payloads fall back to normal delivery. -- If streaming fails mid-reply, OpenClaw falls back to normal delivery for remaining payloads. - -## Configuration reference pointers - -Primary reference: - -- [Configuration reference - Slack](/gateway/configuration-reference#slack) - - High-signal Slack fields: - - mode/auth: `mode`, `botToken`, `appToken`, `signingSecret`, `webhookPath`, `accounts.*` - - DM access: `dm.enabled`, `dmPolicy`, `allowFrom` (legacy: `dm.policy`, `dm.allowFrom`), `dm.groupEnabled`, `dm.groupChannels` - - channel access: `groupPolicy`, `channels.*`, `channels.*.users`, `channels.*.requireMention` - - threading/history: `replyToMode`, `replyToModeByChatType`, `thread.*`, `historyLimit`, `dmHistoryLimit`, `dms.*.historyLimit` - - delivery: `textChunkLimit`, `chunkMode`, `mediaMaxMb` - - ops/features: `configWrites`, `commands.native`, `slashCommand.*`, `actions.*`, `userToken`, `userTokenReadOnly` - -## Related - -- [Pairing](/channels/pairing) -- [Channel routing](/channels/channel-routing) -- [Troubleshooting](/channels/troubleshooting) -- [Configuration](/gateway/configuration) -- [Slash commands](/tools/slash-commands) diff --git a/docs/channels/telegram.md b/docs/channels/telegram.md deleted file mode 100644 index 7e1d95d2fe..0000000000 --- a/docs/channels/telegram.md +++ /dev/null @@ -1,761 +0,0 @@ ---- -summary: "Telegram bot support status, capabilities, and configuration" -read_when: - - Working on Telegram features or webhooks -title: "Telegram" ---- - -# Telegram (Bot API) - -Status: production-ready for bot DMs + groups via grammY. Long polling is the default mode; webhook mode is optional. - - - - Default DM policy for Telegram is pairing. - - - Cross-channel diagnostics and repair playbooks. - - - Full channel config patterns and examples. - - - -## Quick setup - - - - Open Telegram and chat with **@BotFather** (confirm the handle is exactly `@BotFather`). - - Run `/newbot`, follow prompts, and save the token. - - - - - -```json5 -{ - channels: { - telegram: { - enabled: true, - botToken: "123:abc", - dmPolicy: "pairing", - groups: { "*": { requireMention: true } }, - }, - }, -} -``` - - Env fallback: `TELEGRAM_BOT_TOKEN=...` (default account only). - - - - - -```bash -openclaw gateway -openclaw pairing list telegram -openclaw pairing approve telegram -``` - - Pairing codes expire after 1 hour. - - - - - Add the bot to your group, then set `channels.telegram.groups` and `groupPolicy` to match your access model. - - - - -Token resolution order is account-aware. In practice, config values win over env fallback, and `TELEGRAM_BOT_TOKEN` only applies to the default account. - - -## Telegram side settings - - - - Telegram bots default to **Privacy Mode**, which limits what group messages they receive. - - If the bot must see all group messages, either: - - - disable privacy mode via `/setprivacy`, or - - make the bot a group admin. - - When toggling privacy mode, remove + re-add the bot in each group so Telegram applies the change. - - - - - Admin status is controlled in Telegram group settings. - - Admin bots receive all group messages, which is useful for always-on group behavior. - - - - - - - `/setjoingroups` to allow/deny group adds - - `/setprivacy` for group visibility behavior - - - - -## Access control and activation - - - - `channels.telegram.dmPolicy` controls direct message access: - - - `pairing` (default) - - `allowlist` - - `open` (requires `allowFrom` to include `"*"`) - - `disabled` - - `channels.telegram.allowFrom` accepts numeric Telegram user IDs. `telegram:` / `tg:` prefixes are accepted and normalized. - The onboarding wizard accepts `@username` input and resolves it to numeric IDs. - If you upgraded and your config contains `@username` allowlist entries, run `openclaw doctor --fix` to resolve them (best-effort; requires a Telegram bot token). - - ### Finding your Telegram user ID - - Safer (no third-party bot): - - 1. DM your bot. - 2. Run `openclaw logs --follow`. - 3. Read `from.id`. - - Official Bot API method: - -```bash -curl "https://api.telegram.org/bot/getUpdates" -``` - - Third-party method (less private): `@userinfobot` or `@getidsbot`. - - - - - There are two independent controls: - - 1. **Which groups are allowed** (`channels.telegram.groups`) - - no `groups` config: all groups allowed - - `groups` configured: acts as allowlist (explicit IDs or `"*"`) - - 2. **Which senders are allowed in groups** (`channels.telegram.groupPolicy`) - - `open` - - `allowlist` (default) - - `disabled` - - `groupAllowFrom` is used for group sender filtering. If not set, Telegram falls back to `allowFrom`. - `groupAllowFrom` entries must be numeric Telegram user IDs. - - Example: allow any member in one specific group: - -```json5 -{ - channels: { - telegram: { - groups: { - "-1001234567890": { - groupPolicy: "open", - requireMention: false, - }, - }, - }, - }, -} -``` - - - - - Group replies require mention by default. - - Mention can come from: - - - native `@botusername` mention, or - - mention patterns in: - - `agents.list[].groupChat.mentionPatterns` - - `messages.groupChat.mentionPatterns` - - Session-level command toggles: - - - `/activation always` - - `/activation mention` - - These update session state only. Use config for persistence. - - Persistent config example: - -```json5 -{ - channels: { - telegram: { - groups: { - "*": { requireMention: false }, - }, - }, - }, -} -``` - - Getting the group chat ID: - - - forward a group message to `@userinfobot` / `@getidsbot` - - or read `chat.id` from `openclaw logs --follow` - - or inspect Bot API `getUpdates` - - - - -## Runtime behavior - -- Telegram is owned by the gateway process. -- Routing is deterministic: Telegram inbound replies back to Telegram (the model does not pick channels). -- Inbound messages normalize into the shared channel envelope with reply metadata and media placeholders. -- Group sessions are isolated by group ID. Forum topics append `:topic:` to keep topics isolated. -- DM messages can carry `message_thread_id`; OpenClaw routes them with thread-aware session keys and preserves thread ID for replies. -- Long polling uses grammY runner with per-chat/per-thread sequencing. Overall runner sink concurrency uses `agents.defaults.maxConcurrent`. -- Telegram Bot API has no read-receipt support (`sendReadReceipts` does not apply). - -## Feature reference - - - - OpenClaw can stream partial replies by sending a temporary Telegram message and editing it as text arrives. - - Requirement: - - - `channels.telegram.streamMode` is not `"off"` (default: `"partial"`) - - Modes: - - - `off`: no live preview - - `partial`: frequent preview updates from partial text - - `block`: chunked preview updates using `channels.telegram.draftChunk` - - `draftChunk` defaults for `streamMode: "block"`: - - - `minChars: 200` - - `maxChars: 800` - - `breakPreference: "paragraph"` - - `maxChars` is clamped by `channels.telegram.textChunkLimit`. - - This works in direct chats and groups/topics. - - For text-only replies, OpenClaw keeps the same preview message and performs a final edit in place (no second message). - - For complex replies (for example media payloads), OpenClaw falls back to normal final delivery and then cleans up the preview message. - - `streamMode` is separate from block streaming. When block streaming is explicitly enabled for Telegram, OpenClaw skips the preview stream to avoid double-streaming. - - Telegram-only reasoning stream: - - - `/reasoning stream` sends reasoning to the live preview while generating - - final answer is sent without reasoning text - - - - - Outbound text uses Telegram `parse_mode: "HTML"`. - - - Markdown-ish text is rendered to Telegram-safe HTML. - - Raw model HTML is escaped to reduce Telegram parse failures. - - If Telegram rejects parsed HTML, OpenClaw retries as plain text. - - Link previews are enabled by default and can be disabled with `channels.telegram.linkPreview: false`. - - - - - Telegram command menu registration is handled at startup with `setMyCommands`. - - Native command defaults: - - - `commands.native: "auto"` enables native commands for Telegram - - Add custom command menu entries: - -```json5 -{ - channels: { - telegram: { - customCommands: [ - { command: "backup", description: "Git backup" }, - { command: "generate", description: "Create an image" }, - ], - }, - }, -} -``` - - Rules: - - - names are normalized (strip leading `/`, lowercase) - - valid pattern: `a-z`, `0-9`, `_`, length `1..32` - - custom commands cannot override native commands - - conflicts/duplicates are skipped and logged - - Notes: - - - custom commands are menu entries only; they do not auto-implement behavior - - plugin/skill commands can still work when typed even if not shown in Telegram menu - - If native commands are disabled, built-ins are removed. Custom/plugin commands may still register if configured. - - Common setup failure: - - - `setMyCommands failed` usually means outbound DNS/HTTPS to `api.telegram.org` is blocked. - - ### Device pairing commands (`device-pair` plugin) - - When the `device-pair` plugin is installed: - - 1. `/pair` generates setup code - 2. paste code in iOS app - 3. `/pair approve` approves latest pending request - - More details: [Pairing](/channels/pairing#pair-via-telegram-recommended-for-ios). - - - - - Configure inline keyboard scope: - -```json5 -{ - channels: { - telegram: { - capabilities: { - inlineButtons: "allowlist", - }, - }, - }, -} -``` - - Per-account override: - -```json5 -{ - channels: { - telegram: { - accounts: { - main: { - capabilities: { - inlineButtons: "allowlist", - }, - }, - }, - }, - }, -} -``` - - Scopes: - - - `off` - - `dm` - - `group` - - `all` - - `allowlist` (default) - - Legacy `capabilities: ["inlineButtons"]` maps to `inlineButtons: "all"`. - - Message action example: - -```json5 -{ - action: "send", - channel: "telegram", - to: "123456789", - message: "Choose an option:", - buttons: [ - [ - { text: "Yes", callback_data: "yes" }, - { text: "No", callback_data: "no" }, - ], - [{ text: "Cancel", callback_data: "cancel" }], - ], -} -``` - - Callback clicks are passed to the agent as text: - `callback_data: ` - - - - - Telegram tool actions include: - - - `sendMessage` (`to`, `content`, optional `mediaUrl`, `replyToMessageId`, `messageThreadId`) - - `react` (`chatId`, `messageId`, `emoji`) - - `deleteMessage` (`chatId`, `messageId`) - - `editMessage` (`chatId`, `messageId`, `content`) - - Channel message actions expose ergonomic aliases (`send`, `react`, `delete`, `edit`, `sticker`, `sticker-search`). - - Gating controls: - - - `channels.telegram.actions.sendMessage` - - `channels.telegram.actions.editMessage` - - `channels.telegram.actions.deleteMessage` - - `channels.telegram.actions.reactions` - - `channels.telegram.actions.sticker` (default: disabled) - - Reaction removal semantics: [/tools/reactions](/tools/reactions) - - - - - Telegram supports explicit reply threading tags in generated output: - - - `[[reply_to_current]]` replies to the triggering message - - `[[reply_to:]]` replies to a specific Telegram message ID - - `channels.telegram.replyToMode` controls handling: - - - `off` (default) - - `first` - - `all` - - Note: `off` disables implicit reply threading. Explicit `[[reply_to_*]]` tags are still honored. - - - - - Forum supergroups: - - - topic session keys append `:topic:` - - replies and typing target the topic thread - - topic config path: - `channels.telegram.groups..topics.` - - General topic (`threadId=1`) special-case: - - - message sends omit `message_thread_id` (Telegram rejects `sendMessage(...thread_id=1)`) - - typing actions still include `message_thread_id` - - Topic inheritance: topic entries inherit group settings unless overridden (`requireMention`, `allowFrom`, `skills`, `systemPrompt`, `enabled`, `groupPolicy`). - - Template context includes: - - - `MessageThreadId` - - `IsForum` - - DM thread behavior: - - - private chats with `message_thread_id` keep DM routing but use thread-aware session keys/reply targets. - - - - - ### Audio messages - - Telegram distinguishes voice notes vs audio files. - - - default: audio file behavior - - tag `[[audio_as_voice]]` in agent reply to force voice-note send - - Message action example: - -```json5 -{ - action: "send", - channel: "telegram", - to: "123456789", - media: "https://example.com/voice.ogg", - asVoice: true, -} -``` - - ### Video messages - - Telegram distinguishes video files vs video notes. - - Message action example: - -```json5 -{ - action: "send", - channel: "telegram", - to: "123456789", - media: "https://example.com/video.mp4", - asVideoNote: true, -} -``` - - Video notes do not support captions; provided message text is sent separately. - - ### Stickers - - Inbound sticker handling: - - - static WEBP: downloaded and processed (placeholder ``) - - animated TGS: skipped - - video WEBM: skipped - - Sticker context fields: - - - `Sticker.emoji` - - `Sticker.setName` - - `Sticker.fileId` - - `Sticker.fileUniqueId` - - `Sticker.cachedDescription` - - Sticker cache file: - - - `~/.openclaw/telegram/sticker-cache.json` - - Stickers are described once (when possible) and cached to reduce repeated vision calls. - - Enable sticker actions: - -```json5 -{ - channels: { - telegram: { - actions: { - sticker: true, - }, - }, - }, -} -``` - - Send sticker action: - -```json5 -{ - action: "sticker", - channel: "telegram", - to: "123456789", - fileId: "CAACAgIAAxkBAAI...", -} -``` - - Search cached stickers: - -```json5 -{ - action: "sticker-search", - channel: "telegram", - query: "cat waving", - limit: 5, -} -``` - - - - - Telegram reactions arrive as `message_reaction` updates (separate from message payloads). - - When enabled, OpenClaw enqueues system events like: - - - `Telegram reaction added: 👍 by Alice (@alice) on msg 42` - - Config: - - - `channels.telegram.reactionNotifications`: `off | own | all` (default: `own`) - - `channels.telegram.reactionLevel`: `off | ack | minimal | extensive` (default: `minimal`) - - Notes: - - - `own` means user reactions to bot-sent messages only (best-effort via sent-message cache). - - Telegram does not provide thread IDs in reaction updates. - - non-forum groups route to group chat session - - forum groups route to the group general-topic session (`:topic:1`), not the exact originating topic - - `allowed_updates` for polling/webhook include `message_reaction` automatically. - - - - - `ackReaction` sends an acknowledgement emoji while OpenClaw is processing an inbound message. - - Resolution order: - - - `channels.telegram.accounts..ackReaction` - - `channels.telegram.ackReaction` - - `messages.ackReaction` - - agent identity emoji fallback (`agents.list[].identity.emoji`, else "👀") - - Notes: - - - Telegram expects unicode emoji (for example "👀"). - - Use `""` to disable the reaction for a channel or account. - - - - - Channel config writes are enabled by default (`configWrites !== false`). - - Telegram-triggered writes include: - - - group migration events (`migrate_to_chat_id`) to update `channels.telegram.groups` - - `/config set` and `/config unset` (requires command enablement) - - Disable: - -```json5 -{ - channels: { - telegram: { - configWrites: false, - }, - }, -} -``` - - - - - Default: long polling. - - Webhook mode: - - - set `channels.telegram.webhookUrl` - - set `channels.telegram.webhookSecret` (required when webhook URL is set) - - optional `channels.telegram.webhookPath` (default `/telegram-webhook`) - - optional `channels.telegram.webhookHost` (default `127.0.0.1`) - - Default local listener for webhook mode binds to `127.0.0.1:8787`. - - If your public endpoint differs, place a reverse proxy in front and point `webhookUrl` at the public URL. - Set `webhookHost` (for example `0.0.0.0`) when you intentionally need external ingress. - - - - - - `channels.telegram.textChunkLimit` default is 4000. - - `channels.telegram.chunkMode="newline"` prefers paragraph boundaries (blank lines) before length splitting. - - `channels.telegram.mediaMaxMb` (default 5) caps inbound Telegram media download/processing size. - - `channels.telegram.timeoutSeconds` overrides Telegram API client timeout (if unset, grammY default applies). - - group context history uses `channels.telegram.historyLimit` or `messages.groupChat.historyLimit` (default 50); `0` disables. - - DM history controls: - - `channels.telegram.dmHistoryLimit` - - `channels.telegram.dms[""].historyLimit` - - outbound Telegram API retries are configurable via `channels.telegram.retry`. - - CLI send target can be numeric chat ID or username: - -```bash -openclaw message send --channel telegram --target 123456789 --message "hi" -openclaw message send --channel telegram --target @name --message "hi" -``` - - - - -## Troubleshooting - - - - - - If `requireMention=false`, Telegram privacy mode must allow full visibility. - - BotFather: `/setprivacy` -> Disable - - then remove + re-add bot to group - - `openclaw channels status` warns when config expects unmentioned group messages. - - `openclaw channels status --probe` can check explicit numeric group IDs; wildcard `"*"` cannot be membership-probed. - - quick session test: `/activation always`. - - - - - - - when `channels.telegram.groups` exists, group must be listed (or include `"*"`) - - verify bot membership in group - - review logs: `openclaw logs --follow` for skip reasons - - - - - - - authorize your sender identity (pairing and/or numeric `allowFrom`) - - command authorization still applies even when group policy is `open` - - `setMyCommands failed` usually indicates DNS/HTTPS reachability issues to `api.telegram.org` - - - - - - - Node 22+ + custom fetch/proxy can trigger immediate abort behavior if AbortSignal types mismatch. - - Some hosts resolve `api.telegram.org` to IPv6 first; broken IPv6 egress can cause intermittent Telegram API failures. - - Validate DNS answers: - -```bash -dig +short api.telegram.org A -dig +short api.telegram.org AAAA -``` - - - - -More help: [Channel troubleshooting](/channels/troubleshooting). - -## Telegram config reference pointers - -Primary reference: - -- `channels.telegram.enabled`: enable/disable channel startup. -- `channels.telegram.botToken`: bot token (BotFather). -- `channels.telegram.tokenFile`: read token from file path. -- `channels.telegram.dmPolicy`: `pairing | allowlist | open | disabled` (default: pairing). -- `channels.telegram.allowFrom`: DM allowlist (numeric Telegram user IDs). `open` requires `"*"`. `openclaw doctor --fix` can resolve legacy `@username` entries to IDs. -- `channels.telegram.groupPolicy`: `open | allowlist | disabled` (default: allowlist). -- `channels.telegram.groupAllowFrom`: group sender allowlist (numeric Telegram user IDs). `openclaw doctor --fix` can resolve legacy `@username` entries to IDs. -- `channels.telegram.groups`: per-group defaults + allowlist (use `"*"` for global defaults). - - `channels.telegram.groups..groupPolicy`: per-group override for groupPolicy (`open | allowlist | disabled`). - - `channels.telegram.groups..requireMention`: mention gating default. - - `channels.telegram.groups..skills`: skill filter (omit = all skills, empty = none). - - `channels.telegram.groups..allowFrom`: per-group sender allowlist override. - - `channels.telegram.groups..systemPrompt`: extra system prompt for the group. - - `channels.telegram.groups..enabled`: disable the group when `false`. - - `channels.telegram.groups..topics..*`: per-topic overrides (same fields as group). - - `channels.telegram.groups..topics..groupPolicy`: per-topic override for groupPolicy (`open | allowlist | disabled`). - - `channels.telegram.groups..topics..requireMention`: per-topic mention gating override. -- `channels.telegram.capabilities.inlineButtons`: `off | dm | group | all | allowlist` (default: allowlist). -- `channels.telegram.accounts..capabilities.inlineButtons`: per-account override. -- `channels.telegram.replyToMode`: `off | first | all` (default: `off`). -- `channels.telegram.textChunkLimit`: outbound chunk size (chars). -- `channels.telegram.chunkMode`: `length` (default) or `newline` to split on blank lines (paragraph boundaries) before length chunking. -- `channels.telegram.linkPreview`: toggle link previews for outbound messages (default: true). -- `channels.telegram.streamMode`: `off | partial | block` (live stream preview). -- `channels.telegram.mediaMaxMb`: inbound/outbound media cap (MB). -- `channels.telegram.retry`: retry policy for outbound Telegram API calls (attempts, minDelayMs, maxDelayMs, jitter). -- `channels.telegram.network.autoSelectFamily`: override Node autoSelectFamily (true=enable, false=disable). Defaults to disabled on Node 22 to avoid Happy Eyeballs timeouts. -- `channels.telegram.proxy`: proxy URL for Bot API calls (SOCKS/HTTP). -- `channels.telegram.webhookUrl`: enable webhook mode (requires `channels.telegram.webhookSecret`). -- `channels.telegram.webhookSecret`: webhook secret (required when webhookUrl is set). -- `channels.telegram.webhookPath`: local webhook path (default `/telegram-webhook`). -- `channels.telegram.webhookHost`: local webhook bind host (default `127.0.0.1`). -- `channels.telegram.actions.reactions`: gate Telegram tool reactions. -- `channels.telegram.actions.sendMessage`: gate Telegram tool message sends. -- `channels.telegram.actions.deleteMessage`: gate Telegram tool message deletes. -- `channels.telegram.actions.sticker`: gate Telegram sticker actions — send and search (default: false). -- `channels.telegram.reactionNotifications`: `off | own | all` — control which reactions trigger system events (default: `own` when not set). -- `channels.telegram.reactionLevel`: `off | ack | minimal | extensive` — control agent's reaction capability (default: `minimal` when not set). - -- [Configuration reference - Telegram](/gateway/configuration-reference#telegram) - -Telegram-specific high-signal fields: - -- startup/auth: `enabled`, `botToken`, `tokenFile`, `accounts.*` -- access control: `dmPolicy`, `allowFrom`, `groupPolicy`, `groupAllowFrom`, `groups`, `groups.*.topics.*` -- command/menu: `commands.native`, `customCommands` -- threading/replies: `replyToMode` -- streaming: `streamMode` (preview), `draftChunk`, `blockStreaming` -- formatting/delivery: `textChunkLimit`, `chunkMode`, `linkPreview`, `responsePrefix` -- media/network: `mediaMaxMb`, `timeoutSeconds`, `retry`, `network.autoSelectFamily`, `proxy` -- webhook: `webhookUrl`, `webhookSecret`, `webhookPath`, `webhookHost` -- actions/capabilities: `capabilities.inlineButtons`, `actions.sendMessage|editMessage|deleteMessage|reactions|sticker` -- reactions: `reactionNotifications`, `reactionLevel` -- writes/history: `configWrites`, `historyLimit`, `dmHistoryLimit`, `dms.*.historyLimit` - -## Related - -- [Pairing](/channels/pairing) -- [Channel routing](/channels/channel-routing) -- [Multi-agent routing](/concepts/multi-agent) -- [Troubleshooting](/channels/troubleshooting) diff --git a/docs/channels/tlon.md b/docs/channels/tlon.md deleted file mode 100644 index dbd2015c4e..0000000000 --- a/docs/channels/tlon.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -summary: "Tlon/Urbit support status, capabilities, and configuration" -read_when: - - Working on Tlon/Urbit channel features -title: "Tlon" ---- - -# Tlon (plugin) - -Tlon is a decentralized messenger built on Urbit. OpenClaw connects to your Urbit ship and can -respond to DMs and group chat messages. Group replies require an @ mention by default and can -be further restricted via allowlists. - -Status: supported via plugin. DMs, group mentions, thread replies, and text-only media fallback -(URL appended to caption). Reactions, polls, and native media uploads are not supported. - -## Plugin required - -Tlon ships as a plugin and is not bundled with the core install. - -Install via CLI (npm registry): - -```bash -openclaw plugins install @openclaw/tlon -``` - -Local checkout (when running from a git repo): - -```bash -openclaw plugins install ./extensions/tlon -``` - -Details: [Plugins](/tools/plugin) - -## Setup - -1. Install the Tlon plugin. -2. Gather your ship URL and login code. -3. Configure `channels.tlon`. -4. Restart the gateway. -5. DM the bot or mention it in a group channel. - -Minimal config (single account): - -```json5 -{ - channels: { - tlon: { - enabled: true, - ship: "~sampel-palnet", - url: "https://your-ship-host", - code: "lidlut-tabwed-pillex-ridrup", - }, - }, -} -``` - -Private/LAN ship URLs (advanced): - -By default, OpenClaw blocks private/internal hostnames and IP ranges for this plugin (SSRF hardening). -If your ship URL is on a private network (for example `http://192.168.1.50:8080` or `http://localhost:8080`), -you must explicitly opt in: - -```json5 -{ - channels: { - tlon: { - allowPrivateNetwork: true, - }, - }, -} -``` - -## Group channels - -Auto-discovery is enabled by default. You can also pin channels manually: - -```json5 -{ - channels: { - tlon: { - groupChannels: ["chat/~host-ship/general", "chat/~host-ship/support"], - }, - }, -} -``` - -Disable auto-discovery: - -```json5 -{ - channels: { - tlon: { - autoDiscoverChannels: false, - }, - }, -} -``` - -## Access control - -DM allowlist (empty = allow all): - -```json5 -{ - channels: { - tlon: { - dmAllowlist: ["~zod", "~nec"], - }, - }, -} -``` - -Group authorization (restricted by default): - -```json5 -{ - channels: { - tlon: { - defaultAuthorizedShips: ["~zod"], - authorization: { - channelRules: { - "chat/~host-ship/general": { - mode: "restricted", - allowedShips: ["~zod", "~nec"], - }, - "chat/~host-ship/announcements": { - mode: "open", - }, - }, - }, - }, - }, -} -``` - -## Delivery targets (CLI/cron) - -Use these with `openclaw message send` or cron delivery: - -- DM: `~sampel-palnet` or `dm/~sampel-palnet` -- Group: `chat/~host-ship/channel` or `group:~host-ship/channel` - -## Notes - -- Group replies require a mention (e.g. `~your-bot-ship`) to respond. -- Thread replies: if the inbound message is in a thread, OpenClaw replies in-thread. -- Media: `sendMedia` falls back to text + URL (no native upload). diff --git a/docs/channels/troubleshooting.md b/docs/channels/troubleshooting.md deleted file mode 100644 index 2848947c47..0000000000 --- a/docs/channels/troubleshooting.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -summary: "Fast channel level troubleshooting with per channel failure signatures and fixes" -read_when: - - Channel transport says connected but replies fail - - You need channel specific checks before deep provider docs -title: "Channel Troubleshooting" ---- - -# Channel troubleshooting - -Use this page when a channel connects but behavior is wrong. - -## Command ladder - -Run these in order first: - -```bash -openclaw status -openclaw gateway status -openclaw logs --follow -openclaw doctor -openclaw channels status --probe -``` - -Healthy baseline: - -- `Runtime: running` -- `RPC probe: ok` -- Channel probe shows connected/ready - -## WhatsApp - -### WhatsApp failure signatures - -| Symptom | Fastest check | Fix | -| ------------------------------- | --------------------------------------------------- | ------------------------------------------------------- | -| Connected but no DM replies | `openclaw pairing list whatsapp` | Approve sender or switch DM policy/allowlist. | -| Group messages ignored | Check `requireMention` + mention patterns in config | Mention the bot or relax mention policy for that group. | -| Random disconnect/relogin loops | `openclaw channels status --probe` + logs | Re-login and verify credentials directory is healthy. | - -Full troubleshooting: [/channels/whatsapp#troubleshooting-quick](/channels/whatsapp#troubleshooting-quick) - -## Telegram - -### Telegram failure signatures - -| Symptom | Fastest check | Fix | -| --------------------------------- | ----------------------------------------------- | --------------------------------------------------------------------------- | -| `/start` but no usable reply flow | `openclaw pairing list telegram` | Approve pairing or change DM policy. | -| Bot online but group stays silent | Verify mention requirement and bot privacy mode | Disable privacy mode for group visibility or mention bot. | -| Send failures with network errors | Inspect logs for Telegram API call failures | Fix DNS/IPv6/proxy routing to `api.telegram.org`. | -| Upgraded and allowlist blocks you | `openclaw security audit` and config allowlists | Run `openclaw doctor --fix` or replace `@username` with numeric sender IDs. | - -Full troubleshooting: [/channels/telegram#troubleshooting](/channels/telegram#troubleshooting) - -## Discord - -### Discord failure signatures - -| Symptom | Fastest check | Fix | -| ------------------------------- | ----------------------------------- | --------------------------------------------------------- | -| Bot online but no guild replies | `openclaw channels status --probe` | Allow guild/channel and verify message content intent. | -| Group messages ignored | Check logs for mention gating drops | Mention bot or set guild/channel `requireMention: false`. | -| DM replies missing | `openclaw pairing list discord` | Approve DM pairing or adjust DM policy. | - -Full troubleshooting: [/channels/discord#troubleshooting](/channels/discord#troubleshooting) - -## Slack - -### Slack failure signatures - -| Symptom | Fastest check | Fix | -| -------------------------------------- | ----------------------------------------- | ------------------------------------------------- | -| Socket mode connected but no responses | `openclaw channels status --probe` | Verify app token + bot token and required scopes. | -| DMs blocked | `openclaw pairing list slack` | Approve pairing or relax DM policy. | -| Channel message ignored | Check `groupPolicy` and channel allowlist | Allow the channel or switch policy to `open`. | - -Full troubleshooting: [/channels/slack#troubleshooting](/channels/slack#troubleshooting) - -## iMessage and BlueBubbles - -### iMessage and BlueBubbles failure signatures - -| Symptom | Fastest check | Fix | -| -------------------------------- | ----------------------------------------------------------------------- | ----------------------------------------------------- | -| No inbound events | Verify webhook/server reachability and app permissions | Fix webhook URL or BlueBubbles server state. | -| Can send but no receive on macOS | Check macOS privacy permissions for Messages automation | Re-grant TCC permissions and restart channel process. | -| DM sender blocked | `openclaw pairing list imessage` or `openclaw pairing list bluebubbles` | Approve pairing or update allowlist. | - -Full troubleshooting: - -- [/channels/imessage#troubleshooting-macos-privacy-and-security-tcc](/channels/imessage#troubleshooting-macos-privacy-and-security-tcc) -- [/channels/bluebubbles#troubleshooting](/channels/bluebubbles#troubleshooting) - -## Signal - -### Signal failure signatures - -| Symptom | Fastest check | Fix | -| ------------------------------- | ------------------------------------------ | -------------------------------------------------------- | -| Daemon reachable but bot silent | `openclaw channels status --probe` | Verify `signal-cli` daemon URL/account and receive mode. | -| DM blocked | `openclaw pairing list signal` | Approve sender or adjust DM policy. | -| Group replies do not trigger | Check group allowlist and mention patterns | Add sender/group or loosen gating. | - -Full troubleshooting: [/channels/signal#troubleshooting](/channels/signal#troubleshooting) - -## Matrix - -### Matrix failure signatures - -| Symptom | Fastest check | Fix | -| ----------------------------------- | -------------------------------------------- | ----------------------------------------------- | -| Logged in but ignores room messages | `openclaw channels status --probe` | Check `groupPolicy` and room allowlist. | -| DMs do not process | `openclaw pairing list matrix` | Approve sender or adjust DM policy. | -| Encrypted rooms fail | Verify crypto module and encryption settings | Enable encryption support and rejoin/sync room. | - -Full troubleshooting: [/channels/matrix#troubleshooting](/channels/matrix#troubleshooting) diff --git a/docs/channels/twitch.md b/docs/channels/twitch.md deleted file mode 100644 index 32670f3154..0000000000 --- a/docs/channels/twitch.md +++ /dev/null @@ -1,379 +0,0 @@ ---- -summary: "Twitch chat bot configuration and setup" -read_when: - - Setting up Twitch chat integration for OpenClaw -title: "Twitch" ---- - -# Twitch (plugin) - -Twitch chat support via IRC connection. OpenClaw connects as a Twitch user (bot account) to receive and send messages in channels. - -## Plugin required - -Twitch ships as a plugin and is not bundled with the core install. - -Install via CLI (npm registry): - -```bash -openclaw plugins install @openclaw/twitch -``` - -Local checkout (when running from a git repo): - -```bash -openclaw plugins install ./extensions/twitch -``` - -Details: [Plugins](/tools/plugin) - -## Quick setup (beginner) - -1. Create a dedicated Twitch account for the bot (or use an existing account). -2. Generate credentials: [Twitch Token Generator](https://twitchtokengenerator.com/) - - Select **Bot Token** - - Verify scopes `chat:read` and `chat:write` are selected - - Copy the **Client ID** and **Access Token** -3. Find your Twitch user ID: [https://www.streamweasels.com/tools/convert-twitch-username-to-user-id/](https://www.streamweasels.com/tools/convert-twitch-username-to-user-id/) -4. Configure the token: - - Env: `OPENCLAW_TWITCH_ACCESS_TOKEN=...` (default account only) - - Or config: `channels.twitch.accessToken` - - If both are set, config takes precedence (env fallback is default-account only). -5. Start the gateway. - -**⚠️ Important:** Add access control (`allowFrom` or `allowedRoles`) to prevent unauthorized users from triggering the bot. `requireMention` defaults to `true`. - -Minimal config: - -```json5 -{ - channels: { - twitch: { - enabled: true, - username: "openclaw", // Bot's Twitch account - accessToken: "oauth:abc123...", // OAuth Access Token (or use OPENCLAW_TWITCH_ACCESS_TOKEN env var) - clientId: "xyz789...", // Client ID from Token Generator - channel: "vevisk", // Which Twitch channel's chat to join (required) - allowFrom: ["123456789"], // (recommended) Your Twitch user ID only - get it from https://www.streamweasels.com/tools/convert-twitch-username-to-user-id/ - }, - }, -} -``` - -## What it is - -- A Twitch channel owned by the Gateway. -- Deterministic routing: replies always go back to Twitch. -- Each account maps to an isolated session key `agent::twitch:`. -- `username` is the bot's account (who authenticates), `channel` is which chat room to join. - -## Setup (detailed) - -### Generate credentials - -Use [Twitch Token Generator](https://twitchtokengenerator.com/): - -- Select **Bot Token** -- Verify scopes `chat:read` and `chat:write` are selected -- Copy the **Client ID** and **Access Token** - -No manual app registration needed. Tokens expire after several hours. - -### Configure the bot - -**Env var (default account only):** - -```bash -OPENCLAW_TWITCH_ACCESS_TOKEN=oauth:abc123... -``` - -**Or config:** - -```json5 -{ - channels: { - twitch: { - enabled: true, - username: "openclaw", - accessToken: "oauth:abc123...", - clientId: "xyz789...", - channel: "vevisk", - }, - }, -} -``` - -If both env and config are set, config takes precedence. - -### Access control (recommended) - -```json5 -{ - channels: { - twitch: { - allowFrom: ["123456789"], // (recommended) Your Twitch user ID only - }, - }, -} -``` - -Prefer `allowFrom` for a hard allowlist. Use `allowedRoles` instead if you want role-based access. - -**Available roles:** `"moderator"`, `"owner"`, `"vip"`, `"subscriber"`, `"all"`. - -**Why user IDs?** Usernames can change, allowing impersonation. User IDs are permanent. - -Find your Twitch user ID: [https://www.streamweasels.com/tools/convert-twitch-username-%20to-user-id/](https://www.streamweasels.com/tools/convert-twitch-username-%20to-user-id/) (Convert your Twitch username to ID) - -## Token refresh (optional) - -Tokens from [Twitch Token Generator](https://twitchtokengenerator.com/) cannot be automatically refreshed - regenerate when expired. - -For automatic token refresh, create your own Twitch application at [Twitch Developer Console](https://dev.twitch.tv/console) and add to config: - -```json5 -{ - channels: { - twitch: { - clientSecret: "your_client_secret", - refreshToken: "your_refresh_token", - }, - }, -} -``` - -The bot automatically refreshes tokens before expiration and logs refresh events. - -## Multi-account support - -Use `channels.twitch.accounts` with per-account tokens. See [`gateway/configuration`](/gateway/configuration) for the shared pattern. - -Example (one bot account in two channels): - -```json5 -{ - channels: { - twitch: { - accounts: { - channel1: { - username: "openclaw", - accessToken: "oauth:abc123...", - clientId: "xyz789...", - channel: "vevisk", - }, - channel2: { - username: "openclaw", - accessToken: "oauth:def456...", - clientId: "uvw012...", - channel: "secondchannel", - }, - }, - }, - }, -} -``` - -**Note:** Each account needs its own token (one token per channel). - -## Access control - -### Role-based restrictions - -```json5 -{ - channels: { - twitch: { - accounts: { - default: { - allowedRoles: ["moderator", "vip"], - }, - }, - }, - }, -} -``` - -### Allowlist by User ID (most secure) - -```json5 -{ - channels: { - twitch: { - accounts: { - default: { - allowFrom: ["123456789", "987654321"], - }, - }, - }, - }, -} -``` - -### Role-based access (alternative) - -`allowFrom` is a hard allowlist. When set, only those user IDs are allowed. -If you want role-based access, leave `allowFrom` unset and configure `allowedRoles` instead: - -```json5 -{ - channels: { - twitch: { - accounts: { - default: { - allowedRoles: ["moderator"], - }, - }, - }, - }, -} -``` - -### Disable @mention requirement - -By default, `requireMention` is `true`. To disable and respond to all messages: - -```json5 -{ - channels: { - twitch: { - accounts: { - default: { - requireMention: false, - }, - }, - }, - }, -} -``` - -## Troubleshooting - -First, run diagnostic commands: - -```bash -openclaw doctor -openclaw channels status --probe -``` - -### Bot doesn't respond to messages - -**Check access control:** Ensure your user ID is in `allowFrom`, or temporarily remove -`allowFrom` and set `allowedRoles: ["all"]` to test. - -**Check the bot is in the channel:** The bot must join the channel specified in `channel`. - -### Token issues - -**"Failed to connect" or authentication errors:** - -- Verify `accessToken` is the OAuth access token value (typically starts with `oauth:` prefix) -- Check token has `chat:read` and `chat:write` scopes -- If using token refresh, verify `clientSecret` and `refreshToken` are set - -### Token refresh not working - -**Check logs for refresh events:** - -``` -Using env token source for mybot -Access token refreshed for user 123456 (expires in 14400s) -``` - -If you see "token refresh disabled (no refresh token)": - -- Ensure `clientSecret` is provided -- Ensure `refreshToken` is provided - -## Config - -**Account config:** - -- `username` - Bot username -- `accessToken` - OAuth access token with `chat:read` and `chat:write` -- `clientId` - Twitch Client ID (from Token Generator or your app) -- `channel` - Channel to join (required) -- `enabled` - Enable this account (default: `true`) -- `clientSecret` - Optional: For automatic token refresh -- `refreshToken` - Optional: For automatic token refresh -- `expiresIn` - Token expiry in seconds -- `obtainmentTimestamp` - Token obtained timestamp -- `allowFrom` - User ID allowlist -- `allowedRoles` - Role-based access control (`"moderator" | "owner" | "vip" | "subscriber" | "all"`) -- `requireMention` - Require @mention (default: `true`) - -**Provider options:** - -- `channels.twitch.enabled` - Enable/disable channel startup -- `channels.twitch.username` - Bot username (simplified single-account config) -- `channels.twitch.accessToken` - OAuth access token (simplified single-account config) -- `channels.twitch.clientId` - Twitch Client ID (simplified single-account config) -- `channels.twitch.channel` - Channel to join (simplified single-account config) -- `channels.twitch.accounts.` - Multi-account config (all account fields above) - -Full example: - -```json5 -{ - channels: { - twitch: { - enabled: true, - username: "openclaw", - accessToken: "oauth:abc123...", - clientId: "xyz789...", - channel: "vevisk", - clientSecret: "secret123...", - refreshToken: "refresh456...", - allowFrom: ["123456789"], - allowedRoles: ["moderator", "vip"], - accounts: { - default: { - username: "mybot", - accessToken: "oauth:abc123...", - clientId: "xyz789...", - channel: "your_channel", - enabled: true, - clientSecret: "secret123...", - refreshToken: "refresh456...", - expiresIn: 14400, - obtainmentTimestamp: 1706092800000, - allowFrom: ["123456789", "987654321"], - allowedRoles: ["moderator"], - }, - }, - }, - }, -} -``` - -## Tool actions - -The agent can call `twitch` with action: - -- `send` - Send a message to a channel - -Example: - -```json5 -{ - action: "twitch", - params: { - message: "Hello Twitch!", - to: "#mychannel", - }, -} -``` - -## Safety & ops - -- **Treat tokens like passwords** - Never commit tokens to git -- **Use automatic token refresh** for long-running bots -- **Use user ID allowlists** instead of usernames for access control -- **Monitor logs** for token refresh events and connection status -- **Scope tokens minimally** - Only request `chat:read` and `chat:write` -- **If stuck**: Restart the gateway after confirming no other process owns the session - -## Limits - -- **500 characters** per message (auto-chunked at word boundaries) -- Markdown is stripped before chunking -- No rate limiting (uses Twitch's built-in rate limits) diff --git a/docs/channels/whatsapp.md b/docs/channels/whatsapp.md deleted file mode 100644 index a6fb427bdc..0000000000 --- a/docs/channels/whatsapp.md +++ /dev/null @@ -1,444 +0,0 @@ ---- -summary: "WhatsApp channel support, access controls, delivery behavior, and operations" -read_when: - - Working on WhatsApp/web channel behavior or inbox routing -title: "WhatsApp" ---- - -# WhatsApp (Web channel) - -Status: production-ready via WhatsApp Web (Baileys). Gateway owns linked session(s). - - - - Default DM policy is pairing for unknown senders. - - - Cross-channel diagnostics and repair playbooks. - - - Full channel config patterns and examples. - - - -## Quick setup - - - - -```json5 -{ - channels: { - whatsapp: { - dmPolicy: "pairing", - allowFrom: ["+15551234567"], - groupPolicy: "allowlist", - groupAllowFrom: ["+15551234567"], - }, - }, -} -``` - - - - - -```bash -openclaw channels login --channel whatsapp -``` - - For a specific account: - -```bash -openclaw channels login --channel whatsapp --account work -``` - - - - - -```bash -openclaw gateway -``` - - - - - -```bash -openclaw pairing list whatsapp -openclaw pairing approve whatsapp -``` - - Pairing requests expire after 1 hour. Pending requests are capped at 3 per channel. - - - - - -OpenClaw recommends running WhatsApp on a separate number when possible. (The channel metadata and onboarding flow are optimized for that setup, but personal-number setups are also supported.) - - -## Deployment patterns - - - - This is the cleanest operational mode: - - - separate WhatsApp identity for OpenClaw - - clearer DM allowlists and routing boundaries - - lower chance of self-chat confusion - - Minimal policy pattern: - - ```json5 - { - channels: { - whatsapp: { - dmPolicy: "allowlist", - allowFrom: ["+15551234567"], - }, - }, - } - ``` - - - - - Onboarding supports personal-number mode and writes a self-chat-friendly baseline: - - - `dmPolicy: "allowlist"` - - `allowFrom` includes your personal number - - `selfChatMode: true` - - In runtime, self-chat protections key off the linked self number and `allowFrom`. - - - - - The messaging platform channel is WhatsApp Web-based (`Baileys`) in current OpenClaw channel architecture. - - There is no separate Twilio WhatsApp messaging channel in the built-in chat-channel registry. - - - - -## Runtime model - -- Gateway owns the WhatsApp socket and reconnect loop. -- Outbound sends require an active WhatsApp listener for the target account. -- Status and broadcast chats are ignored (`@status`, `@broadcast`). -- Direct chats use DM session rules (`session.dmScope`; default `main` collapses DMs to the agent main session). -- Group sessions are isolated (`agent::whatsapp:group:`). - -## Access control and activation - - - - `channels.whatsapp.dmPolicy` controls direct chat access: - - - `pairing` (default) - - `allowlist` - - `open` (requires `allowFrom` to include `"*"`) - - `disabled` - - `allowFrom` accepts E.164-style numbers (normalized internally). - - Multi-account override: `channels.whatsapp.accounts..dmPolicy` (and `allowFrom`) take precedence over channel-level defaults for that account. - - Runtime behavior details: - - - pairings are persisted in channel allow-store and merged with configured `allowFrom` - - if no allowlist is configured, the linked self number is allowed by default - - outbound `fromMe` DMs are never auto-paired - - - - - Group access has two layers: - - 1. **Group membership allowlist** (`channels.whatsapp.groups`) - - if `groups` is omitted, all groups are eligible - - if `groups` is present, it acts as a group allowlist (`"*"` allowed) - - 2. **Group sender policy** (`channels.whatsapp.groupPolicy` + `groupAllowFrom`) - - `open`: sender allowlist bypassed - - `allowlist`: sender must match `groupAllowFrom` (or `*`) - - `disabled`: block all group inbound - - Sender allowlist fallback: - - - if `groupAllowFrom` is unset, runtime falls back to `allowFrom` when available - - sender allowlists are evaluated before mention/reply activation - - Note: if no `channels.whatsapp` block exists at all, runtime group-policy fallback is effectively `open`. - - - - - Group replies require mention by default. - - Mention detection includes: - - - explicit WhatsApp mentions of the bot identity - - configured mention regex patterns (`agents.list[].groupChat.mentionPatterns`, fallback `messages.groupChat.mentionPatterns`) - - implicit reply-to-bot detection (reply sender matches bot identity) - - Security note: - - - quote/reply only satisfies mention gating; it does **not** grant sender authorization - - with `groupPolicy: "allowlist"`, non-allowlisted senders are still blocked even if they reply to an allowlisted user's message - - Session-level activation command: - - - `/activation mention` - - `/activation always` - - `activation` updates session state (not global config). It is owner-gated. - - - - -## Personal-number and self-chat behavior - -When the linked self number is also present in `allowFrom`, WhatsApp self-chat safeguards activate: - -- skip read receipts for self-chat turns -- ignore mention-JID auto-trigger behavior that would otherwise ping yourself -- if `messages.responsePrefix` is unset, self-chat replies default to `[{identity.name}]` or `[openclaw]` - -## Message normalization and context - - - - Incoming WhatsApp messages are wrapped in the shared inbound envelope. - - If a quoted reply exists, context is appended in this form: - - ```text - [Replying to id:] - - [/Replying] - ``` - - Reply metadata fields are also populated when available (`ReplyToId`, `ReplyToBody`, `ReplyToSender`, sender JID/E.164). - - - - - Media-only inbound messages are normalized with placeholders such as: - - - `` - - `` - - `` - - `` - - `` - - Location and contact payloads are normalized into textual context before routing. - - - - - For groups, unprocessed messages can be buffered and injected as context when the bot is finally triggered. - - - default limit: `50` - - config: `channels.whatsapp.historyLimit` - - fallback: `messages.groupChat.historyLimit` - - `0` disables - - Injection markers: - - - `[Chat messages since your last reply - for context]` - - `[Current message - respond to this]` - - - - - Read receipts are enabled by default for accepted inbound WhatsApp messages. - - Disable globally: - - ```json5 - { - channels: { - whatsapp: { - sendReadReceipts: false, - }, - }, - } - ``` - - Per-account override: - - ```json5 - { - channels: { - whatsapp: { - accounts: { - work: { - sendReadReceipts: false, - }, - }, - }, - }, - } - ``` - - Self-chat turns skip read receipts even when globally enabled. - - - - -## Delivery, chunking, and media - - - - - default chunk limit: `channels.whatsapp.textChunkLimit = 4000` - - `channels.whatsapp.chunkMode = "length" | "newline"` - - `newline` mode prefers paragraph boundaries (blank lines), then falls back to length-safe chunking - - - - - supports image, video, audio (PTT voice-note), and document payloads - - `audio/ogg` is rewritten to `audio/ogg; codecs=opus` for voice-note compatibility - - animated GIF playback is supported via `gifPlayback: true` on video sends - - captions are applied to the first media item when sending multi-media reply payloads - - media source can be HTTP(S), `file://`, or local paths - - - - - inbound media save cap: `channels.whatsapp.mediaMaxMb` (default `50`) - - outbound media cap for auto-replies: `agents.defaults.mediaMaxMb` (default `5MB`) - - images are auto-optimized (resize/quality sweep) to fit limits - - on media send failure, first-item fallback sends text warning instead of dropping the response silently - - - -## Acknowledgment reactions - -WhatsApp supports immediate ack reactions on inbound receipt via `channels.whatsapp.ackReaction`. - -```json5 -{ - channels: { - whatsapp: { - ackReaction: { - emoji: "👀", - direct: true, - group: "mentions", // always | mentions | never - }, - }, - }, -} -``` - -Behavior notes: - -- sent immediately after inbound is accepted (pre-reply) -- failures are logged but do not block normal reply delivery -- group mode `mentions` reacts on mention-triggered turns; group activation `always` acts as bypass for this check -- WhatsApp uses `channels.whatsapp.ackReaction` (legacy `messages.ackReaction` is not used here) - -## Multi-account and credentials - - - - - account ids come from `channels.whatsapp.accounts` - - default account selection: `default` if present, otherwise first configured account id (sorted) - - account ids are normalized internally for lookup - - - - - current auth path: `~/.openclaw/credentials/whatsapp//creds.json` - - backup file: `creds.json.bak` - - legacy default auth in `~/.openclaw/credentials/` is still recognized/migrated for default-account flows - - - - `openclaw channels logout --channel whatsapp [--account ]` clears WhatsApp auth state for that account. - - In legacy auth directories, `oauth.json` is preserved while Baileys auth files are removed. - - - - -## Tools, actions, and config writes - -- Agent tool support includes WhatsApp reaction action (`react`). -- Action gates: - - `channels.whatsapp.actions.reactions` - - `channels.whatsapp.actions.polls` -- Channel-initiated config writes are enabled by default (disable via `channels.whatsapp.configWrites=false`). - -## Troubleshooting - - - - Symptom: channel status reports not linked. - - Fix: - - ```bash - openclaw channels login --channel whatsapp - openclaw channels status - ``` - - - - - Symptom: linked account with repeated disconnects or reconnect attempts. - - Fix: - - ```bash - openclaw doctor - openclaw logs --follow - ``` - - If needed, re-link with `channels login`. - - - - - Outbound sends fail fast when no active gateway listener exists for the target account. - - Make sure gateway is running and the account is linked. - - - - - Check in this order: - - - `groupPolicy` - - `groupAllowFrom` / `allowFrom` - - `groups` allowlist entries - - mention gating (`requireMention` + mention patterns) - - duplicate keys in `openclaw.json` (JSON5): later entries override earlier ones, so keep a single `groupPolicy` per scope - - - - - WhatsApp gateway runtime should use Node. Bun is flagged as incompatible for stable WhatsApp/Telegram gateway operation. - - - -## Configuration reference pointers - -Primary reference: - -- [Configuration reference - WhatsApp](/gateway/configuration-reference#whatsapp) - -High-signal WhatsApp fields: - -- access: `dmPolicy`, `allowFrom`, `groupPolicy`, `groupAllowFrom`, `groups` -- delivery: `textChunkLimit`, `chunkMode`, `mediaMaxMb`, `sendReadReceipts`, `ackReaction` -- multi-account: `accounts..enabled`, `accounts..authDir`, account-level overrides -- operations: `configWrites`, `debounceMs`, `web.enabled`, `web.heartbeatSeconds`, `web.reconnect.*` -- session behavior: `session.dmScope`, `historyLimit`, `dmHistoryLimit`, `dms..historyLimit` - -## Related - -- [Pairing](/channels/pairing) -- [Channel routing](/channels/channel-routing) -- [Multi-agent routing](/concepts/multi-agent) -- [Troubleshooting](/channels/troubleshooting) diff --git a/docs/channels/zalo.md b/docs/channels/zalo.md deleted file mode 100644 index cda126f564..0000000000 --- a/docs/channels/zalo.md +++ /dev/null @@ -1,192 +0,0 @@ ---- -summary: "Zalo bot support status, capabilities, and configuration" -read_when: - - Working on Zalo features or webhooks -title: "Zalo" ---- - -# Zalo (Bot API) - -Status: experimental. Direct messages only; groups coming soon per Zalo docs. - -## Plugin required - -Zalo ships as a plugin and is not bundled with the core install. - -- Install via CLI: `openclaw plugins install @openclaw/zalo` -- Or select **Zalo** during onboarding and confirm the install prompt -- Details: [Plugins](/tools/plugin) - -## Quick setup (beginner) - -1. Install the Zalo plugin: - - From a source checkout: `openclaw plugins install ./extensions/zalo` - - From npm (if published): `openclaw plugins install @openclaw/zalo` - - Or pick **Zalo** in onboarding and confirm the install prompt -2. Set the token: - - Env: `ZALO_BOT_TOKEN=...` - - Or config: `channels.zalo.botToken: "..."`. -3. Restart the gateway (or finish onboarding). -4. DM access is pairing by default; approve the pairing code on first contact. - -Minimal config: - -```json5 -{ - channels: { - zalo: { - enabled: true, - botToken: "12345689:abc-xyz", - dmPolicy: "pairing", - }, - }, -} -``` - -## What it is - -Zalo is a Vietnam-focused messaging app; its Bot API lets the Gateway run a bot for 1:1 conversations. -It is a good fit for support or notifications where you want deterministic routing back to Zalo. - -- A Zalo Bot API channel owned by the Gateway. -- Deterministic routing: replies go back to Zalo; the model never chooses channels. -- DMs share the agent's main session. -- Groups are not yet supported (Zalo docs state "coming soon"). - -## Setup (fast path) - -### 1) Create a bot token (Zalo Bot Platform) - -1. Go to [https://bot.zaloplatforms.com](https://bot.zaloplatforms.com) and sign in. -2. Create a new bot and configure its settings. -3. Copy the bot token (format: `12345689:abc-xyz`). - -### 2) Configure the token (env or config) - -Example: - -```json5 -{ - channels: { - zalo: { - enabled: true, - botToken: "12345689:abc-xyz", - dmPolicy: "pairing", - }, - }, -} -``` - -Env option: `ZALO_BOT_TOKEN=...` (works for the default account only). - -Multi-account support: use `channels.zalo.accounts` with per-account tokens and optional `name`. - -3. Restart the gateway. Zalo starts when a token is resolved (env or config). -4. DM access defaults to pairing. Approve the code when the bot is first contacted. - -## How it works (behavior) - -- Inbound messages are normalized into the shared channel envelope with media placeholders. -- Replies always route back to the same Zalo chat. -- Long-polling by default; webhook mode available with `channels.zalo.webhookUrl`. - -## Limits - -- Outbound text is chunked to 2000 characters (Zalo API limit). -- Media downloads/uploads are capped by `channels.zalo.mediaMaxMb` (default 5). -- Streaming is blocked by default due to the 2000 char limit making streaming less useful. - -## Access control (DMs) - -### DM access - -- Default: `channels.zalo.dmPolicy = "pairing"`. Unknown senders receive a pairing code; messages are ignored until approved (codes expire after 1 hour). -- Approve via: - - `openclaw pairing list zalo` - - `openclaw pairing approve zalo ` -- Pairing is the default token exchange. Details: [Pairing](/channels/pairing) -- `channels.zalo.allowFrom` accepts numeric user IDs (no username lookup available). - -## Long-polling vs webhook - -- Default: long-polling (no public URL required). -- Webhook mode: set `channels.zalo.webhookUrl` and `channels.zalo.webhookSecret`. - - The webhook secret must be 8-256 characters. - - Webhook URL must use HTTPS. - - Zalo sends events with `X-Bot-Api-Secret-Token` header for verification. - - Gateway HTTP handles webhook requests at `channels.zalo.webhookPath` (defaults to the webhook URL path). - - Requests must use `Content-Type: application/json` (or `+json` media types). - - Duplicate events (`event_name + message_id`) are ignored for a short replay window. - - Burst traffic is rate-limited per path/source and may return HTTP 429. - -**Note:** getUpdates (polling) and webhook are mutually exclusive per Zalo API docs. - -## Supported message types - -- **Text messages**: Full support with 2000 character chunking. -- **Image messages**: Download and process inbound images; send images via `sendPhoto`. -- **Stickers**: Logged but not fully processed (no agent response). -- **Unsupported types**: Logged (e.g., messages from protected users). - -## Capabilities - -| Feature | Status | -| --------------- | ------------------------------ | -| Direct messages | ✅ Supported | -| Groups | ❌ Coming soon (per Zalo docs) | -| Media (images) | ✅ Supported | -| Reactions | ❌ Not supported | -| Threads | ❌ Not supported | -| Polls | ❌ Not supported | -| Native commands | ❌ Not supported | -| Streaming | ⚠️ Blocked (2000 char limit) | - -## Delivery targets (CLI/cron) - -- Use a chat id as the target. -- Example: `openclaw message send --channel zalo --target 123456789 --message "hi"`. - -## Troubleshooting - -**Bot doesn't respond:** - -- Check that the token is valid: `openclaw channels status --probe` -- Verify the sender is approved (pairing or allowFrom) -- Check gateway logs: `openclaw logs --follow` - -**Webhook not receiving events:** - -- Ensure webhook URL uses HTTPS -- Verify secret token is 8-256 characters -- Confirm the gateway HTTP endpoint is reachable on the configured path -- Check that getUpdates polling is not running (they're mutually exclusive) - -## Configuration reference (Zalo) - -Full configuration: [Configuration](/gateway/configuration) - -Provider options: - -- `channels.zalo.enabled`: enable/disable channel startup. -- `channels.zalo.botToken`: bot token from Zalo Bot Platform. -- `channels.zalo.tokenFile`: read token from file path. -- `channels.zalo.dmPolicy`: `pairing | allowlist | open | disabled` (default: pairing). -- `channels.zalo.allowFrom`: DM allowlist (user IDs). `open` requires `"*"`. The wizard will ask for numeric IDs. -- `channels.zalo.mediaMaxMb`: inbound/outbound media cap (MB, default 5). -- `channels.zalo.webhookUrl`: enable webhook mode (HTTPS required). -- `channels.zalo.webhookSecret`: webhook secret (8-256 chars). -- `channels.zalo.webhookPath`: webhook path on the gateway HTTP server. -- `channels.zalo.proxy`: proxy URL for API requests. - -Multi-account options: - -- `channels.zalo.accounts..botToken`: per-account token. -- `channels.zalo.accounts..tokenFile`: per-account token file. -- `channels.zalo.accounts..name`: display name. -- `channels.zalo.accounts..enabled`: enable/disable account. -- `channels.zalo.accounts..dmPolicy`: per-account DM policy. -- `channels.zalo.accounts..allowFrom`: per-account allowlist. -- `channels.zalo.accounts..webhookUrl`: per-account webhook URL. -- `channels.zalo.accounts..webhookSecret`: per-account webhook secret. -- `channels.zalo.accounts..webhookPath`: per-account webhook path. -- `channels.zalo.accounts..proxy`: per-account proxy URL. diff --git a/docs/channels/zalouser.md b/docs/channels/zalouser.md deleted file mode 100644 index e93e71a6f7..0000000000 --- a/docs/channels/zalouser.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -summary: "Zalo personal account support via zca-cli (QR login), capabilities, and configuration" -read_when: - - Setting up Zalo Personal for OpenClaw - - Debugging Zalo Personal login or message flow -title: "Zalo Personal" ---- - -# Zalo Personal (unofficial) - -Status: experimental. This integration automates a **personal Zalo account** via `zca-cli`. - -> **Warning:** This is an unofficial integration and may result in account suspension/ban. Use at your own risk. - -## Plugin required - -Zalo Personal ships as a plugin and is not bundled with the core install. - -- Install via CLI: `openclaw plugins install @openclaw/zalouser` -- Or from a source checkout: `openclaw plugins install ./extensions/zalouser` -- Details: [Plugins](/tools/plugin) - -## Prerequisite: zca-cli - -The Gateway machine must have the `zca` binary available in `PATH`. - -- Verify: `zca --version` -- If missing, install zca-cli (see `extensions/zalouser/README.md` or the upstream zca-cli docs). - -## Quick setup (beginner) - -1. Install the plugin (see above). -2. Login (QR, on the Gateway machine): - - `openclaw channels login --channel zalouser` - - Scan the QR code in the terminal with the Zalo mobile app. -3. Enable the channel: - -```json5 -{ - channels: { - zalouser: { - enabled: true, - dmPolicy: "pairing", - }, - }, -} -``` - -4. Restart the Gateway (or finish onboarding). -5. DM access defaults to pairing; approve the pairing code on first contact. - -## What it is - -- Uses `zca listen` to receive inbound messages. -- Uses `zca msg ...` to send replies (text/media/link). -- Designed for “personal account” use cases where Zalo Bot API is not available. - -## Naming - -Channel id is `zalouser` to make it explicit this automates a **personal Zalo user account** (unofficial). We keep `zalo` reserved for a potential future official Zalo API integration. - -## Finding IDs (directory) - -Use the directory CLI to discover peers/groups and their IDs: - -```bash -openclaw directory self --channel zalouser -openclaw directory peers list --channel zalouser --query "name" -openclaw directory groups list --channel zalouser --query "work" -``` - -## Limits - -- Outbound text is chunked to ~2000 characters (Zalo client limits). -- Streaming is blocked by default. - -## Access control (DMs) - -`channels.zalouser.dmPolicy` supports: `pairing | allowlist | open | disabled` (default: `pairing`). -`channels.zalouser.allowFrom` accepts user IDs or names. The wizard resolves names to IDs via `zca friend find` when available. - -Approve via: - -- `openclaw pairing list zalouser` -- `openclaw pairing approve zalouser ` - -## Group access (optional) - -- Default: `channels.zalouser.groupPolicy = "open"` (groups allowed). Use `channels.defaults.groupPolicy` to override the default when unset. -- Restrict to an allowlist with: - - `channels.zalouser.groupPolicy = "allowlist"` - - `channels.zalouser.groups` (keys are group IDs or names) -- Block all groups: `channels.zalouser.groupPolicy = "disabled"`. -- The configure wizard can prompt for group allowlists. -- On startup, OpenClaw resolves group/user names in allowlists to IDs and logs the mapping; unresolved entries are kept as typed. - -Example: - -```json5 -{ - channels: { - zalouser: { - groupPolicy: "allowlist", - groups: { - "123456789": { allow: true }, - "Work Chat": { allow: true }, - }, - }, - }, -} -``` - -## Multi-account - -Accounts map to zca profiles. Example: - -```json5 -{ - channels: { - zalouser: { - enabled: true, - defaultAccount: "default", - accounts: { - work: { enabled: true, profile: "work" }, - }, - }, - }, -} -``` - -## Troubleshooting - -**`zca` not found:** - -- Install zca-cli and ensure it’s on `PATH` for the Gateway process. - -**Login doesn’t stick:** - -- `openclaw channels status --probe` -- Re-login: `openclaw channels logout --channel zalouser && openclaw channels login --channel zalouser` diff --git a/docs/ci.md b/docs/ci.md deleted file mode 100644 index 64d4df0ec1..0000000000 --- a/docs/ci.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: CI Pipeline -description: How the OpenClaw CI pipeline works ---- - -# CI Pipeline - -The CI runs on every push to `main` and every pull request. It uses smart scoping to skip expensive jobs when only docs or native code changed. - -## Job Overview - -| Job | Purpose | When it runs | -| ----------------- | ----------------------------------------------- | ------------------------- | -| `docs-scope` | Detect docs-only changes | Always | -| `changed-scope` | Detect which areas changed (node/macos/android) | Non-docs PRs | -| `check` | TypeScript types, lint, format | Non-docs changes | -| `check-docs` | Markdown lint + broken link check | Docs changed | -| `code-analysis` | LOC threshold check (1000 lines) | PRs only | -| `secrets` | Detect leaked secrets | Always | -| `build-artifacts` | Build dist once, share with other jobs | Non-docs, node changes | -| `release-check` | Validate npm pack contents | After build | -| `checks` | Node/Bun tests + protocol check | Non-docs, node changes | -| `checks-windows` | Windows-specific tests | Non-docs, node changes | -| `macos` | Swift lint/build/test + TS tests | PRs with macos changes | -| `android` | Gradle build + tests | Non-docs, android changes | - -## Fail-Fast Order - -Jobs are ordered so cheap checks fail before expensive ones run: - -1. `docs-scope` + `code-analysis` + `check` (parallel, ~1-2 min) -2. `build-artifacts` (blocked on above) -3. `checks`, `checks-windows`, `macos`, `android` (blocked on build) - -## Runners - -| Runner | Jobs | -| -------------------------------- | ------------------------------------------ | -| `blacksmith-16vcpu-ubuntu-2404` | Most Linux jobs, including scope detection | -| `blacksmith-16vcpu-windows-2025` | `checks-windows` | -| `macos-latest` | `macos`, `ios` | - -## Local Equivalents - -```bash -pnpm check # types + lint + format -pnpm test # vitest tests -pnpm check:docs # docs format + lint + broken links -pnpm release:check # validate npm pack -``` diff --git a/docs/cli/acp.md b/docs/cli/acp.md deleted file mode 100644 index 9535509016..0000000000 --- a/docs/cli/acp.md +++ /dev/null @@ -1,182 +0,0 @@ ---- -summary: "Run the ACP bridge for IDE integrations" -read_when: - - Setting up ACP-based IDE integrations - - Debugging ACP session routing to the Gateway -title: "acp" ---- - -# acp - -Run the ACP (Agent Client Protocol) bridge that talks to a OpenClaw Gateway. - -This command speaks ACP over stdio for IDEs and forwards prompts to the Gateway -over WebSocket. It keeps ACP sessions mapped to Gateway session keys. - -## Usage - -```bash -openclaw acp - -# Remote Gateway -openclaw acp --url wss://gateway-host:18789 --token - -# Remote Gateway (token from file) -openclaw acp --url wss://gateway-host:18789 --token-file ~/.openclaw/gateway.token - -# Attach to an existing session key -openclaw acp --session agent:main:main - -# Attach by label (must already exist) -openclaw acp --session-label "support inbox" - -# Reset the session key before the first prompt -openclaw acp --session agent:main:main --reset-session -``` - -## ACP client (debug) - -Use the built-in ACP client to sanity-check the bridge without an IDE. -It spawns the ACP bridge and lets you type prompts interactively. - -```bash -openclaw acp client - -# Point the spawned bridge at a remote Gateway -openclaw acp client --server-args --url wss://gateway-host:18789 --token-file ~/.openclaw/gateway.token - -# Override the server command (default: openclaw) -openclaw acp client --server "node" --server-args openclaw.mjs acp --url ws://127.0.0.1:19001 -``` - -## How to use this - -Use ACP when an IDE (or other client) speaks Agent Client Protocol and you want -it to drive a OpenClaw Gateway session. - -1. Ensure the Gateway is running (local or remote). -2. Configure the Gateway target (config or flags). -3. Point your IDE to run `openclaw acp` over stdio. - -Example config (persisted): - -```bash -openclaw config set gateway.remote.url wss://gateway-host:18789 -openclaw config set gateway.remote.token -``` - -Example direct run (no config write): - -```bash -openclaw acp --url wss://gateway-host:18789 --token -# preferred for local process safety -openclaw acp --url wss://gateway-host:18789 --token-file ~/.openclaw/gateway.token -``` - -## Selecting agents - -ACP does not pick agents directly. It routes by the Gateway session key. - -Use agent-scoped session keys to target a specific agent: - -```bash -openclaw acp --session agent:main:main -openclaw acp --session agent:design:main -openclaw acp --session agent:qa:bug-123 -``` - -Each ACP session maps to a single Gateway session key. One agent can have many -sessions; ACP defaults to an isolated `acp:` session unless you override -the key or label. - -## Zed editor setup - -Add a custom ACP agent in `~/.config/zed/settings.json` (or use Zed’s Settings UI): - -```json -{ - "agent_servers": { - "OpenClaw ACP": { - "type": "custom", - "command": "openclaw", - "args": ["acp"], - "env": {} - } - } -} -``` - -To target a specific Gateway or agent: - -```json -{ - "agent_servers": { - "OpenClaw ACP": { - "type": "custom", - "command": "openclaw", - "args": [ - "acp", - "--url", - "wss://gateway-host:18789", - "--token", - "", - "--session", - "agent:design:main" - ], - "env": {} - } - } -} -``` - -In Zed, open the Agent panel and select “OpenClaw ACP” to start a thread. - -## Session mapping - -By default, ACP sessions get an isolated Gateway session key with an `acp:` prefix. -To reuse a known session, pass a session key or label: - -- `--session `: use a specific Gateway session key. -- `--session-label