From 3b8d7b2e429e5ccba9fa556bb4e08dce645d5a11 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sat, 21 Feb 2026 01:33:45 -0500 Subject: [PATCH 1/5] deps: remove dead root dependency (#22471) * chore(deadcode): add deadcode scanning and remove unused lockfile deps * chore(changelog): mention deadcode CI scan pass * ci: disable deadcode job temporarily * docs(changelog): add PR ref and thanks for deadcode scan entry * ci: comment out deadcode job condition while keeping it disabled * Deps: remove dead root dependency from package manifest * Changelog: reference PR for deadcode dependency cleanup * Deps: remove unused root signal-utils --- CHANGELOG.md | 2 ++ package.json | 2 -- pnpm-lock.yaml | 15 --------------- 3 files changed, 2 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c14b5633f05..7fa00498481 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ Docs: https://docs.openclaw.ai ### Changes - Dev tooling: add dead-code scans to CI via Knip/ts-prune/ts-unused-exports and report unused dependencies/exports in non-blocking checks. (#22468) Thanks @vincentkoc. +- Dev tooling: move `@larksuiteoapi/node-sdk` out of root `package.json` and keep it scoped to `extensions/feishu` where it is used. (#22471) Thanks @vincentkoc. +- Dev tooling: remove unused root dependency `signal-utils` from core manifest after confirming it was only used by extension-only paths. (#22471) Thanks @vincentkoc. - Agents/Subagents: default subagent spawn depth now uses shared `maxSpawnDepth=2`, enabling depth-1 orchestrator spawning by default while keeping depth policy checks consistent across spawn and prompt paths. (#22223) Thanks @tyler6204. - Channels/CLI: add per-account/channel `defaultTo` outbound routing fallback so `openclaw agent --deliver` can send without explicit `--reply-to` when a default target is configured. (#16985) Thanks @KirillShchetinin. - iOS/Chat: clean chat UI noise by stripping inbound untrusted metadata/timestamp prefixes, formatting tool outputs into concise summaries/errors, compacting the composer while typing, and supporting tap-to-dismiss keyboard in chat view. (#22122) thanks @mbelinky. diff --git a/package.json b/package.json index bc820ac11e9..939d3509fc4 100644 --- a/package.json +++ b/package.json @@ -145,7 +145,6 @@ "@grammyjs/runner": "^2.0.3", "@grammyjs/transformer-throttler": "^1.2.1", "@homebridge/ciao": "^1.3.5", - "@larksuiteoapi/node-sdk": "^1.59.0", "@line/bot-sdk": "^10.6.0", "@lydell/node-pty": "1.2.0-beta.3", "@mariozechner/pi-agent-core": "0.54.0", @@ -182,7 +181,6 @@ "playwright-core": "1.58.2", "qrcode-terminal": "^0.12.0", "sharp": "^0.34.5", - "signal-utils": "^0.21.1", "sqlite-vec": "0.1.7-alpha.2", "tar": "7.5.9", "tslog": "^4.10.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 48853b996ce..84d6011d0d2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,9 +47,6 @@ importers: '@homebridge/ciao': specifier: ^1.3.5 version: 1.3.5 - '@larksuiteoapi/node-sdk': - specifier: ^1.59.0 - version: 1.59.0 '@line/bot-sdk': specifier: ^10.6.0 version: 10.6.0 @@ -164,9 +161,6 @@ importers: sharp: specifier: ^0.34.5 version: 0.34.5 - signal-utils: - specifier: ^0.21.1 - version: 0.21.1(signal-polyfill@0.2.2) sqlite-vec: specifier: 0.1.7-alpha.2 version: 0.1.7-alpha.2 @@ -5396,11 +5390,6 @@ packages: signal-polyfill@0.2.2: resolution: {integrity: sha512-p63Y4Er5/eMQ9RHg0M0Y64NlsQKpiu6MDdhBXpyywRuWiPywhJTpKJ1iB5K2hJEbFZ0BnDS7ZkJ+0AfTuL37Rg==} - signal-utils@0.21.1: - resolution: {integrity: sha512-i9cdLSvVH4j8ql8mz2lyrA93xL499P8wEbIev3ldSriXeUwqh+wM4Q5VPhIZ19gPtIS4BOopJuKB8l1+wH9LCg==} - peerDependencies: - signal-polyfill: ^0.2.0 - simple-git@3.31.1: resolution: {integrity: sha512-oiWP4Q9+kO8q9hHqkX35uuHmxiEbZNTrZ5IPxgMGrJwN76pzjm/jabkZO0ItEcqxAincqGAzL3QHSaHt4+knBg==} @@ -11660,10 +11649,6 @@ snapshots: signal-polyfill@0.2.2: {} - signal-utils@0.21.1(signal-polyfill@0.2.2): - dependencies: - signal-polyfill: 0.2.2 - simple-git@3.31.1: dependencies: '@kwsites/file-exists': 1.1.1 From 3002be76e482048a03f7d329cefc566f2ac49bef Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sat, 21 Feb 2026 01:35:35 -0500 Subject: [PATCH 2/5] docs: add custom spellcheck dictionary and fix docs typos (#22457) * docs: fix typos and add docs spellcheck workflow * docs: add changelog entry for docs spellcheck updates * docs: fix FAQ TOC fragment links for markdownlint * docs: fix TOC nesting and spellcheck dictionary flags --- .github/workflows/ci.yml | 6 +++++- CHANGELOG.md | 1 + docs/help/faq.md | 26 +++++++++++++------------- package.json | 2 ++ scripts/codespell-dictionary.txt | 3 +++ scripts/codespell-ignore.txt | 2 ++ 6 files changed, 26 insertions(+), 14 deletions(-) create mode 100644 scripts/codespell-dictionary.txt create mode 100644 scripts/codespell-ignore.txt diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index abb5b50a5ce..16c9cbeb09d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -259,6 +259,7 @@ jobs: - name: Check types and lint and oxfmt run: pnpm check + # Report-only dead-code scans. Runs after scope detection and stores machine-readable # results as artifacts for later triage before we enable hard gates. # Temporarily disabled in CI while we process initial findings. @@ -298,7 +299,7 @@ jobs: name: dead-code-${{ matrix.tool }}-${{ github.run_id }} path: .artifacts/deadcode - # Validate docs (format, lint, broken links) only when docs files changed. + # Validate docs (spellcheck, format, lint, broken links) only when docs files changed. check-docs: needs: [docs-scope] if: needs.docs-scope.outputs.docs_changed == 'true' @@ -317,6 +318,9 @@ jobs: - name: Check docs run: pnpm check:docs + - name: Spellcheck docs + run: pnpm docs:spellcheck + secrets: runs-on: blacksmith-16vcpu-ubuntu-2404 steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fa00498481..271ae8fc06f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Docs: https://docs.openclaw.ai ### Changes +- Docs: fix FAQ typos and add documentation spellcheck automation with a custom codespell dictionary/ignore list, including CI coverage. (#22457) Thanks @vincentkoc. - Dev tooling: add dead-code scans to CI via Knip/ts-prune/ts-unused-exports and report unused dependencies/exports in non-blocking checks. (#22468) Thanks @vincentkoc. - Dev tooling: move `@larksuiteoapi/node-sdk` out of root `package.json` and keep it scoped to `extensions/feishu` where it is used. (#22471) Thanks @vincentkoc. - Dev tooling: remove unused root dependency `signal-utils` from core manifest after confirming it was only used by extension-only paths. (#22471) Thanks @vincentkoc. diff --git a/docs/help/faq.md b/docs/help/faq.md index 053e7bbb4a9..9e61b595724 100644 --- a/docs/help/faq.md +++ b/docs/help/faq.md @@ -10,7 +10,7 @@ Quick answers plus deeper troubleshooting for real-world setups (local dev, VPS, ## Table of contents - [Quick start and first-run setup] - - [Im stuck whats the fastest way to get unstuck?](#im-stuck-whats-the-fastest-way-to-get-unstuck) + - [Im stuck what's the fastest way to get unstuck?](#im-stuck-whats-the-fastest-way-to-get-unstuck) - [What's the recommended way to install and set up OpenClaw?](#whats-the-recommended-way-to-install-and-set-up-openclaw) - [How do I open the dashboard after onboarding?](#how-do-i-open-the-dashboard-after-onboarding) - [How do I authenticate the dashboard (token) on localhost vs remote?](#how-do-i-authenticate-the-dashboard-token-on-localhost-vs-remote) @@ -126,7 +126,7 @@ Quick answers plus deeper troubleshooting for real-world setups (local dev, VPS, - [Why did context get truncated mid-task? How do I prevent it?](#why-did-context-get-truncated-midtask-how-do-i-prevent-it) - [How do I completely reset OpenClaw but keep it installed?](#how-do-i-completely-reset-openclaw-but-keep-it-installed) - [I'm getting "context too large" errors - how do I reset or compact?](#im-getting-context-too-large-errors-how-do-i-reset-or-compact) - - [Why am I seeing "LLM request rejected: messages.N.content.X.tool_use.input: Field required"?](#why-am-i-seeing-llm-request-rejected-messagesncontentxtooluseinput-field-required) + - [Why am I seeing "LLM request rejected: messages.content.tool_use.input field required"?](#why-am-i-seeing-llm-request-rejected-messagescontenttool_useinput-field-required) - [Why am I getting heartbeat messages every 30 minutes?](#why-am-i-getting-heartbeat-messages-every-30-minutes) - [Do I need to add a "bot account" to a WhatsApp group?](#do-i-need-to-add-a-bot-account-to-a-whatsapp-group) - [How do I get the JID of a WhatsApp group?](#how-do-i-get-the-jid-of-a-whatsapp-group) @@ -262,7 +262,7 @@ Quick answers plus deeper troubleshooting for real-world setups (local dev, VPS, ## Quick start and first-run setup -### Im stuck whats the fastest way to get unstuck +### Im stuck what's the fastest way to get unstuck Use a local AI agent that can **see your machine**. That is far more effective than asking in Discord, because most "I'm stuck" cases are **local config or environment issues** that @@ -440,7 +440,7 @@ Newest entries are at the top. If the top section is marked **Unreleased**, the section is the latest shipped version. Entries are grouped by **Highlights**, **Changes**, and **Fixes** (plus docs/other sections when needed). -### I cant access docs.openclaw.ai SSL error What now +### I can't access docs.openclaw.ai SSL error What now Some Comcast/Xfinity connections incorrectly block `docs.openclaw.ai` via Xfinity Advanced Security. Disable it or allowlist `docs.openclaw.ai`, then retry. More @@ -464,7 +464,7 @@ that same version to `latest`**. That's why beta and stable can point at the See what changed: [https://github.com/openclaw/openclaw/blob/main/CHANGELOG.md](https://github.com/openclaw/openclaw/blob/main/CHANGELOG.md) -### How do I install the beta version and whats the difference between beta and dev +### How do I install the beta version and what's the difference between beta and dev **Beta** is the npm dist-tag `beta` (may match `latest`). **Dev** is the moving head of `main` (git); when published, it uses the npm dist-tag `dev`. @@ -581,7 +581,7 @@ Two common Windows issues: If you want the smoothest Windows setup, use **WSL2** instead of native Windows. Docs: [Windows](/platforms/windows). -### The docs didnt answer my question how do I get a better answer +### The docs didn't answer my question how do I get a better answer Use the **hackable (git) install** so you have the full source and docs locally, then ask your bot (or Claude/Codex) _from that folder_ so it can read the repo and answer precisely. @@ -1839,7 +1839,7 @@ If it keeps happening: Docs: [Compaction](/concepts/compaction), [Session pruning](/concepts/session-pruning), [Session management](/concepts/session). -### Why am I seeing LLM request rejected messagesNcontentXtooluseinput Field required +### Why am I seeing "LLM request rejected: messages.content.tool_use.input field required"? This is a provider validation error: the model emitted a `tool_use` block without the required `input`. It usually means the session history is stale or corrupted (often after long threads @@ -1906,7 +1906,7 @@ openclaw directory groups list --channel whatsapp Docs: [WhatsApp](/channels/whatsapp), [Directory](/cli/directory), [Logs](/cli/logs). -### Why doesnt OpenClaw reply in a group +### Why doesn't OpenClaw reply in a group Two common causes: @@ -1915,7 +1915,7 @@ Two common causes: See [Groups](/channels/groups) and [Group messages](/channels/group-messages). -### Do groupsthreads share context with DMs +### Do groups/threads share context with DMs Direct chats collapse to the main session by default. Groups/channels have their own session keys, and Telegram topics / Discord threads are separate sessions. See [Groups](/channels/groups) and [Group messages](/channels/group-messages). @@ -2335,7 +2335,7 @@ To target a specific agent: openclaw models auth order set --provider anthropic --agent main anthropic:default ``` -### OAuth vs API key whats the difference +### OAuth vs API key what's the difference OpenClaw supports both: @@ -2423,7 +2423,7 @@ Fix: - In the Control UI settings, paste the same token. - Still stuck? Run `openclaw status --all` and follow [Troubleshooting](/gateway/troubleshooting). See [Dashboard](/web/dashboard) for auth details. -### I set gatewaybind tailnet but it cant bind nothing listens +### I set gatewaybind tailnet but it can't bind nothing listens `tailnet` bind picks a Tailscale IP from your network interfaces (100.64.0.0/10). If the machine isn't on Tailscale (or the interface is down), there's nothing to bind to. @@ -2506,7 +2506,7 @@ Service/supervisor logs (when the gateway runs via launchd/systemd): See [Troubleshooting](/gateway/troubleshooting#log-locations) for more. -### How do I startstoprestart the Gateway service +### How do I start/stop/restart the Gateway service Use the gateway helpers: @@ -2732,7 +2732,7 @@ more susceptible to instruction hijacking, so avoid them for tool-enabled agents or when reading untrusted content. If you must use a smaller model, lock down tools and run inside a sandbox. See [Security](/gateway/security). -### I ran start in Telegram but didnt get a pairing code +### I ran start in Telegram but didn't get a pairing code Pairing codes are sent **only** when an unknown sender messages the bot and `dmPolicy: "pairing"` is enabled. `/start` by itself doesn't generate a code. diff --git a/package.json b/package.json index 939d3509fc4..68031a1d5d9 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,8 @@ "docs:check-links": "node scripts/docs-link-audit.mjs", "docs:dev": "cd docs && mint dev", "docs:list": "node scripts/docs-list.js", + "docs:spellcheck": "if command -v codespell >/dev/null 2>&1; then codespell README.md docs --skip='*.png,*.jpg,*.jpeg,*.gif,*.svg' -D - -D scripts/codespell-dictionary.txt -I scripts/codespell-ignore.txt; else pnpm dlx codespell README.md docs --skip='*.png,*.jpg,*.jpeg,*.gif,*.svg' -D - -D scripts/codespell-dictionary.txt -I scripts/codespell-ignore.txt; fi", + "docs:spellcheck:fix": "if command -v codespell >/dev/null 2>&1; then codespell README.md docs --skip='*.png,*.jpg,*.jpeg,*.gif,*.svg' -D - -D scripts/codespell-dictionary.txt -I scripts/codespell-ignore.txt -w; else pnpm dlx codespell README.md docs --skip='*.png,*.jpg,*.jpeg,*.gif,*.svg' -D - -D scripts/codespell-dictionary.txt -I scripts/codespell-ignore.txt -w; fi", "format": "oxfmt --write", "format:all": "pnpm format && pnpm format:swift", "format:check": "oxfmt --check", diff --git a/scripts/codespell-dictionary.txt b/scripts/codespell-dictionary.txt new file mode 100644 index 00000000000..e887ea81d14 --- /dev/null +++ b/scripts/codespell-dictionary.txt @@ -0,0 +1,3 @@ +messagesNcontentXtooluseinput->messages.content.tool_use.input +groupsthreads->groups/threads +startstoprestart->start/stop/restart diff --git a/scripts/codespell-ignore.txt b/scripts/codespell-ignore.txt new file mode 100644 index 00000000000..b7008d3eabf --- /dev/null +++ b/scripts/codespell-ignore.txt @@ -0,0 +1,2 @@ +iTerm +FO From c2f56289153c7cb1387b26353fc2e44fd89081a5 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sat, 21 Feb 2026 01:37:02 -0500 Subject: [PATCH 3/5] Fix formatting (#22474) --- .../tools/web-tools.enabled-defaults.e2e.test.ts | 4 +++- src/security/external-content.ts | 10 ++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/agents/tools/web-tools.enabled-defaults.e2e.test.ts b/src/agents/tools/web-tools.enabled-defaults.e2e.test.ts index cb6dc4969ac..ff28dbf1103 100644 --- a/src/agents/tools/web-tools.enabled-defaults.e2e.test.ts +++ b/src/agents/tools/web-tools.enabled-defaults.e2e.test.ts @@ -269,7 +269,9 @@ describe("web_search external content wrapping", () => { results?: Array<{ description?: string }>; }; - expect(details.results?.[0]?.description).toMatch(/<<>>/); + expect(details.results?.[0]?.description).toMatch( + /<<>>/, + ); expect(details.results?.[0]?.description).toContain("Ignore previous instructions"); expect(details.externalContent).toMatchObject({ untrusted: true, diff --git a/src/security/external-content.ts b/src/security/external-content.ts index 7b6e4313a50..49629db9aef 100644 --- a/src/security/external-content.ts +++ b/src/security/external-content.ts @@ -148,8 +148,14 @@ function replaceMarkers(content: string): string { const replacements: Array<{ start: number; end: number; value: string }> = []; // Match markers with or without id attribute (handles both legacy and spoofed markers) const patterns: Array<{ regex: RegExp; value: string }> = [ - { regex: /<<>>/gi, value: "[[MARKER_SANITIZED]]" }, - { regex: /<<>>/gi, value: "[[END_MARKER_SANITIZED]]" }, + { + regex: /<<>>/gi, + value: "[[MARKER_SANITIZED]]", + }, + { + regex: /<<>>/gi, + value: "[[END_MARKER_SANITIZED]]", + }, ]; for (const pattern of patterns) { From 7428f5a7411f4f2bbd60dad6e22f60f4e6cefde5 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sat, 21 Feb 2026 01:43:18 -0500 Subject: [PATCH 4/5] chore: format files for oxfmt (#22479) From 35fd322114d39de1562ea04a7c4d164d16ca6ee8 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sat, 21 Feb 2026 01:46:55 -0500 Subject: [PATCH 5/5] chore: format CI workflow (#22482) * chore: format files for oxfmt * chore: format CI workflow