Skip to content

Feat/pet bubble scroll and dark mode#6

Merged
BinaryFroggy merged 3 commits into
mainfrom
feat/pet-bubble-scroll-and-dark-mode
May 9, 2026
Merged

Feat/pet bubble scroll and dark mode#6
BinaryFroggy merged 3 commits into
mainfrom
feat/pet-bubble-scroll-and-dark-mode

Conversation

@BinaryFroggy
Copy link
Copy Markdown
Owner

fix(ipc): drop terminal-state branch in stale-sibling pruning

pruneStaleSiblings previously treated any non-running sibling as fair game and pruned it on sight. The problem: idle is not a terminal state — it is the resting state between turns (responding → completed → idle), so a legitimate sibling panel that just finished answering would be pruned within seconds. In IDEs with multiple chat panels (Cursor) or terminals with multiple tabs running the same cwd, this killed real concurrent sessions.

Activity timeout (lastActivityAt > 90s) is now the sole criterion. State enum no longer participates.

feat(pet): scroll bubble list with pixel scroll thumb

The bubble stack was a fixed VStack with a hard 5-bubble cap (prefix(5)); older sessions silently disappeared from view. Now the stack lives inside a ScrollView, soft-capped at roughly five default cards' worth of height. When content overflows, the oldest bubble stays anchored to the pet's head (preserving the "first bubble glued to the seal" semantic) and newer bubbles spill off the top. A pixel-styled thumb on the right edge hints at the hidden content; it is indicative only and does not handle drag.

The scroll metrics (content height + offset) are surfaced via a single PreferenceKey and stored as one @State struct so SwiftUI's Equatable dedup suppresses the no-op writes that the 1Hz now timer would otherwise trigger.

feat(pet): adapt PixelChrome to dark color scheme

PixelChrome and PixelScrollThumb now read @Environment(.colorScheme) and switch base fill, accent tint, and top highlight between light and dark. Accent tint is intentionally stronger in dark mode (40% vs 10%) so state colors stay legible against the deeper neutral surface — including the brightest askUser yellow, which still clears 4:1 contrast against .primary white text.

The previous predicate pruned any non-running sibling session sharing
the same cwd as a new session. But `idle` is not a terminal state —
it is the resting state between turns (responding → completed → idle),
so a legitimate sibling panel that just finished answering would be
pruned within seconds. Use activity timeout as the sole criterion.
Wrap the bubble stack in a ScrollView capped at roughly five default
cards. When content overflows, the oldest bubble stays anchored to
the pet's head (the "first bubble" semantic) and newer bubbles spill
off the top. A pixel-styled thumb on the right edge hints at hidden
content; it is indicative only and does not handle drag.
PixelChrome now reads the environment color scheme and switches its
neutral surface, accent tint, and top highlight between light and
dark. Accent tint is stronger in dark mode so state colors remain
legible against the deeper base, including the brightest askUser
yellow.
@BinaryFroggy BinaryFroggy merged commit c240689 into main May 9, 2026
1 check passed
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