Skip to content

fix(vscode): correct accent tokens and share one token-speed measurement - #21

Merged
elkaix merged 2 commits into
mainfrom
fix/vscode-accent-tokens-and-token-speed
Aug 5, 2026
Merged

fix(vscode): correct accent tokens and share one token-speed measurement#21
elkaix merged 2 commits into
mainfrom
fix/vscode-accent-tokens-and-token-speed

Conversation

@elkaix

@elkaix elkaix commented Aug 5, 2026

Copy link
Copy Markdown
Member

Related Issue

No issue — reported directly with screenshots of the extension sidebar.

Problem

Four defects, three of them rooted in one bad token.

--primary was oklch(0.21 0.006 285.885) in both the light and dark blocks. In dark mode that is darker than the unchecked switch track (--input, oklch 0.274) and barely above the background, so:

  • a Switch turning on got visually darker than when it was off
  • anything built on bg-primary read as an unstyled dark chip, which is why accents had drifted to hardcoded blue-400/blue-500 in individual components

Separately, generation speed was measured per component. TokenInfo and ChatStatus are mounted together and both call useTokenSpeed, so each kept its own start timestamp and token baseline and averaged over a different window — the header and the expanded panel showed different rates for the same response. The sampler also listed the token count as an effect dependency, so it was torn down and recreated on every streamed chunk and never survived its own 250ms interval while tokens arrived faster than that.

What changed

  • --primary points at the CLI periwinkle per theme (#4a5bc4 light, #bbc6ff dark), matching apps/pythinker-code/src/tui/theme/colors.ts.
  • New --success token (CLI success, #0e7a38 / #4ec87e) drives the switch "on" state, so on/off is unambiguous rather than two near-identical darks.
  • Switch geometry: p-[2px] for an even thumb inset. The old 18.4px track with a 16px thumb left ~0.6px above and below but 2px at the travel end.
  • useTokenSpeed now measures once in a module-level sampler that consumers subscribe to via useSyncExternalStore, and the sampler no longer depends on the token count. The readout no longer wraps 74.7 and t/s onto separate lines, and uses tabular-nums so the pill does not resize as the rate changes.
  • The scroll-to-bottom button and the effort toggle move from hardcoded blue to bg-primary.
  • --muted-foreground moves from a near-neutral grey to the CLI periwinkle; the previous value sat too close to the background to read at 11px.

Not included

Hardcoded blue-* classes remain in 11 other components (QuestionDialog, ApprovalDialog, MCPServersModal, ToolRenderers, Markdown, SessionList, CompactionCard, ChatMessage, LoginScreen, WorkDirModal, ThinkingButton hover states). Now that --primary is correct they can be migrated to the token, but that is a wider sweep than this fix and is left for a follow-up.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works. — presentational; verified by typecheck, build:webview, and asserting the emitted CSS custom properties and the data-checked:bg-success rule in the bundle.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

[skip changeset] — every changed file is under apps/vscode, whose package (pythinker-code) is private: true and is not published by changesets. Nothing here enters the @pythoughts/pythinker-code CLI bundle.

Summary by CodeRabbit

  • Enhancements

    • Improved generation-speed tracking for smoother, consistent status updates.
    • Prevented status text from wrapping and improved numeric readability.
    • Updated switch behavior, sizing, and transitions for a more consistent interface.
  • Style

    • Refreshed light and dark theme colors with updated brand and success colors.
    • Improved contrast and theme consistency across chat controls and interactive elements.
    • Updated chat scrolling and thinking controls to better use the active theme.

--primary was oklch(0.21) in both themes: a near-black that sits DARKER than
the unchecked --input (oklch 0.274) and barely above the dark background. Every
accent surface built on it read as an unstyled dark chip, and a Switch turning
on visibly got darker instead of lighting up. Point --primary at the CLI
periwinkle per theme, and give toggles their own --success token so the on state
is unambiguous.

Switch geometry: p-[2px] gives the thumb an even inset. The old 18.4px track
with a 16px thumb left ~0.6px above and below but 2px at the travel end, which
read as a blob rather than a track.

Token speed had two defects. useTokenSpeed kept per-hook state while both
TokenInfo and ChatStatus call it, so each measured from its own mount time and
the header and expanded panel disagreed about the same stream; the measurement
now lives in one module-level sampler that every consumer subscribes to. The
sampler also depended on the token count, so it was torn down and recreated on
every streamed chunk and never survived its own 250ms interval on fast streams.
The readout no longer wraps '74.7' and 't/s' onto separate lines.

Secondary text moves from a near-neutral grey to the CLI periwinkle, which was
too close to the background to read at 11px.
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 30692ca6-9f6d-437f-8bf1-4a4d9046f809

📥 Commits

Reviewing files that changed from the base of the PR and between 4670c71 and aa3b340.

📒 Files selected for processing (1)
  • apps/vscode/webview-ui/src/components/ui/switch.tsx

📝 Walkthrough

Walkthrough

The webview updates theme colors, switch geometry, button styling, and generation-speed display formatting. useTokenSpeed now shares one 250ms measurement sampler across consumers and resets speed when streaming ends.

Changes

Webview theme and status updates

Layer / File(s) Summary
Theme color tokens
apps/vscode/webview-ui/src/styles/index.css
Light and dark themes use updated primary and muted-foreground colors. Success colors are defined and exposed to Tailwind.
Control styling
apps/vscode/webview-ui/src/components/ChatArea.tsx, apps/vscode/webview-ui/src/components/ThinkingButton.tsx, apps/vscode/webview-ui/src/components/ui/switch.tsx, apps/vscode/webview-ui/src/components/ChatStatus.tsx
Buttons use theme primary colors. The switch uses success styling, fixed geometry, padded tracks, and color-only transitions. Speed indicators prevent wrapping and use tabular numerals.
Shared token-speed measurement
apps/vscode/webview-ui/src/components/ChatStatus.tsx
useTokenSpeed shares module-level state and a persistent 250ms sampler. Streaming end clears the timer and resets speed.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ChatStatus
  participant useTokenSpeed
  participant SharedSpeedStore
  participant Sampler250ms
  ChatStatus->>useTokenSpeed: provide token count and streaming state
  useTokenSpeed->>SharedSpeedStore: update latest token count
  useTokenSpeed->>Sampler250ms: start one measurement window
  Sampler250ms->>SharedSpeedStore: publish token speed
  SharedSpeedStore-->>ChatStatus: notify subscribed speed value
  ChatStatus->>useTokenSpeed: end streaming
  useTokenSpeed->>Sampler250ms: clear timer and reset speed
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title uses the fix prefix, stays within 72 characters, uses imperative wording, and clearly summarizes the token and token-speed changes.
Description check ✅ Passed The description includes the required sections, explains the problem and changes, documents validation, and explains why no issue or changeset applies.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

@pkg-pr-new

pkg-pr-new Bot commented Aug 5, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@pythoughts/pythinker-code@aa3b340
npx https://pkg.pr.new/@pythoughts/pythinker-code@aa3b340

commit: aa3b340

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/vscode/webview-ui/src/components/ChatStatus.tsx (1)

2-3: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use the #/ import alias.

Replace the @/stores and @/lib/utils imports with their #/ equivalents.

As per coding guidelines, prefer imports using import ... from '#/...' rather than the equivalent @/... alias.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/vscode/webview-ui/src/components/ChatStatus.tsx` around lines 2 - 3,
Update the import statements in ChatStatus to use the `#/` alias instead of `@/`
by changing the existing `useChatStore`, `useSettingsStore`, and `cn` imports to
their `#/stores` and `#/lib/utils` equivalents. Keep the rest of the component
unchanged and only adjust the import paths in this file.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/vscode/webview-ui/src/components/ui/switch.tsx`:
- Line 38: Update the switch thumb classes in the visible className to use
data-checked:bg-success-foreground instead of data-checked:bg-white, and change
the checked translation offsets to 12px for the default size and 8px for the
small size. Preserve the unchecked offsets and all other styling.

---

Nitpick comments:
In `@apps/vscode/webview-ui/src/components/ChatStatus.tsx`:
- Around line 2-3: Update the import statements in ChatStatus to use the `#/`
alias instead of `@/` by changing the existing `useChatStore`,
`useSettingsStore`, and `cn` imports to their `#/stores` and `#/lib/utils`
equivalents. Keep the rest of the component unchanged and only adjust the import
paths in this file.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8039ea98-f087-44f6-8db8-e32cda966963

📥 Commits

Reviewing files that changed from the base of the PR and between f27649d and 4670c71.

📒 Files selected for processing (5)
  • apps/vscode/webview-ui/src/components/ChatArea.tsx
  • apps/vscode/webview-ui/src/components/ChatStatus.tsx
  • apps/vscode/webview-ui/src/components/ThinkingButton.tsx
  • apps/vscode/webview-ui/src/components/ui/switch.tsx
  • apps/vscode/webview-ui/src/styles/index.css

Comment thread apps/vscode/webview-ui/src/components/ui/switch.tsx Outdated
@elkaix
elkaix merged commit 070d902 into main Aug 5, 2026
12 checks passed
@elkaix
elkaix deleted the fix/vscode-accent-tokens-and-token-speed branch August 5, 2026 13:40
elkaix added a commit that referenced this pull request Aug 5, 2026
The periwinkle that #21 wrote into --primary and --muted-foreground tinted
every neutral surface, so both tokens go back to their original oklch values.
The accent it was compensating for now lives in its own --brand token, applied
only where an accent is actually wanted: inline code in Markdown, and the
DynamicWorkflow lane bars and running status dot, which were invisible against
--muted once --primary went back to a near-black neutral.

The scroll-to-bottom button and the effort toggle return to their blue accents
for the same reason.

Also:
- a finished workflow lane renders a full bar. The bar is scaled to the busiest
  agent, so a lane that completed in fewer steps kept a permanent gap.
- the generation-speed pill in the thinking row no longer wraps "46.0" and
  "t/s" onto two lines, and uses tabular-nums so it stops resizing.
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