Under the Vim preset, `:` opens a transient one-line ex overlay running a
fixed v1 table; ZZ runs :wq directly. Completes the last built child of the
T-403 cross-pane vim layer (T-405 part 2 gt/gT still open).
- ExLineController + parseExCommand grammar + editor-targeted executors
(lib/kernel/src/ex_line.dart); the overlay (lib/widgets/src/ex_line_overlay
.dart) reuses the quick-open chrome, mounts in the root_shell Stack, and
publishes the exline.open scope flag. Unknown commands flash + stay open;
with no active buffer every command no-ops (2026-06-13 decision).
- :q closes the active tab via editor.close on its id — the registry promotes
the next buffer and the split self-collapses on the last (2026-06-12
decision); :w/:wq/:x/ZZ save (+close) the active buffer.
- :e <path> seeds quick-open (new QuickOpenController.open(seed:)); :N adds the
editor.goto-line IPC/CLI verb (reuses _offsetForLine). Goto needs caret sync:
EditorController now handles editor.selection-changed and the editor view
moves the caret on a selection-only change.
- `:` and ZZ are typed intents; the editor matcher and PaneKeyNav now bubble
unhandled typed intents to the app-root Actions, so they fire from any focus.
vim.yaml binds `:`, ZZ (shift+z shift+z), and Esc-dismiss.
Tests: parser/controller/executors, editor.goto-line daemon tests,
selection-changed (controller + view), full overlay widget test. make test
green; analyze + format clean.
Also files T-441 (drop bold from the ticket-id card label) and T-442
(sub-agent renders as 3 cards instead of one bundle) under the T-276 UI epic.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The structural piece: a global SequenceMatcher in root_shell, at the
HardwareKeyboard level so a focused editor/pane can't swallow the second
chord. It only STARTS on a modified chord that prefixes a sequence (ctrl+w),
so bare-key sequences (gg, dd) stay editor/pane-local and single-chord presets
are untouched; bare ctrl+w still fires editor.close after the D-82 timeout.
vim.yaml binds the window family under vim.normal||vim.visual: ctrl+w h/l →
panel.focus.left/right, j → dock.toggle, w / ctrl+w → focus.nextPanel,
shift+w → focus.previousPanel, o → panel.focusMode, q/c → editor.close.
Tests: ctrl+w sequence resolution at the keymap layer, plus app-level
integration (ctrl+w o toggles focus mode; bare ctrl+w closes the editor after
the timeout; a bare g is not grabbed globally).
This is the global matcher T-405 part 2 (gt/gT) was waiting on — though bare-g
sequences need more thought (g is editor-local), noted for that follow-up.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
TabContribution gains an optional iconColor honoured by the icon rail:
full-strength when active/hovered, dimmed (70%) when idle, so the tint
reads as identity without outshouting the active-state border. The
Claude Activity tab sets claudeAccent (#D97757) — nominative use per the
licenses.yaml trademark note (it marks Claude's own panel).
Filed and closed as a try-it-out (user request); trivially revertible if
the accent doesn't land visually.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Typing Shift+; opened quick-open instead of a colon. Two flaws in the
T-341 detector: it counted a tap on the Shift keydown (so a chorded
press could complete the gesture before the chord key arrived), and it
relied on the chorded key bubbling to the root KeyboardListener to
break the gesture — but a focused editor or text field consumes that
event, so the tracker never saw it.
The tracker now models press/release: a tap is a press with no other
key going down while the modifier is held, and the gesture fires on
the second clean release. The root shell feeds it from a
HardwareKeyboard handler, which observes every event before focus
dispatch regardless of who consumes it, and treats a modifier pressed
while a non-modifier is already held as a chord.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
app.dart was 1187 LOC mixing five concerns. It now keeps ClideApp +
the WidgetsApp root (~60 LOC); the shell moved to lib/src/shell/:
- root_shell.dart — keyboard/intent routing (keymap resolution,
double-tap modifiers, menu mnemonics), the overlay stack, and the
welcome overlay
- hat_bar.dart + project_switcher.dart — the window-chrome bar and
its recents/file-actions dropdown (now in src/shell, not builtin/ —
they're app chrome, not extension-shaped contributions)
- slot_host.dart — slot mounting, focus-scope integration, the
per-slot bodies incl. the workspace split + editor drag handle;
_SlotBody's static title resolver became the shared resolveTabTitle
- layout.dart — the three-column grid, status bar, collapse toggles,
bottom icon rails
app.dart re-exports RootLayout, SlotHost, StatusbarHost, and
StatusbarCollapseToggle, so every existing import (incl. the three
app-level test files) is unchanged. Pure move + minimal publics
(RootShell, HatBar, ProjectSwitcherButton); full suite green with no
test edits.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>