# hqt — HQ Terminal A TUI for orchestrating AI coding harness sessions (Claude Code, Kiro, Aider, etc.) via tmux. Manage multiple AI sessions across projects from a single terminal interface. ## Quick Start ```bash uv pip install -e . hqt ``` ## Commands | Command | Description | |---------|-------------| | `hqt` | Launch the TUI (inside tmux) | | `hqt doctor` | Check system requirements | | `hqt list` | List projects and sessions | ## Key Bindings | Key | Action | |-----|--------| | `q` | Quit | | `n` | New session | | `a` | Add project | | `e` | Edit project | | `Tab` | Switch panel | | `d` | Delete session | | `Enter` | Attach to session (auto-resumes if not running) | | `r` | Rename session | | `s` | Stop session | | `h` / `l` | Focus the Projects / Sessions column | | `x` | Archive selected session (instant; keeps the row, kills the window) | | `A` | Toggle the Sessions column between active and archived | | `u` | Restore (unarchive) the selected session — archived view only | ## tmux configuration hqt runs inside tmux and tags each harness window with an `@hqt_label` user option automatically — **it never edits your `~/.tmux.conf`**. The TUI itself needs no tmux config to run. The bindings below are opt-in: add the ones you want to your own `~/.tmux.conf` (`-n` = no prefix key). ### Tool palette — `Alt+p` (required for the palette feature) Pops an fzf palette for the current session's project (nvim / lazygit / shell / clone / reset-windows) from inside a harness window. Requires `hqt` on your `PATH` (see Quick Start) and `fzf`. `run-shell` expands `#{window_name}` to a concrete window name before `hqt` builds its `display-popup`: ```tmux bind -n M-p run-shell -b "hqt palette '#{window_name}'" ``` If you run hqt from a checkout instead of installing it, point `uv run` at the repo so the virtualenv self-heals when deps change: ```tmux bind -n M-p run-shell -b "uv run --project /path/to/hq-term hqt palette '#{window_name}'" ``` ### Session switcher — `Alt+o` (optional) Pops an fzf switcher over whatever you're doing (works inside a harness too). Rows are built from the `@hqt_label` hqt sets; `cut` takes the leading window index and `select-window` jumps to it: ```tmux bind -n M-o display-popup -E -w 50% -h 40% -T ' switch session ' \ "tmux list-windows -F '#{window_index} #{?@hqt_label,#{@hqt_label},#{window_name}}' \ | fzf --reverse --no-info --prompt='session ' \ | cut -d' ' -f1 \ | xargs -r tmux select-window -t" ``` ### Scrollback passthrough — `PageUp` (optional) The TUI uses tmux's alternate screen. This sends `PageUp` straight through to full-screen apps (the TUI) while still entering copy-mode scrollback in normal panes: ```tmux bind -n PageUp if-shell -F '#{alternate_on}' 'send-keys PageUp' 'copy-mode -eu' ``` After editing `~/.tmux.conf`, reload it with `tmux source-file ~/.tmux.conf` (or restart the server). ## Worktree-isolated sessions The New Session dialog (`n`) has an **Isolate in worktree** checkbox. When the selected project is a git repository, checking it runs the session in a dedicated [git worktree](https://git-scm.com/docs/git-worktree) instead of the project root, so concurrent sessions don't step on each other's working tree. - The worktree lives at `/.worktrees/` and is automatically added to the repo's `.git/info/exclude` so it never shows up as untracked. - The branch is created off the current `HEAD`. If you leave the branch field blank it defaults to a slugified form of the session nickname. - For non-git projects the checkbox is disabled. Deleting a worktree session (`d`) opens a confirmation dialog with an **Also remove worktree** option. As a safety check, if the worktree has uncommitted changes or unmerged commits a warning is shown and the removal box is left unchecked — checking it then forces removal and discards that work. Known limitation: submodules are not initialized in freshly created worktrees; run `git submodule update --init` inside the worktree if your project needs them. ## Architecture hqt uses a layered architecture: a Click CLI bootstraps into a Textual TUI, which drives service classes (ProjectService, SessionService) backed by SQLite via SQLAlchemy. Sessions are spawned as tmux windows through TmuxManager, with harness-specific configuration provided by pluggable HarnessConfigurator implementations discovered at runtime.