ProjectService now rejects non-existent paths (path-validation feature), so
the TUI and integration tests must seed projects with real tmp_path dirs.
Completes the path-validation test updates beyond test_services.py.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drive TmuxRunner against a throwaway tmux server (isolated via TMUX_TMPDIR)
so the tests never touch the user's live tmux. Register the 'tmux' pytest marker.
Skips when no tmux binary is present.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Hold an asyncio.Lock across the spawn->capture window for harnesses that
capture a session id, so two concurrent hqt starts in the same project
never produce overlapping capture windows. Completes the P2 capture-race
fix alongside the ambiguity guard.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
When more than one rollout matches the project cwd within the capture
window, return None and warn instead of guessing the earliest. The worst
case is now a kept placeholder id, never a wrong one. Part of the P2
capture-race fix.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Reject non-existent or non-directory paths with ServiceError (already
surfaced as a TUI notification), and store the resolved absolute path.
Closes the P2 finding where bad paths became dead sessions later.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
TUI:
- VimListView: j/k now move down/up in the project and session lists
(arrow keys still work); used by both list widgets.
tmux status bar:
- Widen the gap between window cells via a 2-space window-status-separator
(WINDOW_STATUS_SEPARATOR).
- Fix the current-window cell toggling between padded " 1: name " and
unpadded "1: name". The per-window status format is static, but
set_window_label re-asserted it on every 3s poll — letting a competing
writer (e.g. a stale TUI process running older code with a differently
padded format) flip the cell each cycle. The format is now owned by a
single write-once path (new_window at creation, apply_theme for existing
windows); the poll updates only the dynamic @hqt_label.
Also lands pre-staged scaffolding: AGENTS.md quality gate, TODO.md backlog,
and ty dev dependency.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Style the hqt session's status bar with the same Frappé palette the TUI
uses: blue session badge, Mantle background, peach current-window
highlight, muted inactive windows, styled clock/date. The TUI window
shows just its house glyph (no index/flag/text). Applied from the TUI's
on_mount since the os.execvp bootstrap can't run follow-up tmux commands.
All options are session-scoped (never -g), so the user's other tmux
sessions and personal config are untouched. Window-scoped options
(current-window highlight, pane borders, mode style) have no session
scope in tmux, so they're painted per-window on every existing window in
apply_theme and on each new harness window in new_window — otherwise a
window spawned after mount would render with no peach highlight.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
TUI for orchestrating AI coding harness sessions (Claude Code, Codex,
Kiro, etc.) via tmux. Click CLI bootstraps a Textual TUI over
ProjectService/SessionService backed by SQLite, spawning harness
sessions as tmux windows through TmuxManager.
Includes recent fixes:
- Visible Tab focus highlight on dialog OK/Cancel buttons
- Auto-select first project on launch
- Auto-select first session + per-project session-selection memory
- tmux new-window targets an explicit free index, fixing
"index N in use" failures (broken spawn/attach in attached sessions)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>