Detect the unmarked @ path listing in the pane

Claude Code marks a fuzzy `@` hit with `+ `, but a path that leaves the
project (`@../de`) switches it to a plain directory listing whose rows
carry no marker — the selected row differs only in colour, which the
pane's text-only read of the screen drops. So the compact frame ended one
row under the input box and showed the first hit alone.

Recognise a bare path row by shape (a whitespace-free token holding a
`/`) and, since a user statusLine can look exactly like that, confirm the
list over two rows: the row under the rule must be a menu row or blank
(it is shown either way, so a one-hit menu needs no detection), and at
least one further row must match too.
This commit is contained in:
Jonas H
2026-08-27 12:44:06 +02:00
parent 1f483ad3d1
commit a5a6092579
2 changed files with 146 additions and 19 deletions

View File

@@ -519,13 +519,22 @@ agentId: <hex>`), and the real completion is injected into the parent's next
and shows one context row above the top rule (the spinner / "✻ Worked…" row)
down to the statusLine just under the bottom rule, cropping the persistent
hint/token/effort chrome below it. When an `@`/`/` menu is open it has
replaced that chrome with a list (`text_is_menu_item`, CC-2.1.x glyphs —
retune there if an update changes them), so the frame extends to the last
non-blank row instead. The menu is detected by scanning the *whole* region
below the bottom rule for a menu row, not just the row directly under it: the
list can start after a blank/header row and only the highlighted item carries
a glyph (unselected file rows are plain names), so checking one row collapsed
the pane whenever that row wasn't the selected item. Above the top rule the
replaced that chrome with a list (`text_is_menu_item`), so the frame extends
to the last non-blank row instead. **A menu row is not reliably marked**, so
that list is recognised by *shape* and confirmed by a second row: a `+ `
fuzzy hit, a `/command` / `@agent` row and the highlighted `` all carry a
marker, but a path that leaves the project (`@../de`) switches CC to a plain
**directory listing** whose rows are bare padded paths — the selected one
differs only in colour, which `row_text` drops. So a whitespace-free token
holding a `/` counts too, and because the user's own statusLine can look
exactly like that, `compact_frame_ex` votes over two rows: the row directly
under the rule must be a menu row *or blank* (it is shown either way — it is
the statusLine's slot — so a one-row menu needs no detection), and at least
one *further* row must match as well (which is what keeps a two-line
statusLine from dragging the whole chrome into the pane). Scanning the whole
tail also matters because only the highlighted row of a fuzzy list is marked,
so checking one row collapsed the pane whenever that row wasn't the selected
item. Above the top rule the
frame also swallows an **active task panel** (`text_is_task_row` /
`task_block_top`): Claude Code parks the `N tasks (…)` header + `✔ ◼ ◻` rows
(and its `… +N pending` overflow line) directly above the input box, so