Release 3.1.4: OpenClaw 2026.6.8 + provider compatibility + Telegram pairing#217
Conversation
β¦yout (#199) * docs: pin supported platform to JetPack 6.2 and document the install layout Field report (from-scratch install on a fresh NVIDIA image): NVIDIA now steers downloads to JetPack 7 / Ubuntu 24.04, where the installer fails on PEP 668 (externally-managed pip) -- and the bare `sudo bash install.sh` quickstart says nothing about the expected clone location, so running from a personal user's checkout crashes on the hardcoded /home/clawbox/clawbox paths. Pin JetPack 6.2 explicitly (with download link and a 24.04 warning) and document the supported clone-as-clawbox recipe. * docs: fail fast on real useradd errors in the quickstart recipe CodeRabbit finding: '|| true' swallowed genuine useradd failures, letting the later clone/install steps fail somewhere less obvious. Only skip creation when the user already exists.
Move the fleet from 2026.6.1 to 2026.6.6. Validated on a Jetson device: core + both auth-bypass patches + ClawBox AI and Codex (ARM @openclaw/codex 2026.6.6) chat all work; the codex plugin realigns to the bumped pin on the next gateway start. Fresh installs and the updater both read this pin.
) * fix(openai): stop Codex subscription OAuth corrupting the id token The OpenAI subscription OAuth flows ran an id_token -> openai-api-key token exchange and stored the resulting sk- key as the codex profile's `access`. gateway-pre-start then synthesized ~/.codex/auth.json with `id_token: p.id || p.access` -> the API key string, which the Codex app-server rejects with 'failed to set external auth: invalid ID token format'. Because ~/.codex/auth.json is shared and rebuilt every gateway start, the bad credential also poisoned the API-key OpenAI provider and survived re-auth. - device-poll (device-code flow): drop the api-key exchange; return the raw OAuth JWTs (access_token + id_token + refresh_token). - oauth/exchange (redirect flow): same change, so both completion paths are consistent and the bug isn't left latent on the redirect path. - configure: persist the id_token as the profile's `id` so the synthesis writes a valid JWT id_token (and a JWT access_token, fixing account_id resolution that split `access` on '.'). - AIModelsStep: forward id_token from the OAuth result to configure. Validated on a device: a fresh Codex device-code login now stores a JWT access + id, synthesizes a valid ~/.codex/auth.json, and OpenAI accepts the credential (invalid-ID-token replaced by the account's normal rate-limit). * test(openai): update OAuth tests to the no-api-key-exchange behavior The Codex OAuth fix removed the id_token->api-key exchange, so the tests that asserted that (now-removed) behavior were failing. Replace them with tests that assert the new contract: the OpenAI exchange/device-poll routes return the raw OAuth JWTs incl. id_token and make no second (api-key) request. * fix(openai): reject non-JWT Codex subscription credentials at configure time Addresses CodeRabbit review on #201: the configure route accepted a client-supplied idToken but still wrote the codex oauth profile when neither idToken nor access was JWT-shaped β which the gateway's id->access synthesis fallback could turn back into an invalid id_token. Reject codex subscription saves with a 502 unless the id_token (or access, trimmed) is JWT-like, and store the trimmed id_token. Updates the subscription configure test to use JWT-shaped credentials.
β¦ns detect CI (#207) The e2e-install harness entrypoint seeds /etc/clawbox/test-mode.env (CLAWBOX_TEST_MODE=1 + NETWORK_INTERFACE=eth0) before any install.sh runs, expecting install.sh to read it ("so install.sh knows it's in test mode even before it writes its own .env"). But install.sh only read CLAWBOX_TEST_MODE from its process env, so updater-triggered `install.sh --step` runs via clawbox-root-update@.service β which inherit only /etc/clawbox/network.env, populated late during step_network_setup β ran with CLAWBOX_TEST_MODE=0. They then executed the real Jetson/WiFi steps (iw dev eth0, nvpmodel, jetson_clocks) and failed on the non-Tegra CI host, intermittently breaking e2e-install. Source the seeded marker at startup so every invocation (bootstrap and updater-triggered) detects test mode up front. The file exists only in the CI container, so this is a no-op on real devices.
β¦rminal (#208) ClawBox had no CLI updater (only OpenClaw does), so the only way to update was the Settings UI β which gives no visibility when a step fails (issue #202). `clawbox update` re-runs install.sh in place: the same complete path the Update button drives (git-sync to the pinned code, system packages, OpenClaw at the pinned version, gateway config, rebuild), but straight in the terminal with live output so owners can watch each step and see exactly where it fails. It shells out via sudo; CLAWBOX_ROOT overrides the install location.
A Telegram bot set up on an older OpenClaw can carry a
channels.telegram.groupPolicy value the current schema rejects (allowed:
open, disabled, allowlist). A single invalid value invalidates the entire
openclaw.json, so the gateway loads nothing and the bot stays connected but
never replies β surfaced as 'OpenClaw config is invalid β¦ groupPolicy: must
be equal to one of the allowed values'.
gateway-pre-start.sh already strips the legacy dmPolicy/allowFrom keys from
channels.telegram on every start; extend that same block to reset an unknown
groupPolicy to the secure default ('disabled' β ClawBox has no group-chat
UI; owner DMs are unaffected) so affected devices self-heal on restart.
#205) A flat agents.defaults.compaction.reserveTokensFloor of 24000 suits large-context cloud models but swallows most of Ollama's 32K window, leaving ~8.7K of usable input β less than the agent's ~20K-token system prompt + tool schemas. Every local-model turn then fails before the model runs ("context overflow" / unrecoverable auto-compaction). Size the reserve to the active model's context window β a quarter, clamped to [4096, 24000]: Ollama 32768 -> 8192, llama.cpp/cloud keep 24000. Validated on a 2026.6.6 device (reserve 8000 -> the Ollama model responds); 85/85 affected tests green on-device.
On Jetson, Gemma 4 (llama.cpp) runs at its full 131K context while the 3B Ollama models are RAM-capped at 32K β too tight for the agent's heavy system prompt β so Gemma is the only local engine that performs well. Make it the sole local option, folded into the existing AI Provider step (cloud-first, "go local from here") rather than a separate wizard step. - AI Provider step + Settings -> Local AI: Gemma is offered alongside the cloud providers; Ollama is hidden (its provider def, panel, hooks and routes are left intact, so re-enabling is a one-line revert). - Gemma is promoted up-front (PRIMARY_PROVIDER_IDS) and carries a "Fully local" badge instead of "Recommended" (which stays on ClawBox AI). - i18n: ai.fullyLocal across all 10 locales. Validated on a 2026.6.6 device: 55/55 affected tests green.
β¦209) * feat: approve Telegram pairing codes from Settings Add a "User access" section to Settings -> Telegram so the owner can approve who may chat with the bot without a terminal: - paste an 8-char pairing code, or load pending requests and approve with one click (openclaw pairing list/approve telegram --json/--notify) - --notify makes OpenClaw confirm to the user automatically - show currently approved senders, read from the credentials allowFrom store New /setup-api/telegram/pairing route + helpers in openclaw-config.ts; i18n for all 10 locales; unit + route tests. * refactor: share one spawnOpenclaw helper for the openclaw CLI Extract the spawn/timeout/error machinery duplicated between config-set and the new pairing CLI calls into a single spawnOpenclaw(args, {captureStdout}); export the shared PAIRING_CODE_RE so the route stops re-declaring it. * feat: desktop popup for new Telegram access requests with inline approve When a new person DMs the bot, a corner popup now appears on the desktop (even with Settings closed) showing the requester with Approve / Open / Dismiss. A fast file-read endpoint (?poll=1) backs a 20s poller; de-dup via localStorage. Also corrects the pending-request shape to OpenClaw's real {code,id,meta} (was guessed userId/username).
β¦-only merge (#211) step_git_pull used `git merge --ff-only || echo continuing with current code`, which silently kept stale code whenever the box had any local divergence β so config/openclaw-target.txt, OpenClaw, and the gateway stayed pinned to the old version (#202). The bootstrap + step also defaulted the branch to main, force-pulling a beta box toward main. Route both through the robust helpers the in-app updater already uses: - resolve_update_branch honors an explicit CLAWBOX_BRANCH first, then .update-branch, then the current branch, then main. - The bootstrap resolves the branch the same way (inline, validated) instead of defaulting to main. - step_git_pull hard-syncs via resolve_update_branch + sync_repo_to_update_target (fetch + reset --hard) instead of the ff-only merge. Refs #202.
* feat(telegram): show the requester's name in pairing UI
Pending popup + Settings pending list now show the sender's Telegram display name (meta.name) instead of just the numeric id (the field was mis-guessed as meta.username before). For the Approved users list, capture meta.name at approval time and remember it in an id->name map in config-store (OpenClaw's allowlist stores ids only); GET now returns approved as {id, name?}. Already-approved ids stay as ids until re-approved.
* feat(telegram): reset allowlist on new bot token + live-refresh approved list
- configure: when the bot token actually changes, wipe OpenClaw's allowlist/pending stores (new clearTelegramPairingState) + the ClawBox name map, so a new bot starts fresh. Re-saving the same token keeps approvals.
- popup/Settings: dispatch a clawbox:telegram-approved event on approve; both the desktop popup and the Settings list listen and update live, so an approval reflects immediately without a manual refresh.
* fix(telegram): refresh approved/pending lists after a reconfigure resets the allowlist
* fix(telegram): read the sender name from meta.firstName/lastName
The real pending-request meta on the device is { firstName, accountId } β not { name } (that was from a different channel's source). Capture + display now use firstName (+ lastName), so the approver's name actually shows.
* refactor(telegram): derive the sender name once at the read boundary
Per /simplify: the firstName/lastName -> name join was duplicated in the route + both UIs. listTelegramPairingRequests/readTelegramPairingRequests now attach a derived name; the route and components just read req.name.
β¦ compat) (#214) OpenRouter/anthropic/openai/google chats failed with '401 Missing Authentication header' on OpenClaw 2026.6.8. ClawBox wrote their auth as type:"token" profiles (and OpenRouter's provider apiKey as the placeholder "openrouter-ref"); 2026.6.6 resolved those, but 2026.6.8 reworked auth resolution and no longer turns a token-mode profile into an Authorization header, nor resolves the placeholder β it sends models.providers.*.apiKey verbatim. Write the same type:"api_key" shape the working providers (clawai/ollama/llamacpp) use, and inline OpenRouter's real key. Verified end-to-end on device against 2026.6.8.
β¦26.6.8 (#215) * fix: route google through OpenAI-compat endpoint so Gemini runs on 2026.6.8 OpenClaw's native google plugin registers Gemini models but fails auth at call time on 2026.6.8 β chats silently fall back to the fallback model with reason=auth. Configure google the same way ClawBox already handles OpenRouter: an openai-completions provider pointed at Google's /v1beta/openai endpoint with the key inline, so the gateway actually authenticates the call. - configure: add isGoogle branch writing models.providers.google (openai-compat, inline key, seeded from GOOGLE_MODELS). - chat/model: generalize the models.providers auto-extend from openrouter-only to openrouter+google (google is now an openai-completions provider too, so a picked model not in the seed needs registering β same quirk as openrouter). - provider-models: add gemini-3.5-flash + gemini-3.1-flash-lite to GOOGLE_MODELS. Verified end-to-end on device (OpenClaw 2026.6.8): native generateContent and /v1beta/openai both return 200; the openai-compat provider resolves and runs every Gemini model with no auth fallback. * fix(chat/model): fail loud on readConfig error instead of clobbering the model list Address CodeRabbit review on #215: - chat/model auto-extend: readConfig().catch(()=>({})) meant a config-read failure produced existingModels=[] and overwrote models.providers.<p>.models with ONLY the picked id, dropping every other configured model. Return 500 instead of silently clobbering. - configure test: assert gemini-3.1-flash-lite is in the seeded google models (was only checking 2.5-flash + 3.5-flash).
β¦ helper) (#216) * fix: route anthropic through OpenAI-compat endpoint (+ extract shared helper) Anthropic's native plugin reads a per-agent sqlite auth store that ClawBox's file auth profile doesn't populate, so chats fail with ProviderAuthError 'No API key found' at call time (missing-provider-auth) on 2026.6.8 β the same class as google. Route anthropic through Anthropic's OpenAI-compatible endpoint (api.anthropic.com/v1) with the key inline, like google/openrouter. Now that there are three openai-compat providers, extract the shared writeOpenAICompatProvider() helper (CodeRabbit/simplify flagged the duplication on #215) and refactor openrouter + google to use it. chat/model auto-extend gates on a shared OPENAI_COMPAT_PROVIDERS set (openrouter, google, anthropic). openai-direct (API-key) has the same root cause but is intentionally NOT rerouted here: it's untested (Codex/oauth is the common path) and its native responses/reasoning behavior could degrade under a plain openai-completions shim β a separate follow-up if anyone hits it. Verified on device: api.anthropic.com/v1/chat/completions returns 200 for claude-opus-4-8 with the key; the rerouted provider resolves + runs. * fix(chat/model): reject auto-extend onto a half-written provider Address CodeRabbit review on #216: - chat/model auto-extend: if models.providers.<p> exists without an inline apiKey (legacy/partial state), appending only .models leaves an openai-compat provider that can't authenticate. Return 409 'Re-save in Settings' instead of switching the primary onto a broken provider. - configure test: cover a user-picked non-curated model (claude-opus-4-8) β the helper must still seed the pick via defaultModel so the gateway resolves it. * test(chat/model): give the openrouter auto-extend mock an inline apiKey The new 409 guard for half-written providers needs models.providers.<p>.apiKey; the existing 'accepts an arbitrary openrouter slug' mock only had the auth profile (no provider entry), so it 409'd. Add the realistic provider entry (baseUrl/api/apiKey/models) a configured openrouter provider actually has. * fix(chat/model): require baseUrl + api + apiKey before auto-extend CodeRabbit: a complete openai-compat provider entry has baseUrl + api + apiKey (written atomically by ai-models/configure). Check all three before appending a model, so a partially-written entry triggers the 409 re-save instead of leaving the primary on an unusable provider.
Reverts the TEMP skip from #128 (8bdb5ac). With the AP/install-bootstrap regressions resolved on main, we want the at-flash install to land a working llama-server + Gemma 4 GGUF on the device so first boot has local inference available without an extra Settings UI round-trip. The step still does the right thing on re-runs (idempotent: the needs_rebuild gate at step_llamacpp_install:1245 checks for an existing CUDA-linked llama-server, and ensure_llamacpp_model_cached short-circuits when the GGUF is already cached). Cold flash adds roughly 5β10 min per device on the Jetson Orin Nano β paid in parallel across both devices in Phase 3. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
π WalkthroughWalkthroughAdds Telegram pairing approval flow (lib helpers, new API route, Settings UI card, desktop popup, and translations), simplifies OpenAI OAuth to return raw ChangesTelegram Pairing Approval Feature
AI Provider Unification and OAuth Simplification
Installer and Updater Hardening
Documentation, Config, and Version Bump
Sequence Diagram(s)sequenceDiagram
participant DesktopPage as page.tsx (desktop)
participant PairingAPI as /setup-api/telegram/pairing
participant openclawConfig as openclaw-config.ts
participant SettingsApp as SettingsApp.tsx
rect rgba(30, 100, 200, 0.5)
note over DesktopPage: Poll every 20s
DesktopPage->>PairingAPI: GET ?poll=1
PairingAPI->>openclawConfig: readTelegramPairingRequests()
PairingAPI->>openclawConfig: readTelegramAllowFrom()
PairingAPI-->>DesktopPage: {pending[], approved[]}
DesktopPage->>DesktopPage: filter dismissed codes, show popups
end
rect rgba(200, 80, 30, 0.5)
note over DesktopPage: User approves from popup
DesktopPage->>PairingAPI: POST {code}
PairingAPI->>openclawConfig: approveTelegramPairing(code)
PairingAPI->>openclawConfig: persist display name
PairingAPI-->>DesktopPage: {approved[]}
DesktopPage->>DesktopPage: dispatch clawbox:telegram-approved
end
rect rgba(30, 160, 80, 0.5)
note over SettingsApp: Listens for approval event
SettingsApp->>PairingAPI: GET (refreshPairing)
PairingAPI-->>SettingsApp: updated approved list
end
Estimated code review effortπ― 5 (Critical) | β±οΈ ~120 minutes Possibly related PRs
Suggested labels
Suggested reviewers
π₯ Pre-merge checks | β 4 | β 1β Failed checks (1 warning)
β Passed checks (4 passed)
βοΈ Tip: You can configure your own custom pre-merge checks in the settings. β¨ Finishing Touchesπ Generate docstrings
π§ͺ Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. π§ ESLint
ESLint install failed: dependency version conflict. Check your lock file or package.json. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and canβt be posted inline due to platform limitations.
β οΈ Outside diff range comments (1)
src/components/SettingsApp.tsx (1)
2330-2337:β οΈ Potential issue | π‘ Minor | β‘ Quick winFinish the Ollama removal in the Settings copy.
Line 2330 exposes only
llamacpp, but the adjacent description still says users can βchoose a different local engine,β and this section still has visible Ollama wording in the same render path. Update the copy/legacy labels so Settings consistently presents Gemma 4 as the only local engine.Suggested copy adjustment
title="Set Up Local AI" description={localAiStatus?.configured - ? "Choose a different local engine if you want to switch your on-device fallback." + ? "Gemma 4 is configured as your private on-device fallback." : "Turn on a local model so ClawBox always has a private on-device backup."}π€ Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/SettingsApp.tsx` around lines 2330 - 2337, The SettingsApp component at the Local AI configuration section is exposing only llamacpp as a provider in the providerIds array, but the description text still mentions "choose a different local engine" which incorrectly implies multiple options are available. Update the description text in the section where title is "Set Up Local AI" to remove references to switching or choosing different local engines, and instead clearly state that Gemma 4 (via llamacpp) is the only available local engine option. Ensure all copy reflects that there is a single local engine choice rather than multiple options, maintaining consistency with the provider configuration.
π€ Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/superpowers/specs/2026-06-16-telegram-pairing-design.md`:
- Around line 47-56: Update the Architecture section of the design spec to
include a new subsection documenting the desktop notification popup in
`src/app/page.tsx` with its 20-second polling loop and `?poll=1` query parameter
usage. Revise the GET endpoint description (lines 47-48) to clearly distinguish
between `?poll=1` for fast cached store reads used by the desktop notification
layer and `?pending=1` for the slow authoritative CLI used by the Settings UI.
Clarify the "No auto-poll" statement on line 55 to specify that auto-polling is
avoided in the SettingsApp component but the desktop notification component
performs 20-second interval polling for new pairing requests.
In `@mcp/clawbox-cli.ts`:
- Around line 326-341: The `projectRoot` variable assignment that reads from the
`CLAWBOX_ROOT` environment variable lacks input validation, which poses a
security risk if the environment variable is compromised. Add validation to
check that `CLAWBOX_ROOT` matches a safe-character pattern (following the same
approach as in `force-update.sh` lines 32-35) before using it to construct the
`installScript` path. If validation fails, log an appropriate error message and
exit with status 1, ensuring the script path cannot be manipulated through
environment variable injection.
In `@src/app/page.tsx`:
- Around line 1786-1808: The buttons in this component (the dismiss button with
dismissPairingRequest, the approve button with approvePairingRequest, and the
"Open" button with openTelegramPairingSettings) lack an explicit type attribute.
Add type="button" to each of these button elements to prevent accidental form
submission behavior if the component structure changes in the future to include
a form wrapper.
In `@src/components/SettingsApp.tsx`:
- Around line 2450-2462: The pairing code input field lacks an accessible name
for screen readers since placeholders are not reliable for accessibility. Add an
aria-label attribute to the input element that clearly describes its purpose
(such as "Telegram pairing code"), or alternatively add an id attribute to the
input and associate it with a label element. This will ensure screen readers
properly announce the input purpose to users.
In `@src/tests/routes/chat-model.test.ts`:
- Around line 334-335: The test fixtures in the openrouter profile objects
(appearing at lines 334-335, 358-359, and 382-383) are using the legacy schema
with mode: "token", but the actual provider setup now persists profiles using
type: "api_key" with a key property. Update each of these fixture definitions to
use the current auth profile schema by replacing the mode: "token" structure
with type: "api_key" and including the appropriate key property to match the
real provider contract and prevent hidden regressions.
---
Outside diff comments:
In `@src/components/SettingsApp.tsx`:
- Around line 2330-2337: The SettingsApp component at the Local AI configuration
section is exposing only llamacpp as a provider in the providerIds array, but
the description text still mentions "choose a different local engine" which
incorrectly implies multiple options are available. Update the description text
in the section where title is "Set Up Local AI" to remove references to
switching or choosing different local engines, and instead clearly state that
Gemma 4 (via llamacpp) is the only available local engine option. Ensure all
copy reflects that there is a single local engine choice rather than multiple
options, maintaining consistency with the provider configuration.
πͺ Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
βΉοΈ Review info
βοΈ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: ee8163f5-452a-4e15-b4f8-ec0f6e3f17d7
π Files selected for processing (31)
README.mdconfig/openclaw-target.txtdocs/superpowers/specs/2026-06-16-telegram-pairing-design.mde2e/settings-workflow.spec.tse2e/setup-local-ai-order.spec.tsinstall.shmcp/clawbox-cli.tspackage.jsonscripts/gateway-pre-start.shsrc/app/page.tsxsrc/app/setup-api/ai-models/configure/route.tssrc/app/setup-api/ai-models/oauth/device-poll/route.tssrc/app/setup-api/ai-models/oauth/exchange/route.tssrc/app/setup-api/chat/model/route.tssrc/app/setup-api/telegram/configure/route.tssrc/app/setup-api/telegram/pairing/route.tssrc/components/AIModelsStep.tsxsrc/components/SettingsApp.tsxsrc/components/SetupWizard.tsxsrc/lib/openclaw-config.tssrc/lib/provider-models.tssrc/lib/translations.tssrc/tests/components/ai-models-step.test.tsxsrc/tests/oauth-routes.test.tssrc/tests/routes/ai-models/configure.test.tssrc/tests/routes/ai-models/device-poll.test.tssrc/tests/routes/chat-model.test.tssrc/tests/routes/telegram/configure.test.tssrc/tests/routes/telegram/pairing.test.tssrc/tests/unit/openclaw-config.test.tssrc/tests/unit/telegram-pairing.test.ts
- cli: validate CLAWBOX_ROOT against the SAFE_PATH guard (force-update.sh / updater.ts) before `sudo bash install.sh` β blocks a compromised env from running an attacker-controlled script. - a11y: aria-label on the pairing-code input; type="button" on the desktop pairing-popup buttons. - copy: Local AI Settings no longer says 'choose a different local engine' (Gemma 4 is the only engine since #206). - docs: telegram-pairing spec now documents the desktop popup + its 20s ?poll=1 polling (the spec said 'no auto-poll'). Skipped: the chat-model.test fixture mode:"token" note β the route gates on models.providers.*.apiKey, not the profile mode, so the fixture shape is inert.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and canβt be posted inline due to platform limitations.
β οΈ Outside diff range comments (1)
docs/superpowers/specs/2026-06-16-telegram-pairing-design.md (1)
47-48:β οΈ Potential issue | π‘ Minor | β‘ Quick winGET endpoint description is incomplete β missing
?poll=1query parameter.The GET endpoint description states
pendingis only populated with?pending=1, but the actual implementation supports two modes:
?poll=1(fast file readβfor the desktop 20s poller)?pending=1(slow CLIβfor manual Settings "Check" button)Update lines 47β48 to document both pathways:
- `pending` is only populated when `?pending=1` (opt-in to the slow CLI). + `pending` is only populated when `?poll=1` (fast, safe for polling) or `?pending=1` (slow CLI, authoritative for manual checks).This aligns with the desktop popup behavior documented on lines 59β60 and the actual route implementation.
π€ Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/superpowers/specs/2026-06-16-telegram-pairing-design.md` around lines 47 - 48, The GET endpoint description on lines 47-48 is incomplete and only documents the `?pending=1` query parameter. Update the description to document both supported query parameters: add `?poll=1` (fast file read used by the desktop 20s poller) and `?pending=1` (slow CLI used for manual Settings "Check" button). This will align the documentation with the actual implementation and match the behavior documented on lines 59-60 regarding the desktop popup behavior.
π€ Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@docs/superpowers/specs/2026-06-16-telegram-pairing-design.md`:
- Around line 47-48: The GET endpoint description on lines 47-48 is incomplete
and only documents the `?pending=1` query parameter. Update the description to
document both supported query parameters: add `?poll=1` (fast file read used by
the desktop 20s poller) and `?pending=1` (slow CLI used for manual Settings
"Check" button). This will align the documentation with the actual
implementation and match the behavior documented on lines 59-60 regarding the
desktop popup behavior.
βΉοΈ Review info
βοΈ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 4ced9fcb-8c56-448d-b725-3c6916665bcb
π Files selected for processing (4)
docs/superpowers/specs/2026-06-16-telegram-pairing-design.mdmcp/clawbox-cli.tssrc/app/page.tsxsrc/components/SettingsApp.tsx
β¦ + review) (#248) * feat(ci): ClawReview β our own advisory PR bot (policy + duplicates + review) Clawsweeper-inspired PR bot, owned by us, complementing CodeRabbit: - Structured advisory review on every PR (opened/reopened/synchronize): summary, source/test surface split, severity-ranked findings (P1-P3), duplicate detection vs open PRs + linked-issue validation, and a hidden <!-- clawreview-verdict:... --> marker for tooling - Deterministic repo-policy checks (no AI needed): beta-first base-branch rule (docs/meta paths may target main), package.json<->bun.lock consistency, conventional title, tests-expected heuristic, security-sensitive-path flagging, size warning - Auto area-labels from touched paths (same taxonomy as the issue-triage bot) - Advisory by design: posts + updates ONE comment (upsert by marker, no spam on every push); never closes PRs; never fails the pipeline (exit 0 on any error); skips bot-authored PRs - Security: pull_request_target with the base-repo checkout ONLY β PR code is never checked out or executed; the diff is reviewed as data via the API (capped at 80k chars); PR title/body/diff are declared untrusted in the system prompt - Same hardening as the triage bot: SHA-pinned actions, job-scoped permissions, --prefix scripts SDK install, graceful no-op without ANTHROPIC_API_KEY (same pending secret) Dry-run validated against real PRs: #243 (bot-skip fires), #238 (meta->main passes base policy), #227 (device->beta passes; sensitive-path + tests checks fire). * feat(ci): ClawReview review fixes β empirically tuned policy, hardened plumbing Four-angle /simplify review applied. The big one: replaying the policy checks against the 40 most recently merged PRs showed 55% would have warned (the routine release PR collected 5 warnings at once) β warnings tuned to be rare enough to mean something: - Release promotions (head beta -> base main) are the sanctioned path to main: exempted from feature-PR conventions (was 3/4 of base-check warns) - Lockfile check is diff-aware: only warns when package.json DEPENDENCY sections change β version-only bumps never break --frozen-lockfile (6/6 historical warns on the naive check were false) - 'release' added to the conventional-title types (the repo's own release convention was failing its own check) - Tests-expected check gated to >=10 changed src lines (string-swap PRs were the main noise) - SENSITIVE_RE: config/ narrowed to root-privilege files (was flagging every openclaw-target.txt version bump); added real misses (login-api route, rate limiters, oauth utils, credentials route, root-update-step.sh, launch-browser.sh, recover.sh); rendered as an βΉοΈ note, notβ οΈ , so warnings keep meaning Plumbing (config + simplification reviews): - upsertComment author-checked (a user comment starting with our marker can't be PATCH-overwritten) and single-page (bot comments early) - --paginate + per-page '-q [...]' arrays would crash JSON.parse on >100-item PRs (we've had a 1,028-file PR) β files now fetched as JSONL - drafts skipped (reviewed at ready_for_review; type added) - bot-skip moved before the expensive gathering; dead 'dependabot' arm dropped; dead fetched fields trimmed; labels applied in one batched pr edit; duplicate render gated on likely && of - reciprocal keep-in-sync comments at the two cross-bot drift points (area taxonomy, SDK version pin) Re-validated by dry-run: #217 release promotion 5 warns -> 0 (1 pass + 1 info), #238 meta->main all-pass, #227 device->beta all-pass. * feat(ci): give ClawReview its crab voice π¦ Playful frame, rigorous content: greeting, verdict badge, clean-bill line, and sign-off carry the persona (Shipshape β claws up / Needs a molt / Walking sideways / This shell looks occupied); policy checks and findings stay strictly factual so a P1 never drowns in puns. Lines are picked deterministically by PR number, keeping the upserted comment's voice stable across pushes. The model's summary gets at most one marine flourish by prompt; finding titles/details are instructed pun-free. * feat(ci): optional ClawReview GitHub App identity (clawreview[bot] + crab avatar) Both bots (pr-review + issue-triage) mint an installation token via actions/create-github-app-token when the CLAWREVIEW_APP_ID + CLAWREVIEW_APP_PRIVATE_KEY secrets exist β comments and labels then post as clawreview[bot] with the App's avatar (and get the App's own rate limits). Without the secrets the step skips and everything falls back to github-actions[bot]; the bots work either way. Comment-upsert author check accepts both identities so the switch-over edits the same comment. * feat(ci): OAuth subscription transport + CodeRabbit fixes Both bots now prefer the Claude Code CLI (claude -p, authed by CLAUDE_CODE_OAUTH_TOKEN) β the official Pro/Max subscription path, same runtime as claude-code-action and the team's crons β falling back to the Anthropic SDK when only ANTHROPIC_API_KEY is set, and no-op without either. - review()/main() split into reviewViaClaudeCli + reviewViaSdk (pr-review) and classifyViaClaudeCli + classifyViaSdk (issue-triage); selected by CLAUDE_CODE_OAUTH_TOKEN presence at runtime - parseModelJson tolerates fenced/wrapped CLI output (json wrapper -> .result -> object); the SDK path keeps schema-enforced output - workflows install the backend the available secret needs (CLI when OAuth, SDK otherwise), both pinned; token passed to the run step - REVIEW_ONLY env prints the composed comment without posting, for local end-to-end testing of either transport CodeRabbit (#248): - top-level permissions: {} so the default token grant is empty (only the job's explicit scopes apply) - bun.lock check: dependency-entry match now requires a version-spec-shaped value (^/~/digit/npm:/workspace:/git/url), so edits to scripts/name/etc. no longer misfire the 'dependencies changed' warning Validated end-to-end via the OAuth CLI transport against PR #227: correct verdict, crab voice, and a genuine P3 finding in gateway-pre-start.sh.
Release 3.1.4 β OpenClaw 2026.6.8 + provider compatibility + Telegram pairing
Promotes the staged
betaline tomain. Version 3.1.3 β 3.1.4, OpenClaw pin 2026.6.1 β 2026.6.8.Headline: OpenClaw 2026.6.8 provider compatibility
2026.6.8 reworked provider auth; without these fixes OpenRouter 401s and Gemini/Anthropic silently fall back to the fallback model.
api_key(not legacytoken) auth profiles for key providers; inline OpenRouter's real key (was a placeholder). Fixes OpenRouter401 Missing Authentication header.writeOpenAICompatProvider()helper.Telegram pairing
groupPolicythat silenced the bot.Installer / updater
install.shhard-syncs to the resolved branch instead of a silent ff-only merge (fixes "updates from the portal don't work", Updates from the clawbox portal don't workΒ #202).clawbox updatecommand (issue #202)Β #208 βclawbox updateCLI to run the full installer from the terminal.a691fc3β re-enablestep_llamacpp_installat flash time.Local AI
Docs
Validation
All provider paths (ClawBox AI, OpenRouter, OpenAI/Codex, Gemini, Anthropic) verified end-to-end on a Jetson running 2026.6.8; unit tests green on-device. Final sign-off on a fresh
betaflash.Summary by CodeRabbit
clawbox updatefor streamlined updates.