Skip to content

feat(web): refine model and workbench controls - #5

Merged
boh5 merged 6 commits into
mainfrom
codex/split-model-variant-picker
Jul 29, 2026
Merged

feat(web): refine model and workbench controls#5
boh5 merged 6 commits into
mainfrom
codex/split-model-variant-picker

Conversation

@boh5

@boh5 boh5 commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Summary

  • split model and variant selection into two explicit, independently searchable controls while preserving requested selection semantics
  • keep sidebar and inspector toggles in page headers across the workbench, with shared accessible presentation and responsive coverage
  • stabilize the real-Git managed-claim integration scenario by isolating it from Bun's flaky asynchronous piped-spawn path

Why

The combined model picker made model identity and option variants harder to scan and change independently. Panel controls also moved with panel content instead of remaining available from stable page headers. The managed-claim test exercised the intended Git lifecycle but could fail in Bun's asynchronous piped-spawn path rather than on product behavior.

This keeps each control aligned with the state it owns and preserves the real-Git integration coverage with a deterministic process adapter scoped to the test.

Validation

  • bun run typecheck
  • bun run test
  • bun run build when the production package or Web UI is affected
  • git diff --check origin/main...HEAD

Documentation and security

  • User-facing documentation is not required; this refines existing controls without changing setup or configuration contracts.
  • I added or updated tests for behavior changes.
  • I did not commit credentials, tokens, private configuration, or generated secrets.
  • No security or trust-boundary behavior changes.

Related issue

None.

Review in cubic

Summary by CodeRabbit

  • New Features
    • Added consistent sidebar toggle controls across dashboard, automation, project, and session views.
    • Introduced a unified panel toggle control for expanding/collapsing sidebar and inspector panels.
    • Redesign model selection into separate Model and Variant menus with search, compact UI, and improved selection feedback.
  • Bug Fixes
    • Improved responsive behavior for toggle visibility and updated accessibility/styling for panel controls.
    • Removed focus-mode controls/settings and updated related navigation and focus restoration behavior.

@coderabbitai

coderabbitai Bot commented Jul 29, 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 Plus

Run ID: 4221e61e-69f1-4e65-b05c-95dec686807c

📥 Commits

Reviewing files that changed from the base of the PR and between dc8b402 and bf5d079.

📒 Files selected for processing (3)
  • apps/web/src/components/features/ModelPicker.test.tsx
  • apps/web/src/components/features/ModelPicker.tsx
  • packages/agent-core/src/worktrees/service-managed-claim.integration.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/agent-core/src/worktrees/service-managed-claim.integration.test.ts
  • apps/web/src/components/features/ModelPicker.tsx
  • apps/web/src/components/features/ModelPicker.test.tsx

📝 Walkthrough

Walkthrough

The web workbench adds shared sidebar and inspector toggles, removes focus-mode state, restructures layout behavior, and refactors ModelPicker into separate model and variant popovers. Route headers and interaction tests are updated, alongside a synchronous Git runner for an agent-core integration test.

Changes

Web workbench controls and selection

Layer / File(s) Summary
Model and variant picker flow
apps/web/src/components/features/ModelPicker.tsx, apps/web/src/components/features/ModelPicker.test.tsx, apps/web/src/components/features/ChatInput.tsx, apps/web/src/components/features/compact-control-surface.test.ts
Model selection now uses separate model and variant popovers with search, keyboard navigation, revised selection payloads, availability handling, and next-execution messaging.
Shared panel toggle controls
apps/web/src/components/features/PanelToggleButton.tsx, apps/web/src/components/features/SidebarToggleButton.tsx, apps/web/src/components/features/InspectorToggleButton.tsx, apps/web/src/components/features/Sidebar.tsx, apps/web/src/components/features/ContextInspector.tsx, apps/web/src/components/features/ChatHeader.tsx
PanelToggleButton centralizes panel accessibility and icon behavior; sidebar and inspector controls use it while former inline collapse controls are removed.
Workbench layout state and shell
apps/web/src/context/workbench-layout.tsx, apps/web/src/lib/workbench-layout.ts, apps/web/src/routes/root-layout.tsx, apps/web/src/routes/root-layout.interaction.tsx, apps/web/src/context/workbench-layout.interaction.tsx
Focus-mode state and persistence are removed, mobile surface setters are exposed, focus targeting is updated, and desktop/mobile shell rendering is simplified.
Route headers and layout test wiring
apps/web/src/routes/automation-detail.tsx, apps/web/src/routes/automations.tsx, apps/web/src/routes/dashboard.tsx, apps/web/src/routes/project-todos.tsx, apps/web/src/routes/session.tsx, apps/web/package.json, apps/web/src/routes/*test.tsx, apps/web/src/components/features/ChatHeader.test.tsx
Route headers add sidebar toggles, dashboard rendering is scope-dependent, tests provide layout context, and the interaction test command uses an updated entry-file list.

Agent worktree integration test

Layer / File(s) Summary
Synchronous Git test runner
packages/agent-core/src/worktrees/service-managed-claim.integration.test.ts
The managed-claim test uses a Bun.spawnSync-backed ProcessRunner, compares validation output with a precomputed HEAD SHA, and verifies bounded output metadata.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.06% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately reflects the PR’s main changes to model and workbench controls.
Description check ✅ Passed The description matches the template and covers summary, why, validation, documentation/security, and related issue.
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.

@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 (3)
apps/web/src/components/features/ModelPicker.tsx (1)

42-64: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Home/End are hijacked while typing in the search field.

movePickerFocus is bound on the popover, so keystrokes from the search input bubble into it. Home/End call preventDefault() and move focus to the first/last option, breaking caret navigation in the query. Consider restricting Home/End handling to [data-picker-option] targets.

♻️ Proposed guard
 function movePickerFocus(
   event: React.KeyboardEvent<HTMLElement>,
   root: HTMLDivElement | null,
 ): void {
   if (!["ArrowDown", "ArrowUp", "Home", "End"].includes(event.key)) return;
+  const fromOption = (event.target as HTMLElement)?.hasAttribute?.("data-picker-option") ?? false;
+  if (!fromOption && (event.key === "Home" || event.key === "End")) return;
   const options = Array.from(
🤖 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/web/src/components/features/ModelPicker.tsx` around lines 42 - 64,
Update movePickerFocus so Home and End are handled only when event.target is a
[data-picker-option] element; allow those keys to bubble normally from the
search input without preventDefault or focus movement, while preserving existing
option navigation behavior.
apps/web/src/components/features/ModelPicker.test.tsx (2)

406-419: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Arrow navigation is only covered for the variant menu.

The model popover is the one with the search input and the Home/End interaction, and Escape's focus restoration to the originating trigger is untested. Adding a case that opens the model picker on a large catalog and arrows down from the search field would cover the riskier path.

🤖 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/web/src/components/features/ModelPicker.test.tsx` around lines 406 -
419, Extend the ModelPicker keyboard-navigation tests with a large-catalog case
that opens the model popover, focuses its search input, and verifies ArrowDown
moves focus to the expected model option. Locate the existing
renderPicker/openVariantPicker helpers and model-popover/search-input selectors,
and preserve the current variant-menu test while covering Escape focus
restoration if the surrounding test setup supports it.

120-136: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Simplify changeSearch to the public input path. This is already a controlled <input type="search">; setting the native value and dispatching a bubbling input event should drive onChange, so the _valueTracker / __reactProps$… fallback can be removed.

🤖 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/web/src/components/features/ModelPicker.test.tsx` around lines 120 -
136, Simplify the changeSearch helper to set the search input’s native value and
dispatch a bubbling input event through the public DOM path. Remove the
_valueTracker manipulation, React __reactProps$ lookup, direct onChange
invocation, and related fallback logic while preserving the existing input
lookup and act wrapper.
🤖 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 `@packages/agent-core/src/worktrees/service-managed-claim.integration.test.ts`:
- Around line 68-96: Update the sync runner’s Bun.spawnSync invocation to pass
input.maxOutputBytes through the supported maxBuffer option, ensuring stdout and
stderr are capped consistently with the normal runner. Derive the output and
truncation metadata from the capped result so the byte counts and truncation
flags accurately reflect whether either stream exceeded the configured limit.

---

Nitpick comments:
In `@apps/web/src/components/features/ModelPicker.test.tsx`:
- Around line 406-419: Extend the ModelPicker keyboard-navigation tests with a
large-catalog case that opens the model popover, focuses its search input, and
verifies ArrowDown moves focus to the expected model option. Locate the existing
renderPicker/openVariantPicker helpers and model-popover/search-input selectors,
and preserve the current variant-menu test while covering Escape focus
restoration if the surrounding test setup supports it.
- Around line 120-136: Simplify the changeSearch helper to set the search
input’s native value and dispatch a bubbling input event through the public DOM
path. Remove the _valueTracker manipulation, React __reactProps$ lookup, direct
onChange invocation, and related fallback logic while preserving the existing
input lookup and act wrapper.

In `@apps/web/src/components/features/ModelPicker.tsx`:
- Around line 42-64: Update movePickerFocus so Home and End are handled only
when event.target is a [data-picker-option] element; allow those keys to bubble
normally from the search input without preventDefault or focus movement, while
preserving existing option navigation behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 2712dd7e-4efe-484f-89f9-09e4803f17c6

📥 Commits

Reviewing files that changed from the base of the PR and between ee62f7e and dc8b402.

📒 Files selected for processing (31)
  • apps/web/package.json
  • apps/web/src/components/features/ChatHeader.test.tsx
  • apps/web/src/components/features/ChatHeader.tsx
  • apps/web/src/components/features/ChatInput.tsx
  • apps/web/src/components/features/ContextInspector.tsx
  • apps/web/src/components/features/InspectorToggleButton.interaction.tsx
  • apps/web/src/components/features/InspectorToggleButton.tsx
  • apps/web/src/components/features/ModelPicker.test.tsx
  • apps/web/src/components/features/ModelPicker.tsx
  • apps/web/src/components/features/PanelToggleButton.tsx
  • apps/web/src/components/features/Sidebar.interaction.tsx
  • apps/web/src/components/features/Sidebar.tsx
  • apps/web/src/components/features/SidebarToggleButton.interaction.tsx
  • apps/web/src/components/features/SidebarToggleButton.tsx
  • apps/web/src/components/features/compact-control-surface.test.ts
  • apps/web/src/context/workbench-layout.interaction.tsx
  • apps/web/src/context/workbench-layout.tsx
  • apps/web/src/lib/workbench-layout.test.ts
  • apps/web/src/lib/workbench-layout.ts
  • apps/web/src/routes/automation-detail.tsx
  • apps/web/src/routes/automations.tsx
  • apps/web/src/routes/dashboard.test.tsx
  • apps/web/src/routes/dashboard.tsx
  • apps/web/src/routes/project-todos.interaction.tsx
  • apps/web/src/routes/project-todos.test.tsx
  • apps/web/src/routes/project-todos.tsx
  • apps/web/src/routes/root-layout.interaction.tsx
  • apps/web/src/routes/root-layout.tsx
  • apps/web/src/routes/session.test.tsx
  • apps/web/src/routes/session.tsx
  • packages/agent-core/src/worktrees/service-managed-claim.integration.test.ts
💤 Files with no reviewable changes (5)
  • apps/web/src/components/features/Sidebar.interaction.tsx
  • apps/web/src/lib/workbench-layout.test.ts
  • apps/web/src/components/features/ChatInput.tsx
  • apps/web/src/context/workbench-layout.interaction.tsx
  • apps/web/src/lib/workbench-layout.ts

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 31 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread apps/web/src/components/features/ModelPicker.tsx
@boh5
boh5 merged commit 6be34a4 into main Jul 29, 2026
7 checks passed
@boh5
boh5 deleted the codex/split-model-variant-picker branch July 29, 2026 12:57
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