Skip to content

Navigate xmd repl by focus regions and their children #895

Description

@taras

Story

As a person using xmd repl, I want to move between parts of the screen with Tab and navigate their controls with arrow keys, so reaching another part of the interface does not require stepping through every control along the way.

For example, while navigating rows in the sidebar, Tab moves to the next top-level focus region regardless of how many sidebar rows exist. Up, Down, Left and Right navigate within the active region. Shift+Tab moves back between regions.

Current gap

Keyboard traversal treats the interface as one long sequence of focusable controls. Moving to another pane can require many Tab presses, and adding controls makes that journey longer.

The implementation already has a mounted component tree. Freedom's focusChain() flattens its focusable descendants, and REPL dispatch sends Tab and Backtab through that sequence. Arrow keys currently have no normalized navigation event. The gap is the navigation model, rather than the absence of an underlying tree.

Accepted direction

  • Focus navigation follows a tree of regions and their children. A region is a recognizable part of the interface whose controls are navigated together.
  • Tab and Shift+Tab move forward and backward between the roots of those regions. They do not enumerate every descendant before leaving a region.
  • Up, Down, Left and Right navigate among children within the active region. Arrow navigation does not become another traversal of the whole screen.
  • Increasing the number of children in a region does not increase the number of Tab presses needed to reach another region.

The precise region inventory and navigation details below require Product Owner review before this becomes an implementation handoff.

Decisions before implementation

Prepare a concrete focus-tree diagram and key walkthrough for the empty REPL, populated Entries and Sessions, an open interaction drawer, and the Bindings/Sidekick composition from #883. Settle:

  1. Which visible parts are region roots, their Tab order, and what focus visibly lands on when entering a region: the root itself, a default child, or its previously focused child.
  2. How each arrow moves through vertical lists, horizontal controls, nested groups and mixed layouts; what happens at an edge; and whether traversal wraps.
  3. How text fields and composers use arrows for editing while keeping their neighboring controls reachable.
  4. How modal drawers constrain the available regions, restore focus when closed, and coexist with the existing History-reachability contract.
  5. How windowed lists expose further children and how narrow composition or removal of a focused child chooses a surviving focus target.

Update the accepted keyboard contract in specs/repl-spec.md and the affected architecture description with the settled design. In particular, reconcile the current statement that list-window controls have no arrow shortcut. Do not silently reinterpret that statement as already providing this behavior.

Existing boundaries

Freedom remains the sole focus owner within the mounted tree. Region navigation introduces no second focus store or terminal reader. Host input names keys and targets; mounted components and their ancestry determine meaning under the established dispatch contract.

Keyboard focus remains distinct from selected entries, scopes and History positions. Moving focus alone does not execute a control, submit a draft or answer an interaction. Background output does not steal focus. Hidden or unmounted surfaces have no navigation targets, and pointer and keyboard interaction agree on the focused control.

Product verification proposal

  • Start within a populated sidebar, reach another region with Tab, navigate its children with arrows, and return with Shift+Tab. Repeat with substantially more sidebar rows: the cross-region Tab distance stays the same.
  • Traverse a region's children in both directions without unexpectedly moving into another region. Demonstrate the approved behavior for nesting, edges and list windows.
  • Move between the main entry input and the Sidekick composer when available. Typing reaches the visibly focused destination; arrow editing follows the approved field contract.
  • Open and close a drawer, resize to a narrow terminal and back, and remove the focused child. Focus stays within the permitted visible tree or moves to the approved surviving target.
  • Show that focus movement preserves selection, drafts and pending interactions and performs no activation. Background Agent activity preserves the current focus.

Exercise actual terminal key input through REPL dispatch and capture the visible focus destination. A helper-only test or a flattened chain with a few skipped controls does not establish the region model. The Architect and Product Owner refine this proposal before the Planner freezes acceptance.

Relationships and scope

Follow-on REPL Story related to Quest #827. #881 owns original visual parity and already requires visible focus distinct from selection; this Story owns the changed keyboard-navigation model. Coordinate with #883 for right-pane tabs and its independent composer. Preserve those active contracts rather than rewriting their scope through this Story.

Relevant implementation boundaries are packages/cli/src/repl/input.ts, reconcile.ts, and the vendored Freedom lib/focus.ts. Existing composition and terminal regression entrypoints are packages/cli/tests/repl-composition.test.ts and packages/cli/tests/repl-terminal.test.ts.

Exclude a renderer replacement, a general public UI framework, new panes, session-management features and changes to execution or Journal semantics.

Activity

  1. added
    enhancementNew feature or request
    UXUser-facing usability and interaction improvements
    on Oct 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    UXUser-facing usability and interaction improvementsenhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions