Skip to content

feat(tui): make pet mode the main Codewhale view - #6920

Merged
Hmbown merged 6 commits into
mainfrom
feat/tui-native-pet-mode
Oct 9, 2026
Merged

Hmbown merged 6 commits into
mainfrom
feat/tui-native-pet-mode

Conversation

@Hmbown

@Hmbown Hmbown commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

/pet on makes the animated GPUI whale the main Codewhale terminal view while retaining the normal message box, paste, caret, queued messages and permission controls. F5, the clickable replies hint or /pet inspect opens streamed replies, errors and the current session’s real agents. Escape returns to the same view and draft; /pet off restores the standard shell.

The selected view now survives restarts through the existing Settings store and ordered background writer. Appearance settings distinguish the saved choice from the live session. Invalid choices and session overrides do not change the startup preference; failed saves surface a localized warning and preserve malformed settings.

The inspector’s c key and visible footer action invoke the existing /copy command. They copy the last completed assistant receipt with its original Markdown and recovery backup, including while a newer reply streams. Clipboard accepted/queued/failure wording comes from that command. Its transient result stays visible over the completed phase. Hidden or truncated controls leave no click targets. All new controls are translated in the 15 interface languages.

Native animation wakes the existing event loop and follows theme/motion preferences. Stream formatting uses the existing incremental Markdown cache, actual cell revisions and append provenance. Worker opening revalidates current-session identity; missing usage stays unknown. Durable companion world, audio, sessions, prompts and execution keep their existing owners.

Validation of source 4434806df9d0be8d85fd8730bb126841aa17a41e:

  • 60 pet, 9 ordered-writer, 17 routing, 14 copy, 6 toast and 1 localized settings-schema checks passed: 107 TUI checks, 0 failures.
  • Config schema: 4 passed; localization: 54 passed. Total focused Rust checks: 165 passed, 0 failed.
  • npm test: 1,317 passed, 7 skipped, 0 failed; npm run check:web passed.
  • Changed Rust formatting (17 files) and production TUI Clippy passed with CI’s three existing style allowances.
  • Actual renderer checks cover 40×12 through 140×40, dark/light colors, composer/paste/pointer, queued feedback, approval ownership, motion deadlines, streaming cache and copy confirmation. No exhaustive local TUI suite was run.
  • The vendored PetMode remains identical to merged codewhale-ratatui #25; its prior 8 focused tests and 15 hosted checks passed.

The latest slice commits 35 declared paths; this review has 47 paths in total. The clean review ref applies exactly the tested edits while preserving main’s context: 15 updated blobs match source exactly, and 20 retain main’s existing context with identical changed lines. Projected changelogs and all 45 new translated values were checked. Foreign shared documentation/web/avatar work, including two avatar guard lines, is excluded. Hosted CI must qualify this review head.

The 0.10.2 candidate in #6907 is unchanged. Integration into that candidate, a locally installed 0.10.2 binary, real provider use and physical terminal/audio/desktop-owner acceptance remain open under SHA-6533. This PR does not claim release or installed-client qualification.

Refs #6155

Replace the full-screen tank layout with the shared GPUI whale, current-session retained agents, streamed replies/errors and existing notices. Preserve composer/session state, route Enter through the existing agent transcript/approval event, and revalidate painted worker identities. Use the pet view motion policy and canonical completion clip without a second world, prompt or execution owner.

Validation: focused pet/owner/audio/persistence tests 30 passed, 0 failed; keyboard routing 17 passed, 0 failed; draft/focus binding guard 1 passed, 0 failed. Scoped production Clippy passed with the three deliberate project-style allowances from CI; changed-path formatting passed. Library PR #23 merged after all 10 hosted checks passed; local component tests 5+1 passed and idle PTY 7/7 passed, with both 200-frame previews matching actual buffers.

Earlier raw Clippy hit 20 findings in unchanged code covered by those documented style allowances; its failure receipt is retained. Updated two old test assumptions for native availability and context-owned Tab. macOS warned that the large unit-test binary exceeds the compact unwind section limit; test exit was 0. No full local suite, live providers, physical terminal/audio, installed release or simultaneous desktop-owner acceptance claimed.

Stage only 13 declared paths. Saved foreign avatar hunks remain unstaged, including the two adjacent preview guards removed from the index by exact baseline subtraction. This feature stays separate from release-candidate PR #6907. Evidence: artifacts/ratatui-full-pet-20261008; SHA-6533.
Copilot AI balanced review requested due to automatic review settings October 8, 2026 13:29

@devin-ai-integration devin-ai-integration 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.

Devin Review found 4 potential issues.

Devin Review

Comment on lines +411 to +413
state.output_scroll = state
.output_scroll
.min(self.output.len().saturating_sub(usize::from(body.height)));

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.

🟡 Streaming replies stop following new text

When a reply grows beyond the viewport, output_scroll stays at zero while new lines arrive. The user sees the beginning instead of the streaming tail until they scroll manually.

Learn more

The output pane displays an already-wrapped response and stores its current top line in output_scroll. On each redraw, the code clamps that top line only if it exceeds the maximum; it never advances it when streaming adds lines. A new response starts at offset zero, so once its lines fill the pane, later streamed content appears below the visible area. The user must scroll to see whether the reply has progressed.

Example: At 40×12, a response with 20 wrapped lines starts at line zero. When another 20 lines stream in, the visible pane still starts at line zero instead of showing the new lines.

Recommended fix: Track whether the reader has explicitly scrolled away from the tail in PetModeState. Follow appended lines while tail-follow is active, and preserve the existing offset once the reader scrolls up; reset tail-follow on a new turn.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +464 to +470
KeyCode::Tab | KeyCode::BackTab => (1..=agents.len())
.map(|step| {
if key.code == KeyCode::BackTab || key.modifiers.contains(KeyModifiers::SHIFT) {
(index + agents.len() - step) % agents.len()
} else {
(index + step) % agents.len()
}

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.

🟡 Empty agent list crashes on backward Tab

BackTab with an empty roster iterates an empty range, so no modulo runs. This is not a bug.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +297 to +310
view.agent_words = SubagentViewWords {
title: tr(app.ui_locale, MessageId::SubagentsHeaderRoster),
empty: tr(
app.ui_locale,
MessageId::SubagentsNoCurrentSessionFleetWorkers,
),
hints: "".into(),
open: "".into(),
message: "".into(),
stop: "".into(),
summary: Some(agents.len().to_string().into()),
steps_label: Some(tr(app.ui_locale, MessageId::SessionMetricsSteps)),
..Default::default()
};

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.

🔍 Agent details bypass localized labels

Wide-screen agent details retain English activity, output, toggle_output, and no_events defaults because the host overrides only some SubagentViewWords fields.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread crates/tui/src/tui/pet_watch/full.rs Outdated
Comment on lines +212 to +227
let response = app
.history
.iter()
.skip(app.pet_watch.work_history_start)
.chain(
app.active_cell
.as_ref()
.into_iter()
.flat_map(|cell| cell.entries()),
)
.rfind(|cell| {
matches!(
cell,
HistoryCell::Assistant { .. } | HistoryCell::Error { .. }
)
});

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.

🔍 Pet result selects only the last reply

A turn with multiple assistant messages shows only its last assistant message or error. Earlier replies remain in the normal transcript; clarify whether the pet result intentionally omits them.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Copilot AI 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.

🟡 Changes recommended

Streamed responses and long agent outputs currently incur repeated full-content processing that can stall the TUI.

1 open finding
What changed in this PR

Integrates the native Ratatui pet experience into the live TUI Engine session, combining animated whale rendering, streamed responses, notices, and retained agents.

Changes:

  • Adds native pet, roster, response, and pixel-rendering components.
  • Connects pet mode to live session state, motion policy, and agent transcripts.
  • Adds keyboard, mouse, visibility, and rendering coverage.
File Description
vendor/​codewhale-ratatui/​src/​whale_motion/​pixels.rs Adds bounded RGBA whale rendering.
vendor/​codewhale-ratatui/​src/​whale_motion/​mod.rs Registers the pixel renderer.
vendor/​codewhale-ratatui/​src/​whale_motion/​acting.rs Exposes completion-animation state.
vendor/​codewhale-ratatui/​src/​components/​whale_pet.rs Adds the native whale widget.
vendor/​codewhale-ratatui/​src/​components/​subagents.rs Adds retained-agent roster and detail views.
vendor/​codewhale-ratatui/​src/​components/​pet_mode.rs Composes the full pet-mode surface.
vendor/​codewhale-ratatui/​src/​components/​mod.rs Exports new components.
vendor/​codewhale-ratatui/​src/​avatar_sprite.rs Adds single-image sprite construction.
crates/​tui/​src/​tui/​ui/​tests.rs Extends shell-binding coverage.
crates/​tui/​src/​tui/​shell_key_routing.rs Adds pet navigation bindings.
crates/​tui/​src/​tui/​pet_watch/​mod.rs Integrates native pet state and controls.
crates/​tui/​src/​tui/​pet_watch/​habitat.rs Routes modal input and transcript opening.
crates/​tui/​src/​tui/​pet_watch/​full.rs Projects live Engine state into pet mode.

🧠 Review effort: Balanced


Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.

Comment thread crates/tui/src/tui/pet_watch/full.rs Outdated
Comment on lines +241 to +243
if app.pet_watch.full_response_key != Some(key) {
app.pet_watch.full_response = None;
app.pet_watch.full_response_key = Some(key);
Describe the actual session view and its controls under Unreleased. Link the
shared component provenance and state its boundary from the separate 0.10.2
candidate; this satisfies the feature-note receipts required by the original
feature commit without changing that candidate or claiming a release.

Validation: the PR-scoped feature-note check passed for both required linked
references (2 checked); changed-path whitespace check passed. Product code is
unchanged from the 48 passing focused Engine checks and passing scoped
production Clippy/formatting receipts. No Rust suite was repeated for prose.

SHA-6533; Refs #6155. Evidence: artifacts/ratatui-full-pet-20261008/.
Apply the shared PetMode stream-follow correction: appended replies remain
visible until the reader scrolls back, End or reaching the bottom resumes
following, and the existing turn-start event resets the presentation state.
Reuse canonical Director turn identity. Supply localized status/result words
for the retained agent pane and leave unprojected event receipts blank; Enter
continues to open the existing full transcript.

Validation: 31 focused pet/owner/audio/persistence tests passed, 0 failed,
including streamed-tail mutation through the real ActiveCell cache and French
agent details. Prior 17 routing tests and 1 draft/focus guard remain green;
their code was unchanged and they were not repeated. Scoped production Clippy
with CI's deliberate style allowances and changed-path formatting passed.
The matching shared library has 6 passing PetMode integration tests, locked
all-target Clippy with warnings denied and formatting. No full local suite,
installed release, physical terminal/audio or live provider journey claimed.

Only three declared paths are staged. The avatar author's two preview guards
are preserved unstaged by exact index-only baseline subtraction. The reading
correction is separately reviewed in the shared library. SHA-6533; Refs #6155.
Evidence: artifacts/ratatui-full-pet-20261008/.
CodeWhale Bot added 2 commits October 8, 2026 06:49
Regenerate the packaged /change notes from the root changelog with the existing
sync script. This repairs the missing generated copy reported by Version drift
without changing product code, version numbers or the separate candidate.

Validation: changelog sync check passed; the version-state gate passed with
range audits advisory (40 global feature references checked; workspace, npm,
binary pin and lockfile all 0.10.1); changed-path whitespace check passed.
The PR-scoped feature-note check already passed for its 2 required references.
Only 10 generated prose lines changed. The 49 focused Engine checks and scoped
Clippy/formatting receipts are unchanged and were not repeated for prose.

SHA-6533; Refs #6155. Evidence: artifacts/ratatui-full-pet-20261008/.
/pet on now selects the native whale backdrop with the existing composer,
queue feedback and permission controls. F5, the painted hint and /pet inspect
open the same replies/agents inspector; Escape returns to the existing draft.
The standard transcript, metrics and work rail yield their space and hitboxes.
Explicit tools and focused worker transcripts remain available on demand.

Schedule native idle motion through the existing poll loop and honor the
selected palette. Localize all new controls in 15 packs. Keep incremental
reply formatting across streamed revisions and view changes using the actual
source identity, revision and existing append receipt; unknown edits revoke
provenance and rebuild correctly. No prompt/session/execution authority added.

Validation: 54 focused pet tests, 17 routing tests and 1 draft/focus guard
passed (72 checks, 0 failures); localization 54 passed, 0 failed. npm test:
1,317 passed, 7 skipped, 0 failed; npm run check:web passed. Changed Rust
formatting and scoped production Clippy with CI's 3 style allowances passed.
Five terminal sizes, both themes, composer paste/caret/mouse, queue visibility,
approval ownership, idle deadlines and incremental/rewrite fallback are covered.
Actual Engine buffer captures are under artifacts/ratatui-pet-main-20261008.

The vendored PetMode matches merged codewhale-ratatui #25 (6f0ab44) exactly;
its 8 focused tests and all 15 hosted checks passed. Stage only this slice's
31 paths, excluding the avatar author's two guard lines in pet_watch/mod.rs.
Physical terminal/audio/provider and installed/released acceptance stay open.
The 0.10.2 candidate #6907 is untouched.

Refs #6920, #6155
@Hmbown Hmbown changed the title feat(tui): use native full pet mode for the real Engine session feat(tui): make pet mode the main Codewhale view Oct 8, 2026
Persist /pet on|off through Settings and the existing ordered background
writer. Restore the main pet backdrop without the launch overlay. The
Appearance setting reports saved and effective values separately; session
only overrides and rejected values leave the startup choice alone.

The inspector's c key and painted footer target invoke /copy, retaining its
completed-answer receipt, raw Markdown, recovery backup and queued-vs-accepted
clipboard wording. A bounded command receipt remains visible over Done.
Hidden, resized and truncated footer targets are cleared before input.
All three new labels are translated in the fifteen complete locale packs.

Validation, final source:
- Pet: 60 passed, 0 failed (restart/order/shutdown, malformed settings, drafts,
  real keyboard/pointer routes, copy authority and dark/light renderer).
- Ordered writer: 9 passed; shell routing: 17 passed; /copy: 14 passed;
  toast lifecycle: 6 passed; localized settings schema: 1 passed. No failures.
- Config schema: 4 passed; localization: 54 passed. Total: 165 passed, 0 failed.
- npm test: 1,317 passed, 7 skipped, 0 failed (545 Node + 772 Vitest).
- npm run check:web passed. Changed Rust formatting: 17 files passed.
- Production TUI Clippy passed with -D warnings and the CI's existing
  uninlined_format_args, too_many_arguments and unnecessary_map_or allowances.

Earlier local receipts retained: a test import used a retired private command
path (E0433), then the first compiled run passed 58 and failed 1 because its
unknown-key fixture assumed preservation beyond the existing serializer's
contract. Tests now use the public command entry and supported preference
annotations; malformed TOML remains byte-preserved. Final checks above pass.

Stage only 35 declared paths. Preserve unrelated shared documentation/web/
avatar changes, including the two avatar guards in pet_watch/mod.rs. The
shared library remains the merged #25 component; no new execution authority.
This source slice updates #6920. Actual 0.10.2 candidate #6907 integration,
local installed binary and live terminal/provider acceptance remain separate.

Refs SHA-6533
@Hmbown
Hmbown merged commit 80e1d2a into main Oct 9, 2026
33 of 36 checks passed
@Hmbown
Hmbown deleted the feat/tui-native-pet-mode branch October 9, 2026 05:02
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.

2 participants