|
| 1 | +# Order, hide and drag session sidebar sections |
| 2 | + |
| 3 | +## Identity |
| 4 | + |
| 5 | +- Status: active |
| 6 | +- Integration branch: `dev-nowaker` |
| 7 | +- Development branch(es): `tui-sidebar-order` (config, off upstream `dev` `907b3bc518`), `tui-sidebar-drag` (drag-and-drop, stacked on it); both are upstream PR heads |
| 8 | +- First local commit: `bc5aa4ec1e` |
| 9 | +- Current local commit(s): `bc5aa4ec1e`, `dc68262b8a` |
| 10 | +- Upstream base when introduced: `907b3bc518` (upstream `dev`) |
| 11 | +- Last checked against upstream: `907b3bc518` (upstream `dev`) |
| 12 | +- Upstream: issue [#53198](https://github.com/anomalyco/opencode/issues/53198), PR [#53201](https://github.com/anomalyco/opencode/pull/53201) (config), PR [#53217](https://github.com/anomalyco/opencode/pull/53217) (drag-and-drop, builds on #53201) |
| 13 | + |
| 14 | +## Original request |
| 15 | + |
| 16 | +Relayed by coordinator `ses_ef8235798ffejGr4sa22eXmVNv` (effort item 4D), |
| 17 | +quoting the user: |
| 18 | + |
| 19 | +> allow reordering and hiding of elements in that menu (except for title) via |
| 20 | +> tui config. and maybe also drag and drop? <- as a separate PR on top of the |
| 21 | +> first one, since this may be controversial. |
| 22 | +
|
| 23 | +## Goals |
| 24 | + |
| 25 | +- `sidebar.order` lists sidebar sections in display order; unlisted sections |
| 26 | + follow in their default order, so a future section never vanishes. |
| 27 | +- `sidebar.hidden` hides sections. Names: `context`, `mcp`, `lsp`, `todo`, |
| 28 | + `files`, or a plugin's slot registration id, so plugin sections work too. |
| 29 | +- Dragging a section by its header onto another moves it there; the order is |
| 30 | + saved in kv `sidebar_order`, wins over `sidebar.order`, and is cleared by |
| 31 | + "Reset sidebar order" (`session.sidebar.reset_order`). |
| 32 | + |
| 33 | +## Non-goals |
| 34 | + |
| 35 | +- The session title (`sidebar_title` slot) and the footer are not sections. |
| 36 | +- No change without config or a drag. |
| 37 | + |
| 38 | +## Rationale and constraints |
| 39 | + |
| 40 | +- opentui slot order belongs to a whole registration, so the host splits a |
| 41 | + registration's `sidebar_content` into its own registration and leaves its |
| 42 | + other slots (e.g. `sidebar_footer`) in place. |
| 43 | +- Each section is wrapped in a host box that is `visible={false}` while the |
| 44 | + section renders nothing, so empty Todo/Files take no space. |
| 45 | +- opentui captures the renderable under the pointer at the first drag event, |
| 46 | + which can be a gap; the dragged section is the one pressed on mouse down and |
| 47 | + a drag is recognized from `over` events carrying a `source`. |
| 48 | +- Header text is `selectable={false}` so a press starts a drag, not a text |
| 49 | + selection; content text still selects and never reorders. |
| 50 | +- Collapsible headers (MCP, LSP, Todo, Files, and 4B's Context) toggle only |
| 51 | + when pressed and released on the same cell (`feature-plugins/sidebar/click.ts`), |
| 52 | + so a drag or a drop onto a header does not toggle it. |
| 53 | +- Shares the `sidebar` `tui.json` struct with 4A (`pin_title`) and 4B |
| 54 | + (`context`). |
| 55 | + |
| 56 | +## Changes |
| 57 | + |
| 58 | +| Commit | Workday | Change | Stable seam | |
| 59 | +|---|---|---|---| |
| 60 | +| `bc5aa4ec1e` | 2026-10-04 | `sidebar.order` / `sidebar.hidden`; `placeSidebarSection` applied in slot registration; config passed via `setupSlots(api, config.sidebar)` | `createSlots` in `packages/tui/src/plugin/slots.tsx`; `TuiConfig.Sidebar`; `load()` in `packages/opencode/src/plugin/tui/runtime.ts` | |
| 61 | +| `dc68262b8a` | 2026-10-04 | drag-and-drop wrapper, kv `sidebar_order`, live `registry.updateOrder`, reset command, non-selectable headers, `onHeaderClick` | `packages/tui/src/plugin/slots.tsx`; `packages/tui/src/feature-plugins/sidebar/*.tsx`; `routes/session/index.tsx` command list | |
| 62 | + |
| 63 | +## Verification |
| 64 | + |
| 65 | +- `bun typecheck` in `packages/tui` and `packages/opencode` - exit 0 on both |
| 66 | + upstream branches and on `dev-nowaker`; `packages/tui` `bun test` on |
| 67 | + `dev-nowaker` - 225 pass, 0 fail. |
| 68 | +- Pre-existing, unrelated: 4-5 failures in `packages/opencode` |
| 69 | + `test/config/tui.test.ts` + `test/cli/tui/plugin-loader.test.ts`, identical on |
| 70 | + vanilla `907b3bc518`. |
| 71 | +- Manual surface (throwaway tmux socket `oc-tui-sidebar-order`, isolated XDG, |
| 72 | + fake OpenAI-compatible provider, 3 failing MCP servers): vanilla ignores |
| 73 | + `{"sidebar":{"order":["mcp","context"],"hidden":["lsp"]}}`; this build shows |
| 74 | + MCP, Context, no LSP. Drag MCP onto Context and back, drag down, text-select |
| 75 | + drag (no reorder), restart persistence, reset, click collapse/expand, drop on |
| 76 | + a header without toggling it, 4B's compact Context toggle. |
| 77 | +- Installed desktop binary `1.18.34-vt-80-907b3bc518` with |
| 78 | + `{"order":["lsp"],"hidden":["context"]}`: LSP first, Context hidden, MCP next. |
| 79 | + |
| 80 | +## Timeline |
| 81 | + |
| 82 | +- 2026-10-04 |
| 83 | + [`ses_ef81ad30fffeo7m3HoZisuJdli`](../sessions/2026-10-04-sidebar-section-order.md) |
| 84 | + - `bc5aa4ec1e`, `dc68262b8a`: introduce; issue #53198, PRs #53201 and |
| 85 | + #53217; build and install on desktop and m4max. |
| 86 | + |
| 87 | +## Current maintenance notes |
| 88 | + |
| 89 | +- Drop the fork commits once #53201 / #53217 (or equivalents) land upstream. |
| 90 | +- No host setting; the user has not asked for a specific order. |
| 91 | + |
| 92 | +### Upstream integration checklist |
| 93 | + |
| 94 | +- `placeSidebarSection` and the `register` wrapper in |
| 95 | + `packages/tui/src/plugin/slots.tsx` still see every `sidebar_content` |
| 96 | + registration; `setupSlots` still receives `config.sidebar`. |
| 97 | +- Run `bun typecheck` and `bun test test/plugin test/config.test.tsx` in |
| 98 | + `packages/tui`. |
| 99 | +- In a TUI: configured order applies, a header drag reorders, a click still |
| 100 | + collapses. |
| 101 | +- Link a new timeline row to the current session record. |
| 102 | + |
| 103 | +## Supersession or removal |
| 104 | + |
| 105 | +- Not applicable; status is active. |
0 commit comments