docs: design tmux window index reset

This commit is contained in:
2026-06-10 21:39:31 -04:00
parent b680112c9c
commit 9b515f6b44
@@ -0,0 +1,134 @@
# Reset tmux window indexes
**Date:** 2026-06-11
**Status:** Approved
## Goal
Add reusable functionality that compacts tmux window indexes inside the `hqt`
tmux session so keyboard shortcuts such as `Alt+1`, `Alt+2`, and `Alt+3` stay
useful after windows have been closed.
This reset affects only tmux window indexes. It does not change database session
IDs, `tmux_session_name`, harness conversation IDs, nicknames, panes, or running
processes.
## Behavior
The reset operation works on the configured `hqt` tmux session:
- The home/TUI window always ends at tmux index `0`.
- Every non-home window keeps its current name, pane, process, and content.
- Non-home windows are sorted by their current tmux index.
- Those non-home windows are moved into contiguous indexes starting at `1`.
Example:
```text
0: ⌂ HQT
1: hqt-foo
4: hqt-bar
9: hqt-baz
```
becomes:
```text
0: ⌂ HQT
1: hqt-foo
2: hqt-bar
3: hqt-baz
```
If the home window is not already at `0`, it is moved to `0` first, then the
remaining windows are compacted after it in their original index order.
## Architecture
Add the reset at the tmux layer rather than the session or database layer.
Existing app and service code targets windows by name, so changing tmux indexes
should not disturb attach, stop, delete, status polling, or label syncing.
### Runner
Add a low-level method on `TmuxRunner`, for example:
```python
async def reset_window_indexes(self, home_window: str) -> bool:
...
```
The method should:
1. List windows for `self.session_name` with `#{window_id}`,
`#{window_index}`, and `#{window_name}`.
2. Find the row whose name matches `home_window`.
3. Move the home window to index `0` if needed.
4. Sort all other windows by their original index.
5. Move each non-home window to `1..N` in that order.
Use `move-window` with `window_id` as the source target so changing one index
cannot make a later move target the wrong window. The destination should target
the configured tmux session and explicit index.
The implementation should be idempotent: running it against an already compact
session should return success without changing anything meaningful.
### Manager
Add a thin delegate on `TmuxManager`, for example:
```python
async def reset_window_indexes(self, home_window: str) -> bool:
return await self.runner.reset_window_indexes(home_window)
```
No `SessionService` change is needed for the initial implementation. This is a
tmux maintenance operation, not a session lifecycle operation.
### Command Surface
Implement the reusable operation now and defer user-facing wiring. A command
palette is planned separately, so this feature should expose a callable method
that the future command can invoke.
Do not add a TUI keybinding or footer item in this change.
## Error Handling
- If the configured tmux session does not exist or cannot be listed, return
failure and leave the database untouched.
- If the home window is missing, return failure rather than guessing which
window should become index `0`.
- If a `move-window` command fails, return failure. The operation may have
partially moved tmux windows before the failure; this is acceptable because
tmux indexes are maintenance metadata and no persisted hqt state is changed.
- Log tmux stderr for failed operations to aid debugging.
## Testing
Add focused tests in `tests/test_tmux.py`:
- Missing home window returns failure and performs no moves.
- Already compact windows return success.
- Sparse indexes compact in current index order:
`0 home, 1 foo, 4 bar, 9 baz` moves `bar` to `2` and `baz` to `3`.
- Home initially not at `0` is moved to `0`, and all other windows compact to
`1..N` in original order.
- Moves target stable window identities, not mutable index-only targets.
The implementation must pass the project checks after code changes:
```bash
uv run ruff format src tests
uv run ruff check src tests
uv run ty check
```
## Out of Scope
- Changing database primary keys.
- Changing `Session.tmux_session_name`.
- Changing harness session IDs or resume behavior.
- Adding command palette UI, keybindings, or footer labels.
- Enabling permanent tmux automatic renumbering.