Files
hqt/README.md
T
2026-06-11 12:31:52 -04:00

4.3 KiB

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

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:

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:

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:

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:

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 instead of the project root, so concurrent sessions don't step on each other's working tree.

  • The worktree lives at <project>/.worktrees/<branch> 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.