Skip to content

Settings › Appearance › Layout brings back the three panels as an option beside the grid - #124

Open
davidbudac wants to merge 5 commits into
AgentSystemLabs:mainfrom
davidbudac:panels-layout
Open

davidbudac wants to merge 5 commits into
AgentSystemLabs:mainfrom
davidbudac:panels-layout

Conversation

@davidbudac

Copy link
Copy Markdown
Contributor

Brings back the PROJECTS | WORKTREES | SESSIONS columns from before 0.34 as an opt-in layout. Settings › Appearance › Layout gets panels next to grid, and grid stays the default. This addresses #108 and supersedes #122, which I closed to rework it into this smaller, reviewable series.

Contents: 📸 Screenshots · ✨ What you get · 🧭 What changes for grid users · ⚠️ Risk · 🔧 Technical overview

📸 Screenshots

The three columns beside the pane Inline follow-up on a session
Panels layout: PROJECTS, WORKTREES with open PRs and issues, SESSIONS, and the terminal pane on the right A session pill expanded into its follow-up box, typing the agent's next prompt

✨ What you get

  • A Layout setting: grid (default) or panels
    • layout in config.json; the setting switches live, no restart
    • the selected project, worktree and session, and the attached pane, carry across the switch
  • The columns, built on the grid's own state
    • same cursors the grid already uses, so there is no second selection model
    • the old row shapes, colours, ? help and keys (⇧Tab / ^⇧H / ^⇧L walk, z full screen, m row menu)
    • Space opens the inline follow-up box on a session; recent prompts show under each one
  • Columns you can shape
    • drag a border to resize; widths are saved in the UI state and survive a restart
    • ⇧P / ⇧B / ⇧S fold a column to a rail; a window too narrow for the saved widths shrinks them proportionally
  • What stayed the same: the grid's drawing and key bindings. Apart from the fixes in the next section, grid users only see the new rows in Settings › Appearance.

🧭 What changes for grid users

One commit (The pane only takes input when it shows a live session…) changes shared code. The panels needed these fixes, and the same holes exist in the grid:

  • A PR, issue or cloud reader covering a still-attached session no longer passes keystrokes, paste or mouse reports to the hidden PTY. PgUp/PgDn/Home/End scroll the reader.
  • Attaching an archived agent shows a flash and does not attach.
  • Full screen with no terminal in the pane refuses with a message, and the key-combo echo no longer says "Full screen" when it didn't happen.

The commit is self-contained, so I can split it into its own PR if you prefer.

⚠️ Risk

Verdict: 🟢 Low. Everything new is behind layout = panels, and the shared changes only make the pane refuse input in more cases.

Level Why
🔒 Security & production Low No new surface: no new ClientRequest, daemon code or protocol change. Two additive config/UI-state keys (layout, panels_widths); older files read as before.
⚡ Performance Low The grid's draw path is unchanged. The panels code runs only with layout = panels.
🧩 Fit Low Three new modules mirroring the launcher's split (panels.rs model, event_loop/panels.rs keys, ui/panels_view.rs draw). Shared files get panels_active() branches and the input gate above.

Rollback: git revert the merge removes everything. Saved layout / panels_widths keys are then ignored, and the hide_* / recent_prompts* settings return to being retired-but-preserved.

🔧 Technical overview

Commits, files, tests

Size: about 6,300 added lines, of which roughly 2,500 are tests and 400 are docs and screenshot scenes.

Five commits, each builds on its own:

  1. Layout setting and the three columns, with help and wheel scrolling
  2. Drag-to-resize borders, with persisted widths
  3. Old row shapes, folding columns, panel keys, inline follow-up
  4. Pane input gate (shared, see above)
  5. Screenshot scenes (make shot SCENE=panels…, plus RESTART=1 in shot.sh for the restart scene)

Where to start reading: crates/nebula-tui/src/panels.rs has the layout maths (columns()) and the row model. event_loop/panels.rs routes keys and mouse ahead of the grid's keymap only when app.panels_active(). In app.rs, pane_shows_terminal / pane_accepts_input are the shared gate.

flowchart LR
  CFG["config: layout"] --> APP["App.panels"]
  APP -->|grid| GRID["grid: launcher, ui.rs"]
  APP -->|panels| EV["event_loop/panels.rs"]
  EV --> MODEL["panels.rs: columns(), rows"]
  MODEL --> VIEW["ui/panels_view.rs"]
  EV --> GATE["App::pane_accepts_input"]
  GRID --> GATE
  GATE --> PTY["PTY input"]
  classDef changed fill:#fde68a,stroke:#b45309,color:#111
  class EV,MODEL,VIEW,GATE changed
Loading

Not done: workspaces. They were removed alongside the old panels, but this PR is only the layout.

Gate: cargo fmt --check is clean. cargo clippy adds no warnings; the 11 it reports also appear on main with a current toolchain. cargo test --workspace: 1772 passed, 4 failed. The same 4 fail on main on my machine (Linux): question_mark_ignores_menus_without_session_rows, the_harness_picker_is_no_wider_than_its_rows_and_keeps_its_keys_in_the_footer, nebula_open_from_inside_a_session_raises_the_file_tabs and tui_drag_past_the_pane_top_autoscrolls_and_copies_the_run. A few branch_switch / ipc tests also fail intermittently here; this PR doesn't touch those files. New coverage: ~75 unit tests (layout maths, drag floors, folds, persistence, follow-up, the input gate in both layouts) and 2 e2e tests (switching the layout live, and walking the columns).

Closes #108

🤖 Generated with Claude Code

davidbudac and others added 5 commits October 4, 2026 15:47
…, WORKTREES and SESSIONS columns beside the pane, on the grid's own selection

- New config key `layout`: `grid` (the default, unchanged) or `panels`. The
  row cycles live; switching keeps the selected project, worktree and
  session and whatever the pane has attached.
- `panels` draws the three columns from before the grid (ui/panels_view.rs,
  model in panels.rs) on the cursors the grid already indexes, so there is
  no second selection. The PROJECTS column stands in for the PROJECT TABS.
- Keys: event_loop/panels.rs gives the grid-owned keys their panel meaning
  (`Space` follow-up, `^F` full screen, `]`/`[` attention walk, `⇧A` folds
  ARCHIVED) or a line saying they have none here. Rows and group headers
  take clicks; the wheel scrolls a column without moving its cursor.
- `?` with the PANELS up lists the panels' own keys; the grid's help is
  unchanged.
- docs/configuration.md, docs/keys.md and docs/sessions.md follow.

Refs AgentSystemLabs#108

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the widths survive a restart

- Each column's right border (PROJECTS|WORKTREES, WORKTREES|SESSIONS,
  SESSIONS|pane) is a drag target: col-resize pointer and a lit grip on
  hover, a grab offset so the border doesn't jump, no row selected and no
  FOCUS moved. A column stops at MIN_W, the pane at MIN_PANE_W.
- The widths are kept in the saved UI state (`panels_widths`, absent in
  older blobs); a narrow window still squeezes them for the frame without
  forgetting them.
- The pane's PTY follows the new width through the usual resize.
- `?` help, docs/keys.md and docs/sessions.md follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… collapsible columns, the old keys, help and colours, and the inline follow-up

- Rows are the old shapes again: 3-row PROJECT buttons, 2-row pills with a
  full-height rail for checkouts, sessions, PRs and issues. A project row
  carries its `3 prs · 2 issues` counts and a renamed project's `└ folder`;
  a merged checkout goes purple with its one-shot sweep; `▶ running`,
  ` N new` comments, `100+` / `9/12` group counts, the empty WORKTREES hint
  and the footer's `+N files` are back.
- Columns collapse to `▶` rails: a `◀` on each header, ⇧P / ⇧B / ⇧S and
  ^B / ⌘B / ⇧Z, kept in `hide_projects` / `hide_worktrees` /
  `hide_sessions`, with remembered widths. SESSIONS folds to its rule under
  an OPEN PRS or ISSUES row. Saved widths that no longer fit shrink in
  proportion, each open column held at MIN_W and the pane at MIN_PANE_W.
- PANEL_KEYS, panels only and ahead of the keymap: ⇧Tab / ^⇧H / ^⇧L walk,
  ^→ into the pane without its input, `z` full screen, `m` the row menu,
  ⇧C a Ghostty tab. The grid keeps its own bindings.
- `?` is the old help; the footer ends `m: menu  ?: help`; the focused
  column takes the old per-preset tint; the key echo stays hidden.
- Space expands a session pill into the old inline FOLLOW-UP box; RECENT
  PROMPTS lines return under each pill (`recent_prompts`,
  `recent_prompts_count`).
- Settings › Appearance ends on a PANELS LAYOUT group for these settings,
  dated so they don't show as NEW to grid users.
- Panels start on PROJECTS; switching back to the grid moves FOCUS to
  SESSIONS so `d` / `r` never land on a column the grid lacks.
- docs/keys.md, docs/sessions.md and docs/configuration.md follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ts, and full screen refuses cleanly

Touches the grid too:
- A PR, issue or cloud reader covering a retained attachment no longer
  lets keys, paste, mouse reports or a pending attach through to the
  hidden PTY (`App::pane_shows_terminal` / `App::pane_accepts_input`).
  Page/Home/End scroll the reader from a focused pane.
- An archived agent is refused with a flash instead of attaching
  (`App::is_archived_session`, replacing three inlined checks).
- Full screen works on any terminal surface, exited output and starting
  sessions included, and otherwise refuses with one message; the KEY COMBO
  DISPLAY only says "Full screen" when it happened.

Panels only:
- Activating a checkout walks past a folded SESSIONS; the quick prompt
  targets the visible checkout and carries a selected PR or issue.
- A click elsewhere breaks a session row's double-click.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- panels: three launches beside PROJECTS | WORKTREES | SESSIONS.
- panels-drag / panels-drag-floor: borders dragged, and the pane's floor.
- panels-rails / panels-pr-fold: folded columns and the SESSIONS fold.
- panels-follow-up / panels-recent-prompts /
  panels-settings-recent-prompts: the inline follow-up and recent prompts.
- panels-restart: the dragged widths after nebula restarts, via the
  harness's new `RESTART=1`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@davidbudac

Copy link
Copy Markdown
Contributor Author

Hi Cody, this took surprisingly long and a lot of effort. I was aiming for a simple switch in the settings which I think I achieved.

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.

what happened to the new layout?

1 participant