Skip to content

Harden gateway recovery after updates - #263

Merged
yalexx merged 1 commit into
betafrom
hotfix/v3.1.10-gateway-legacy-recovery
Jul 20, 2026
Merged

Harden gateway recovery after updates#263
yalexx merged 1 commit into
betafrom
hotfix/v3.1.10-gateway-legacy-recovery

Conversation

@yalexx

@yalexx yalexx commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add post-update gateway verification so the UI does not mark updates complete while the OpenClaw gateway is offline
  • run conservative legacy-state recovery only when port 18789 is down and logs match known blockers from older devices
  • bump ClawBox to v3.1.10 for the beta release candidate

Safety

  • beta was first aligned to main/v3.1.9 so this PR is one focused commit on top of both branches
  • legacy files are moved to an openclaw-legacy-quarantine timestamped directory, not deleted
  • main is untouched; this targets beta first

Verification

  • bun run test:unit -- src/tests/unit/updater.test.ts
  • bunx tsc --noEmit
  • bun run lint -- src/lib/updater.ts src/tests/unit/updater.test.ts
  • bash -n install.sh
  • git diff --check

@yalexx
yalexx requested a review from a team as a code owner July 20, 2026 13:43
@github-actions

Copy link
Copy Markdown

πŸ¦€ ClawReview

Your friendly reef crab, here with the lay of the land.

This PR hardens the post-update flow by adding a gateway health verification step that runs after updates complete. When the OpenClaw gateway isn't reachable on port 18789, the system attempts an openclaw doctor --fix recovery; if journal logs match known legacy-state migration blockers, it quarantines specific files to a timestamped directory before retrying. The change lands in both install.sh and src/lib/updater.ts, and bumps the version to v3.1.10 for the beta RC.

At a glance

  • πŸ”§ Fix Β· touches the post-update / auto-update flow in install.sh and src/lib/updater.ts
  • Base branch: beta Β· +170 source / +7 tests across 5 files
  • βœ… base beta matches the beta-first convention
  • 🟑 package.json dependencies changed without bun.lock β€” CI runs bun install --frozen-lockfile and will fail
  • 🟑 title doesn't follow type: description (feat/fix/chore/docs/…)
  • βœ… source changes come with test changes
  • ℹ️ touches security-sensitive paths (install.sh) β€” review with extra care

Good to know

  • 🟑 The new gateway_verify step uses failFast: true, so if gateway recovery fails entirely, the update will now halt rather than marking success with a dead gateway β€” a meaningful behavior change on customer devices.
  • 🟑 package-lock.json is updated but bun.lock (the authoritative lockfile per project convention) is not present in the diff β€” policy check flagged this; CI's bun install --frozen-lockfile may surface a mismatch even though no actual dependencies changed.
  • ℹ️ Test coverage for the new recovery logic is light β€” the added mock stubs isPortOpen to always return true, so the quarantine, journal-reading, and legacy-blocker-detection paths aren't exercised by the test suite yet.
  • ℹ️ Legacy state is moved to a timestamped openclaw-legacy-quarantine-* directory rather than deleted, making the recovery reversible if something goes wrong on a specific device.

β€” ClawReview πŸ¦€, scuttling off. General info only β€” see CodeRabbit for the detailed review. Conventions: docs.

@github-actions github-actions Bot added area: install Auto-triage area area: gateway Auto-triage area labels Jul 20, 2026
@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown

CI Summary

βœ… Tests

  • Result: passed
  • View run
  • Coverage: statements 69.77%, branches 59.68%, functions 65.16%, lines 71.79%

βœ… E2E

βœ… E2E Install

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 9 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
βš™οΈ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6345a479-2285-4921-a8a9-a6c898f98410

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 49ab98c and 33d5a6b.

β›” Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
πŸ“’ Files selected for processing (4)
  • install.sh
  • package.json
  • src/lib/updater.ts
  • src/tests/unit/updater.test.ts
✨ Finishing Touches
πŸ§ͺ Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hotfix/v3.1.10-gateway-legacy-recovery

Comment @coderabbitai help to get the list of available commands.

@yalexx
yalexx merged commit 22fa9ba into beta Jul 20, 2026
8 checks passed
@yalexx
yalexx deleted the hotfix/v3.1.10-gateway-legacy-recovery branch July 20, 2026 13:55
yalexx added a commit that referenced this pull request Jul 22, 2026
* Harden gateway recovery after updates (#263)

* fix: migrate legacy openai/<gpt> model+fallbacks to codex on startup (#266)

ChatGPT-subscription boxes (Codex OAuth, no OpenAI API key) that stored
their active model or a fallback as `openai/gpt-5.5` (etc.) before the setup
UI routed ChatGPT picks through Codex hit `401 Missing bearer or basic
authentication in header` on api.openai.com/v1/responses β€” often only as a
FailoverError days into use, once the OAuth token first refreshes and the
failover chain reaches the keyless `openai/*` fallback.

The chat-model pick route already rewrites openai/<gpt> -> codex/<gpt>, but
only when the user re-picks the model; existing configs never re-pick, so an
updated box stays broken until manually re-selected. Migrate primary +
fallbacks in gateway-pre-start.sh on gateway start, guarded on "codex OAuth
present AND no OpenAI API key" so keyed / dual-auth boxes (where openai/* is a
valid route) are left untouched. Mirrors CODEX_SUPPORTED_MODEL_RE /
hasOpenAiApiKeyProfile / hasCodexOauthProfile in
src/app/setup-api/chat/model/route.ts.

Verified against 6 fixtures: openai->codex primary+fallback migrate; keyed
box untouched; non-supported (gpt-4o) primary left as-is; already-codex no-op;
no-codex-auth untouched; composes with the retired-Sonnet migration. bash -n
and py_compile pass.

Co-authored-by: Mike (IDRobots) <mike@idrobots.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

* fix(3.1.10): responsive chat header pills (wrap instead of overlap on narrow chat) (#267)

* fix: chat header pills squeeze + truncate cleanly on narrow panels

On a narrow chat the provider / model / thinking selector pills overlapped
into an unreadable strip. Two parts:

1. .header-dropdown-trigger gets width:100% so the button fills its
   flex-shrinking .header-dropdown parent. Previously the button kept its
   content width and spilled past the shrunk parent, so overflow:hidden on
   .chat-header-pills clipped / overlapped the pills instead of the labels
   truncating. Now every pill gives ground evenly and its label ellipsizes
   (the chevron stays β€” it's reserved in the 24px right padding).

2. Single row (no wrap) + overflow:hidden, and the chat window clamps to
   MIN_CHAT_WIDTH (340px) on both resize paths + the rendered width, so the
   window stops shrinking once the pills reach a readable minimum instead of
   smashing them.

The open menu is portaled to <body> (HeaderDropdown), so clipping the row
can't hide it. Verified at 320-420px: even truncation, carets visible, zero
overlap.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: open chat from mascot with a macOS-style animation, no corner flash

- Stop streaming the frozen mascot's position into mascotX while the chat is
  open (page.tsx). That nudged mascotX for a frame right after opening, so the
  popup flashed to the wrong corner before settling. mascotX is now captured
  once from the tap.
- Grow the popup OUT of the mascot: transform-origin pinned to the popup's
  bottom edge, aligned horizontally with the mascot, and scale 0.82 -> 1 on an
  easeOutExpo curve (cubic-bezier(0.16,1,0.3,1)) over 0.36s. Smooth, premium,
  emanates from where you tapped instead of scaling from the popup centre.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* chore: bump SW cache clawbox-v3 -> v4 to invalidate stale assets on the 3.1.10 chat-UI changes

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: keep chat popup header on-screen on short/zoomed viewports

The un-dragged popup anchors from the bottom (bottom:170 above the mascot,
bottom:65 in tray mode) but its maxHeight budget was a flat 100vh-60px, so on
viewports shorter than ~680px (small windows, browser zoom) a 500px-tall popup
shoved its whole header β€” pills, status dot, close button β€” off the TOP of the
screen (rect.y = -76 measured on a 594px viewport). Subtract the bottom anchor
from the height budget per mode (+12px top margin) so the header is always
visible and the popup just gets shorter instead.

Found by driving the real desktop over CDP and sampling the popup rect during
open; the same probe confirmed the mascot-open animation runs and there is no
left-corner flash.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Mike (IDRobots) <mike@idrobots.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Mike (IDRobots) <mike@idrobots.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: gateway Auto-triage area area: install Auto-triage area

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant