* fix(infra): stop package-root walks at node_modules boundaries
Nested git worktrees (.worktrees/<pr>, .claude/worktrees/*) have no local
node_modules, so vitest workers run with argv1 inside the enclosing
checkout's node_modules. resolveOpenClawPackageRoot* walked up past that
boundary, resolved the enclosing checkout as the openclaw package root,
and bundled plugin discovery loaded the ancestor's stale extension
manifests, failing ~12 test shards and the scripts/pr prepare-run test
gate whenever the primary checkout sat on a different branch.
A package.json above a node_modules directory belongs to the workspace
that installed the tooling, never to the package owning the running code,
so the ancestor walk now stops there. Installed layouts
(node_modules/openclaw, .bin shims, global installs) match at or below
the boundary and are unaffected.
* fix(scripts): pin bundled plugin discovery in nested PR worktree gates
scripts/pr gates run pnpm test inside .worktrees/<pr>, which resolves
vitest tooling from the primary checkout's node_modules. PR branches that
predate the openclaw-root node_modules-boundary fix would still discover
the primary checkout's stale bundled plugin manifests, so pin
OPENCLAW_BUNDLED_PLUGINS_DIR to the worktree's own extensions before the
build/check/test gates.
* feat: add session thread management
Squash of codex/thread-management (025aefc3ad1) onto origin/main:
pin/archive/rename sessions via sessions.patch, archived-aware
sessions.list, lifecycle fencing, read-only archived chat, SDK +
Swift protocol support, Control UI session management.
* refactor(ui): minimal session rows with hover-revealed management
Chat picker and sidebar recents share session-row primitives: single-line
rows, relative timestamps, rename/archive/pin revealed on hover or focus,
accent pin badge for pinned rows, and an active-run spinner in the trail
slot. Sidebar floats pinned sessions above recency via the shared
comparator and gains archive/pin actions through the unified sessions-view
patch fallback. Archive eligibility is one shared policy
(canArchiveSessionRow); the sidebar/picker active-run tooltip now uses the
real sessionsView.activeRun locale key.
* fix: align session admission with mailbox-era main
Integration fixes after rebasing onto current main: sessions_list mailbox
test expectations learn the archived/pinned row fields and archived:false
list param; gateway agent admission treats a session as deleted only when
both the requested and canonical alias sets miss it (legacy bare-main
stores and exec-approval followups read under different spellings); cron
persist tests keep a consistent store across claim-guarded persist calls;
the ACP abort hook test asserts abort propagation instead of signal
identity; drop dead lifecycle writes flagged by no-useless-assignment and
fix the promise-executor return in the codex compact test.
* fix(qa): align UI e2e and shard fixtures with redesigned session rows
Sidebar session rows are wrapper divs with an inner link now: update the
navigation browser tests and chat-flow Playwright selectors. Seed a real
per-test session store for the auto-fallback admission guard instead of
depending on leftover host files at /tmp/sessions.json. Teach the
test-projects routing fixture about the suites that newly import the
shared temp-dir helper. Document the Codex thread-format contract for
archivedAt/pinnedAt (flag derived from server-stamped timestamp, epoch ms
here vs Codex epoch seconds) at the type and in the session docs.
* test: route auto-fallback suite through temp-dir helper plans
The auto-fallback suite now imports the shared temp-dir helper for its
seeded session store, so the top-level helper routing fixture must list
it in the auto-reply plan.
The scoped outbound media tests added in #92872 assert raw mkdtemp paths,
but prod resolvers canonicalize roots, so on macOS the /var -> /private/var
tmpdir symlink made three tests fail (green on Linux CI). Realpath the tmp
roots like sibling tests, and export the real UploadDailyLimitExceededError
from the outbound-dispatch sender.js mock so prod instanceof checks in error
paths hit real assertions instead of vitest's missing-export guard.
Also add AGENTS.md test guidance covering both patterns.
Bare openclaw does not open Crestodian once config has authored settings.
Document the actual three-way routing: missing/unauthored config starts
classic onboarding, invalid config starts Crestodian for repair, valid
config opens the normal agent TUI (local or reachable configured Gateway),
with /crestodian or openclaw crestodian as the explicit entry points.
Matches resolveBareRootLaunchTarget in src/cli/run-main.ts.
* feat(gateway): add device.pair.setupCode RPC for connect QR
The OpenClaw mobile/companion app scans a pairing setup code to connect to the gateway, but that code + QR could only be produced by the openclaw qr CLI (ASCII to stdout). Non-terminal clients driving onboarding had no way to display the connect QR.
Add a device.pair.setupCode gateway method that reuses resolvePairingSetupFromConfig + encodePairingSetupCode + renderQrPngDataUrl to return { setupCode, qrDataUrl?, gatewayUrl, auth, urlSource }. The embedded setup code mints a short-lived bootstrap token that hands off broad operator scopes (read/write/approvals/talk.secrets), so the method requires operator.admin (matching the wizard methods a companion already uses) and is not advertised. auth is a label only; the gateway credential is never returned, and an oversized QR is omitted so the response always satisfies the result schema.
Refs #94661.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat(ui): pair mobile devices from Control UI
* docs: refresh generated docs map
* docs: clarify mobile QR auto-connect
* docs: clarify mobile QR auto-connect
* docs: clarify mobile QR auto-connect
---------
Co-authored-by: Barbara Kudiess <76582160+bkudiess@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Summary:
- The branch adds plugin package live-proof guidance to the testing skill and plugin docs, separating npm-pack package validation from official-trust proof and documenting runtime dependency and compiled-entry checks.
- PR surface: Docs +111. Total +111 across 3 files.
- Reproducibility: not applicable. this is a documentation and skill-guidance clarification PR rather than a bug report. I validated the documented claims against current source, adjacent docs, tests, and live PR checks.
Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.
Validation:
- ClawSweeper review passed for head b56efcffc5.
- Required merge gates passed before the squash merge.
Prepared head SHA: b56efcffc5
Review: https://github.com/openclaw/openclaw/pull/99962#issuecomment-4882084565
Co-authored-by: Mason Huang <masonxhuang@tencent.com>
Approved-by: hxy91819
Claude Fable 5 requests on direct Anthropic API keys now opt into Anthropic's server-side fallback (server-side-fallback-2026-06-01): a safety-classifier decline is re-served by claude-opus-4-8 inside the same call instead of failing the turn with "LLM request failed.". Mid-stream boundaries drop the declined model's thinking/tool blocks per Anthropic's replay contract, keep the partial text as the continuation prefix, record a provider_fallback diagnostic, and cost the turn at the serving model's rates. Docs lead with the coupling: using Fable 5 means also using Opus 4.8. OAuth, proxies, Bedrock, Vertex, and Foundry requests are unchanged.
Live-verified: a benign reasoning_extraction classifier decline through the product path returns an Opus-served answer with the provider_fallback diagnostic; exact-head CI green (67 checks).
Related: #98976