You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
screen.ai_panel is the 14th and last field from #592's table, and the only one still
unpainted on GTK. #670 (part B of the epic) covered four of the five panel surfaces in its
group — quickfix, bottom_tabs, debug_toolbar, panel_hover — and deferred the fifth.
Its own code comment records the deferral and points at a follow-up issue that was never
filed:
// src/gtk/mod.rs:9364-9369
_ => {// PANEL_AI and unknowns: not yet migrated to Backend// primitives (#670 scoped only the other four panel// surfaces — quickfix/bottom_tabs/debug_toolbar/// panel_hover — and left AI for a follow-up issue; see// that issue's own "no PANEL_AI arm at all" note).}
So #592 reads as complete (all four children A–D closed) while one of its 14 fields is
still on the floor. This issue is that follow-up, and #592 should not close until it lands.
Current state
Paint.render_content's sidebar-panel match (src/gtk/mod.rs:9351-9371) has arms for PANEL_SETTINGS, ext:*, and the rest; PANEL_AI falls into the empty _ =>. Selecting
the AI panel from the activity bar on GTK therefore shows an empty sidebar body.
Click.try_route_sidebar_mouse_event (:7325-7327) has the matching holdout and
comments it honestly:
// PANEL_AI and unknowns are not painted through `render_content`// yet (same `_ =>` holdout that arm has), so there is nothing for a// click to hit — let it fall through rather than swallow it.
_ => false,
That is the right call while paint is missing, and it becomes wrong the moment paint lands
— both halves must change together.
Dead handles.ai_sidebar_da_ref (:558) and ai_panel_box_ref (:572) are two of the
22 permanently-None Relm4-era widget handles. :3170, :6574, :6584, :6602 read ai_sidebar_da_ref inside if let Some(…) arms that never run, and handle_ai_sidebar_msg
(:6549) is reached only through the Msg bus. None of it paints anything. Delete on the
way through, or leave to the orphan-handle sweep — but do not wire new code to either
handle.
TUI reference.render_ai_sidebar (src/tui_main/panels.rs:1168, 180 lines) is the
working implementation. Read it first; the GTK arm should call the same shared builder, not
re-derive the layout.
Design
Follow #670's own pattern exactly — it is the template this issue is a straggler from:
If a shared render:: builder for the AI panel does not exist, add one (mirroring render::populate_ext_sidebar_system / populate_settings_form_controller), and have TUI's render_ai_sidebar call it too so this lands as convergence, not a second
implementation. A GTK arm that duplicates TUI's 180 lines is the failure mode CLAUDE.md's Platform-Neutrality Rule exists to stop.
Add the PANEL_AI arm to render_content's match, painting through Backend primitives
at q_sb like its siblings.
⚠️ Line numbers in this body drift — locate by symbol
Every line number above was measured on develop @ 4872ab9 (2026-09-01). They are
already wrong.#727 landed src/gtk/mod.rs +435/−44 within hours and moved enum Msg 1096→1131, fn dispatch 1799→1896, sync_scrollbar 2657→2754. Seven more
issues sit ahead of this one in the chain, each deleting or moving thousands of lines.
Treat the numbers as provenance — proof the claim was verified once — never as
coordinates. Locate by these anchors instead:
grep -n "PANEL_AI and unknowns" src/gtk/mod.rs # both holdouts, paint + click
grep -n "fn try_route_sidebar_mouse_event" src/gtk/mod.rs
grep -n "fn render_ai_sidebar" src/tui_main/panels.rs # the working reference
This is the same defect #734 exists to fix: src/tui_main/ carries 19 mirrors mod.rs:NNNN comments whose targets all drifted after #540, leaving the only
record of a cross-backend contract pointing at unrelated code. Do not re-point the
numbers when they rot — the anchors are the durable form.
Summary
screen.ai_panelis the 14th and last field from #592's table, and the only one stillunpainted on GTK. #670 (part B of the epic) covered four of the five panel surfaces in its
group —
quickfix,bottom_tabs,debug_toolbar,panel_hover— and deferred the fifth.Its own code comment records the deferral and points at a follow-up issue that was never
filed:
So #592 reads as complete (all four children A–D closed) while one of its 14 fields is
still on the floor. This issue is that follow-up, and #592 should not close until it lands.
Current state
Paint.
render_content's sidebar-panelmatch(src/gtk/mod.rs:9351-9371) has arms forPANEL_SETTINGS,ext:*, and the rest;PANEL_AIfalls into the empty_ =>. Selectingthe AI panel from the activity bar on GTK therefore shows an empty sidebar body.
Click.
try_route_sidebar_mouse_event(:7325-7327) has the matching holdout andcomments it honestly:
That is the right call while paint is missing, and it becomes wrong the moment paint lands
— both halves must change together.
Dead handles.
ai_sidebar_da_ref(:558) andai_panel_box_ref(:572) are two of the22 permanently-
NoneRelm4-era widget handles.:3170,:6574,:6584,:6602readai_sidebar_da_refinsideif let Some(…)arms that never run, andhandle_ai_sidebar_msg(
:6549) is reached only through theMsgbus. None of it paints anything. Delete on theway through, or leave to the orphan-handle sweep — but do not wire new code to either
handle.
TUI reference.
render_ai_sidebar(src/tui_main/panels.rs:1168, 180 lines) is theworking implementation. Read it first; the GTK arm should call the same shared builder, not
re-derive the layout.
Design
Follow #670's own pattern exactly — it is the template this issue is a straggler from:
render::builder for the AI panel does not exist, add one (mirroringrender::populate_ext_sidebar_system/populate_settings_form_controller), and haveTUI's
render_ai_sidebarcall it too so this lands as convergence, not a secondimplementation. A GTK arm that duplicates TUI's 180 lines is the failure mode
CLAUDE.md's Platform-Neutrality Rule exists to stop.PANEL_AIarm torender_content's match, painting throughBackendprimitivesat
q_sblike its siblings._ => falseclick holdout with real routing once the panel paints, using thelayout the paint cached — never a re-derived one (#448-D: GTK ShellApp migration — click-handling logic largely not working (follow-up bugs from #540) #544, Split-pane divider drag is broken in both TUI and GTK (falls through to text-selection) #582, Adopt quadraui's GtkDriver — vimcode has zero GTK black-box tests though the harness shipped in quadraui#301 #646 are all that bug).
Acceptance criteria
_ =>holdout comment at:9364and the one at
:7325are both gone.GtkDriverblack-box test (src/gtk/testing.rs) asserts the panel's rendered output— not that a state field is
Some(CLAUDE.mdrule 1;ScreenLayout.pickerwas populatedfor months while nothing painted it). If the content is icon glyphs, probe pixels (#448-H: GTK breadcrumb bar non-functional after ShellApp migration (clicks dead / dropdown hidden) #555).
develop(rule 2).existing coverage stays green.
cargo build && cargo test && cargo clippy -- -D warnings && cargo fmt --checkEXIT=0.Files
src/gtk/mod.rs(render_contentmatch,try_route_sidebar_mouse_event)src/render.rs(shared builder, if added)src/tui_main/panels.rs(migrate onto the shared builder)src/gtk/testing.rs(driver coverage)Milestone
#7 Platform-Neutral — child of #592.
Every line number above was measured on
develop @ 4872ab9(2026-09-01). They arealready wrong. #727 landed
src/gtk/mod.rs+435/−44 within hours and movedenum Msg1096→1131,fn dispatch1799→1896,sync_scrollbar2657→2754. Seven moreissues sit ahead of this one in the chain, each deleting or moving thousands of lines.
Treat the numbers as provenance — proof the claim was verified once — never as
coordinates. Locate by these anchors instead:
This is the same defect #734 exists to fix:
src/tui_main/carries 19mirrors mod.rs:NNNNcomments whose targets all drifted after #540, leaving the onlyrecord of a cross-backend contract pointing at unrelated code. Do not re-point the
numbers when they rot — the anchors are the durable form.