# 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.