feat(webchat): sidebar lobster status pet (seeded per session)#102766
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 9, 2026, 8:10 AM ET / 12:10 UTC. Summary PR surface: Source +867, Tests +147. Total +1014 across 5 files. Reproducibility: not applicable. This PR implements a new visual feature rather than fixing a reproducible bug. Current-main source inspection confirms the composer does not already render the requested mascot. Review metrics: 1 noteworthy metric.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review detailsBest possible solution: Land the PR only if maintainers approve the mascot direction for core Control UI, then refresh against current main and keep the implementation local to the composer without adding config or i18n surface. Do we have a high-confidence way to reproduce the issue? Not applicable: this PR implements a new visual feature rather than fixing a reproducible bug. Current-main source inspection confirms the composer does not already render the requested mascot. Is this the best way to solve the issue? Yes for implementation shape, subject to product approval: the mascot is isolated to the chat composer, uses existing Lit patterns, adds no config/i18n/dependency surface, and includes focused lifecycle and reduced-motion tests. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against f786efddcd88. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +867, Tests +147. Total +1014 across 5 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
A decorative OpenClaw lobster (smooth icons.lobster style) sits on the composer edge while the prompt is idle, ducks away on typing/runs, and plays personality-weighted idle acts (scuttle, wave, snip, hop, spin, peek, bubbles, nap with z's; poke to startle). Look and personality are seeded per session + page load: palette, size, antennae, accessory, perch, facing, temperament. Decorative contract: aria-hidden, no config, reduced-motion stays fully static, timers pause on hidden tabs and clean up on disconnect. Hidden on short-landscape viewports where the composer scrolls. Closes #102754
…s pet The composer perch read too close to Claude Code's input mascot. The pet now lives on the sidebar footer ledge above the connection dot and mirrors gateway state: idle personality acts when quiet, a faster scurry pool while runs are active, grey-eyed worried pacing while disconnected, and a startle on every status flip. Composer wiring reverted; element renamed openclaw-lobster-pet; hidden in the collapsed rail.
2f542bb to
d81536a
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d81536a259
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (!connected) { | ||
| return "offline"; | ||
| } | ||
| return sessions?.some((row) => row.hasActiveRun === true) ? "busy" : "idle"; |
There was a problem hiding this comment.
Honor session status when choosing pet mode
When a session row reports run state through status rather than a fresh hasActiveRun flag, this resolver can show the opposite status: status: "running" with an omitted flag stays idle, while a stale hasActiveRun: true with a terminal status stays busy. Other run-state UI paths use the shared isSessionRunActive contract in ui/src/lib/session-run-state.ts, so the new sidebar mascot can misrepresent active/finished runs for those existing row shapes unless this helper accepts status and applies the same predicate.
Useful? React with 👍 / 👎.
|
Merged via squash.
|
…law#102766) * feat(webchat): composer lobster mascot perches on the empty prompt A decorative OpenClaw lobster (smooth icons.lobster style) sits on the composer edge while the prompt is idle, ducks away on typing/runs, and plays personality-weighted idle acts (scuttle, wave, snip, hop, spin, peek, bubbles, nap with z's; poke to startle). Look and personality are seeded per session + page load: palette, size, antennae, accessory, perch, facing, temperament. Decorative contract: aria-hidden, no config, reduced-motion stays fully static, timers pause on hidden tabs and clean up on disconnect. Hidden on short-landscape viewports where the composer scrolls. Closes openclaw#102754 * refactor(webchat): move lobster mascot from composer to sidebar status pet The composer perch read too close to Claude Code's input mascot. The pet now lives on the sidebar footer ledge above the connection dot and mirrors gateway state: idle personality acts when quiet, a faster scurry pool while runs are active, grey-eyed worried pacing while disconnected, and a startle on every status flip. Composer wiring reverted; element renamed openclaw-lobster-pet; hidden in the collapsed rail.
Closes #102754
What Problem This Solves
The Control UI has a strong lobster identity (sidebar logo, dreams-scene sleeper,
icons.lobster) but nothing alive in the product itself, and gateway status is just a colored dot. A tiny mascot with real status semantics adds personality without adding config or product surface.Why This Change Was Made
Adds a decorative
openclaw-lobster-petelement that perches on the sidebar footer divider (feet dangling over the border, above the connection dot) and mirrors gateway state:icons.lobster/the dreams sleeper), deliberately not pixel art.aria-hidden, no i18n strings, no config surface.prefers-reduced-motiongets a static sprite (no acts on any path, including tab-visibility resumes and mode flips). Timers pause on hidden tabs and clean up on disconnect; hidden entirely in the collapsed sidebar rail. The act loop avoids lit change-in-update re-renders.Known nit (intentional): the sprite overlays the bottom ~20px of the last visible session row while perched there; rows scroll behind it and only the ~32px sprite itself captures clicks.
Non-goals: no product/config surface, no behavior change for navigation, sessions, or the composer.
User Impact
Web UI users get a small sidebar mascot that shows gateway status at a glance — napping means idle, scurrying means a run is active, grey-eyed pacing means disconnected. Every session + page load hatches a different lobster. Reduced-motion users get a static (still randomized) one.
Evidence
Perched on the sidebar footer (idle) / full page:
Napping with z's (idle) and offline (red dot, grey glints, startled):
Session-seeded variants (palette, accessories, antennae) and light mode:
Validation (delegated Blacksmith Testbox,
exit=0):pnpm test ui/src/components/lobster-pet.test.ts ui/src/pages/chat/chat-composer.test.ts— seed determinism, variant catalog bounds,resolveLobsterPetModemapping, mode-startle + per-mode act pools with fake timers, poke startle, disconnect timer cleanup, reduced-motion inertness (incl. visibilitychange resume and mode flips), plus the untouched composer suite after the revert.pnpm tsgo:test:uitypecheck andpnpm --dir ui build(vite production build).pnpm dev:ui:mock: perch on the footer ledge, idle acts, offline flip (grey glints + startle, red status dot), reconnect startle, busy mode class, collapsed-rail hiding, per-reload re-randomization, dark/light, no new lit change-in-update warnings.