Skip to content

feat(kiloclaw): polish onboarding previews with shared chat shell#3354

Open
Drixled wants to merge 1 commit into
mainfrom
worktree/main-20260519-1505
Open

feat(kiloclaw): polish onboarding previews with shared chat shell#3354
Drixled wants to merge 1 commit into
mainfrom
worktree/main-20260519-1505

Conversation

@Drixled
Copy link
Copy Markdown
Contributor

@Drixled Drixled commented May 20, 2026

Summary

  • Adds a reusable BriefingChatPreview component (apps/web/src/app/(app)/claw/components/BriefingChatPreview.tsx) that renders the user's bot identity sending a sample tomorrow-morning message — used as the left column of the Calendar / Inbound Email / Interests steps so the Identity step's personalization (name + emoji) carries through the rest of the wizard.
  • Tightens each step's right column: drops redundant single-row eyebrows (ACCESS, INBOUND ADDRESS), right-sizes integration tiles (56px → 40px) to match the chat avatar, swaps the generic Lucide Calendar icon for the multi-color Google "G" mark from the existing GoogleLogo, and replaces three brand-yellow-on-every-row Forward tip tiles with a neutral mono numbered list (1, 2, 3) — three yellow tiles violated the brand's "yellow scarce" rule.
  • Merges the inbound email address display + Copy button into a single bordered field with an inline border-l divider action, matching the field-with-action pattern used elsewhere in the codebase.
  • Migrates the wizard's primary CTAs from the legacy blue (variant="primary" = hardcoded #2B6AD2) to brand yellow-green by overriding with bg-brand-primary className on variant="default". Follows existing precedent (KiloClawCheckoutSuccessClient, SidebarMenuBadge); does not introduce a new Button variant.
  • Trims verbose UX copy: Interests description 33 → 13 words; feature titles drop redundant Read prefix (Read your calendar eventsCalendar events); Calendar subtitle simplified (via OAuth · read-onlyOAuth · Read-only).
  • Fixes a "card-in-card" anti-pattern by removing border + bg-card wrappers around inner content blocks on Calendar and Interests steps.
  • Caps the Interests preview at 6 visible topics + a + N more topics overflow line so the preview shell stays predictably sized when users select many topics, while still being honest about the magnitude.

Verification

  • Walked all four onboarding steps locally via the existing ?fakeOnboardingStep= non-prod route (identity, calendar, email, interests, plus complete and error terminal states). Chat preview renders the fake identity (Aria 🤖) consistently across the three middle steps.
  • Toggled topics on the Interests step: preview updates live, empty-state message renders inside the bubble when no topics, overflow line appears at 7+ topics, cap holds at 6 visible.
  • Connected/disconnected states on Calendar render the correct subtitle (Connected as <email> vs OAuth · Read-only) and the emerald Connected pill only when connected.
  • Copy button on the merged Inbound Email field shows the transient "Copied" state with the emerald check; aria-label updates accordingly.
  • All four primary CTAs render in brand yellow-green; ghost Skip for now buttons render with the bg-accent hover and focus-visible ring.
  • Two-column layout (md:grid-cols-[1fr_2fr]) collapses cleanly to a single column below the md breakpoint.

Visual Changes

Before/after screenshots can be captured by running locally — I don't have a way to attach images from a coding session.

To preview locally:

  1. From a worktree with .env.local: KILO_PORT_OFFSET=auto pnpm dev:start
  2. Read the assigned port from .dev-port
  3. Sign in with ?fakeUser=...&callbackPath=%2Fclaw%2Fnew%3FfakeOnboardingStep%3D<step>
  4. Walk through identity, calendar, email, interests

Reviewer Notes

  • --primary token mismatch left intentionally. apps/web/src/app/globals.css:138 has --primary: oklch(0.922 0 0) (near-white), contradicting design.md and kilo-brand.md which say it should equal the brand yellow-green (oklch(95% 0.15 108)). Flipping the token would turn ~89 unrelated consumers yellow — chat bubbles, message input send button, selected-state cards, payment success buttons, sidebar menu badges, reaction pills. That's a coordinated design-system task. The CTA migration here uses bg-brand-primary className override instead, matching the existing precedent in KiloClawCheckoutSuccessClient.tsx.
  • Sibling CTAs left blue. SettingsTab, OpenClawButton, BillingBanner, WelcomePage, PlanSelectionDialog, AccessLockedDialog, and SubscriptionTab all still use variant="primary" (legacy blue). They're outside the wizard flow so deliberately out of scope for this PR — easy follow-up: grep -rn 'variant="primary"' apps/web/src returns the rest.
  • Email step's copy button is a raw <button> rather than the Button primitive. The merged field needed precise control over self-stretch, border-l divider, rounded-none corners, and hover:bg-muted/60 to integrate cleanly. It still carries focus-visible ring and disabled-state styling consistent with the Button primitive. If a second screen needs the same merged-field affordance, that's the moment to promote it to a Button variant.
  • botIdentity may be null briefly during OAuth resume on the Calendar step. ClawOnboardingFlow.tsx's hydration effect catches this from instanceStatus, but until it fires, the chat preview falls back to DEFAULT_BOT_IDENTITY (KiloClaw 🦾). Sub-second flash, acceptable.
  • ClawOnboardingFakeWalkthrough got a FAKE_BOT_IDENTITY constant (Aria 🤖 / Operator) so the preview reads convincingly when designers/reviewers load steps directly via the fake route without going through Identity first.
  • No DB schema changes, no PII additions, no new dependencies. Pure UI/UX changes against existing components.
  • Error-step CTA also migrated. ClawSetupErrorStep's "Contact Support" button moved from variant="primary" to variant="default" + bg-brand-primary so the brand action color is consistent across all wizard exit states.

Adds a reusable BriefingChatPreview that shows the user's bot identity
sending a sample tomorrow-morning message, used as the left column of
the Calendar / Inbound Email / Interests steps to pay off the Identity
step's personalization across the rest of the wizard.

Tightens visual hierarchy on each step's right column: drops redundant
single-row eyebrows, right-sizes integration tiles to match the chat
preview avatar, swaps the generic Lucide calendar icon for the Google
brand mark, replaces brand-yellow-on-every-row tip tiles with a neutral
numbered list, and merges the inbound email address + Copy button into
a single bordered field.

Migrates the wizard's primary CTAs from legacy blue (variant=primary,
hardcoded #2B6AD2) to brand yellow-green via bg-brand-primary on
variant=default. The semantic --primary token mismatch in globals.css
is intentionally not touched here — flipping the token would affect
~89 other consumers (chat bubbles, message input, selected-state
cards, payment success buttons) that should not be yellow.

Trims verbose copy: Interests description 33 -> 13 words; feature
titles drop redundant 'Read' prefix; Calendar subtitle simplified.
// even when the user picks many topics. Past the cap we collapse the
// remainder into a single "+ N more topics" line so the magnitude is
// still honest without unbounded vertical growth.
const TOPIC_CAP = 6;
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.

SUGGESTION: TOPIC_CAP is a module-level constant but is declared inside the useMemo callback.

It'll be re-evaluated on every memo recalculation and is not visible to callers or tests. Hoist it next to the other module-scope constants (EASE_OUT_QUART, TOPIC_PREVIEW_SAMPLES, etc.):

Suggested change
const TOPIC_CAP = 6;
const TOPIC_CAP = 6;

Wait — to hoist it, replace this line with just the usage reference and declare const TOPIC_CAP = 6; at module scope alongside EASE_OUT_QUART. Since this is a multi-line refactor and the suggestion block can only replace one line, the fix would be:

  1. Remove line 96 (const TOPIC_CAP = 6;) from inside the useMemo
  2. Add const TOPIC_CAP = 6; at module scope (e.g. after line 19 with TAP_EASE)

@kilo-code-bot
Copy link
Copy Markdown
Contributor

kilo-code-bot Bot commented May 20, 2026

Code Review Summary

Status: 1 Issue Found | Recommendation: Merge (minor suggestion only)

Executive Summary

PR is a clean UI polish — new BriefingChatPreview component is well-structured with one minor style note about a constant's placement.

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 1
Issue Details (click to expand)

SUGGESTION

File Line Issue
apps/web/src/app/(app)/claw/components/InterestsStep.tsx 96 TOPIC_CAP = 6 declared inside useMemo callback — hoist to module scope alongside EASE_OUT_QUART / TAP_EASE
Files Reviewed (6 files)
  • apps/web/src/app/(app)/claw/components/BriefingChatPreview.tsx — new file, no issues
  • apps/web/src/app/(app)/claw/components/CalendarConnectStep.tsx — no issues
  • apps/web/src/app/(app)/claw/components/InboundEmailStep.tsx — no issues
  • apps/web/src/app/(app)/claw/components/InterestsStep.tsx — 1 suggestion
  • apps/web/src/app/(app)/claw/components/ClawOnboardingFlow.tsx — no issues
  • apps/web/src/app/(app)/claw/components/ClawOnboardingFakeWalkthrough.tsx — no issues
  • apps/web/src/app/(app)/claw/components/BotIdentityStep.tsx — no issues

Fix these issues in Kilo Cloud


Reviewed by claude-sonnet-4.6 · 1,612,552 tokens

Review guidance: REVIEW.md from base branch main

@Drixled Drixled marked this pull request as draft May 20, 2026 02:37
@Drixled Drixled marked this pull request as ready for review May 20, 2026 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant