Skip to content

feat(webchat): sidebar lobster status pet (seeded per session)#102766

Merged
steipete merged 2 commits into
mainfrom
claude/lobster-lobby-placeholder-4abdbb
Jul 9, 2026
Merged

feat(webchat): sidebar lobster status pet (seeded per session)#102766
steipete merged 2 commits into
mainfrom
claude/lobster-lobby-placeholder-4abdbb

Conversation

@steipete

@steipete steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Closes #102754

Rework: the first revision perched the lobster on the chat composer, which felt too close to Claude Code's input mascot. It now lives on the sidebar footer ledge and doubles as a status indicator. Same seeded looks and personalities; new home and new job.

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-pet element that perches on the sidebar footer divider (feet dangling over the border, above the connection dot) and mirrors gateway state:

  • Idle (connected, nothing running): personality-weighted acts — scuttle along the ledge, claw wave, snips, hop, spin, peek, bubble-blowing, naps with floating z's.
  • Busy (any session has an active run): faster scurry pool — scuttles, hops, snips; no napping mid-run.
  • Offline (gateway disconnected): eye glints turn grey and it paces/peeks worriedly. Status flips trigger a startle reaction, so disconnects and reconnects are visible at a glance.
  • Poking it startles it. Seeded per session + page load: shell palette (crimson, coral, teal, violet, ink, rare gold), size, perky/droopy antennae, accessory (none, crown, sprout, eyepatch), perch spot, facing, and one of 4 temperaments (sleepy/zoomy/friendly/showoff).
  • Drawn in the smooth OpenClaw lobster style (same species as icons.lobster/the dreams sleeper), deliberately not pixel art.
  • Decorative by contract: aria-hidden, no i18n strings, no config surface. prefers-reduced-motion gets 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:

perch closeup
hero dark

Napping with z's (idle) and offline (red dot, grey glints, startled):

nap
offline

Session-seeded variants (palette, accessories, antennae) and light mode:

variants
light

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, resolveLobsterPetMode mapping, 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:ui typecheck and pnpm --dir ui build (vite production build).
  • Live verification against 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.
  • Codex autoreview across the iterations accepted and led to fixes for: reduced-motion bypass on the visibility-resume path, nap eye rules losing the cascade to the blink animation, and (in the composer revision) a clipped perch on short-landscape viewports; final review clean.

@clawsweeper

clawsweeper Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 9, 2026, 8:10 AM ET / 12:10 UTC.

Summary
Adds a decorative Lit custom element, CSS, composer integration, and tests for a session-seeded animated mascot shown on the idle Control UI chat composer.

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.

  • Config/default surface: 0 added, 0 changed, 0 removed. The decorative feature does not add a user setting, default, env var, migration, or compatibility path that would need upgrade proof.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #102754
Summary: The linked issue is the canonical feature request, and this PR is its open implementation candidate via closing syntax.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster ✨ media proof bonus
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Get explicit maintainer product/design approval for the protected-label core UI polish before landing.

Risk before merge

  • [P1] Product/design acceptance remains maintainer-owned because this is a new decorative core web chat behavior, not a bug fix.
  • [P1] The branch is behind current main even though the touched UI files did not change between the base and current main; landing should refresh the merge head before final approval.

Maintainer options:

  1. Decide the mitigation before merge
    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.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P2] Manual maintainer review is needed because this is a protected-label product/UI feature PR, not a narrow automated repair.

Maintainer decision needed

  • Question: Should the idle Control UI chat composer get this decorative session-seeded mascot in core web UI?
  • Rationale: The code path looks bounded, but the change intentionally alters the tone of a primary chat surface and the PR has a protected maintainer label, so product/design acceptance cannot be automated.
  • Likely owner: steipete — Peter requested the feature, authored the implementation, and is listed as the project decision owner in CONTRIBUTING.md.
  • Options:
    • Approve Core Composer Mascot (recommended): Proceed with normal PR landing after final review, keeping the feature decorative and config-free.
    • Defer The Mascot Direction: Keep the linked feature open or ask for a narrower design if the core chat surface should stay quieter.
    • Move To A Different Surface: Reject this composer placement and ask for mascot polish in a less central UI area instead.

Security
Cleared: No security or supply-chain concern found; the diff adds UI TypeScript, CSS, and tests without dependency, workflow, secret, auth, package, or script changes.

Review details

Best 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 changes

Label changes:

  • add P3: This is low-risk Control UI visual polish and product delight, not a regression, setup blocker, data loss, or security issue.
  • add proof: sufficient: Contributor real behavior proof is sufficient. Screenshots directly show the after-fix visual behavior across dark, light mobile, animation states, and variants; the PR body also reports live dev UI verification and focused tests.
  • add proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. Screenshots directly show the after-fix visual behavior across dark, light mobile, animation states, and variants; the PR body also reports live dev UI verification and focused tests.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (screenshot): Screenshots directly show the after-fix visual behavior across dark, light mobile, animation states, and variants; the PR body also reports live dev UI verification and focused tests.

Label justifications:

  • P3: This is low-risk Control UI visual polish and product delight, not a regression, setup blocker, data loss, or security issue.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (screenshot): Screenshots directly show the after-fix visual behavior across dark, light mobile, animation states, and variants; the PR body also reports live dev UI verification and focused tests.
  • proof: sufficient: Contributor real behavior proof is sufficient. Screenshots directly show the after-fix visual behavior across dark, light mobile, animation states, and variants; the PR body also reports live dev UI verification and focused tests.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. Screenshots directly show the after-fix visual behavior across dark, light mobile, animation states, and variants; the PR body also reports live dev UI verification and focused tests.
Evidence reviewed

PR surface:

Source +867, Tests +147. Total +1014 across 5 files.

View PR surface stats
Area Files Added Removed Net
Source 4 867 0 +867
Tests 1 147 0 +147
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 5 1014 0 +1014

What I checked:

Likely related people:

  • steipete: CONTRIBUTING.md lists Peter as project maintainer, he requested the feature and authored the candidate PR, and recent history includes his web chat work. (role: product decision owner and recent web chat contributor; confidence: high; commits: 2f542bb1a0b7, 3ccf2a07393e; files: ui/src/pages/chat, ui/src/styles/chat, CONTRIBUTING.md)
  • BunsDev: CONTRIBUTING.md lists Val Alexander for UI/UX, and git history shows multiple Control UI/chat polish commits in adjacent files. (role: adjacent UI/UX owner; confidence: medium; commits: 2cfb660a9bb8, a710366e9ece, 4e94f3aa0273; files: ui/src/pages/chat, ui/src/styles/chat)
  • vincentkoc: Current main blame for the composer shell points to a recent Vincent Koc commit, though that commit appears to be broad text-safety churn rather than mascot or design ownership. (role: recent direct-line contributor; confidence: low; commits: 0ac8933721f7; files: ui/src/pages/chat/components/chat-composer.ts, ui/src/styles/chat/layout.css)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. labels Jul 9, 2026
steipete added 2 commits July 9, 2026 05:22
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.
@steipete
steipete force-pushed the claude/lobster-lobby-placeholder-4abdbb branch from 2f542bb to d81536a Compare July 9, 2026 12:23
@steipete steipete changed the title feat(webchat): composer lobster mascot perches on the empty prompt feat(webchat): sidebar lobster status pet (seeded per session) Jul 9, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

@steipete
steipete merged commit 01f4596 into main Jul 9, 2026
80 checks passed
@steipete
steipete deleted the claude/lobster-lobby-placeholder-4abdbb branch July 9, 2026 12:34
@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 10, 2026
…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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui maintainer Maintainer-authored PR P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: XL status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Composer lobster mascot perches on the empty prompt (seeded per session)

1 participant