Commit Graph

28 Commits

Author SHA1 Message Date
felixm 88a52d0e6d fix: handle scheduled prompts on session deletion 2026-06-11 08:26:33 -04:00
felixm 4169e7fc28 feat: schedule prompts in session service 2026-06-11 08:18:44 -04:00
felixm 60612065ff feat: persist scheduled prompts 2026-06-10 22:55:18 -04:00
felixm c574117c71 feat: report tmux prompt injection failures 2026-06-10 22:54:48 -04:00
felixm 09505f0758 fix: keep tmux focus during window index reset 2026-06-10 22:18:13 -04:00
felixm ee4bb4cbfa feat: expose tmux window index reset 2026-06-10 22:02:09 -04:00
felixm 666df40aca test: cover tmux window index reset 2026-06-10 21:51:16 -04:00
felixm dff53144c9 Merge branch 'main' into worktree-sessions
# Conflicts:
#	src/hqt/sessions/service.py
#	tests/test_sessions.py
2026-06-10 21:07:20 -04:00
felixm d78d8ee149 test: add isolated real-tmux smoke tests
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>
2026-06-10 20:56:58 -04:00
felixm ace537e3d6 fix: worktree session UI safety and visibility (review)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 20:49:12 -04:00
felixm 6ed598b443 fix: serialize Codex spawn->capture with a lock
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>
2026-06-10 20:47:35 -04:00
felixm f6a90e8f4d fix: refuse ambiguous Codex session-id capture
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>
2026-06-10 20:43:52 -04:00
felixm 9efa270422 feat: worktree session UI (dialog checkbox, confirm delete, list marker)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 20:41:11 -04:00
felixm 1b79530214 feat: validate project paths at create/update
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>
2026-06-10 20:40:24 -04:00
felixm 0cf147ee25 fix: robust worktree repo-path derivation and branch typing (review)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 20:28:25 -04:00
felixm 61f1a07ba7 feat: worktree-aware session lifecycle in SessionService
Add worktree support to SessionService via the hqt.git.worktree module:

- create_session(worktree_branch=...): creates the worktree before the row
  (ServiceError → no row, no spawn); spawn/capture use the worktree path;
  blank nickname defaults to the branch name.
- _session_path / _repo_path_for_worktree helpers route every harness-facing
  path through the worktree when set, with a parent.parent repo fallback when
  the project row is gone.
- attach_session rung 0: recreate a missing worktree from its branch, else
  raise "delete the session".
- delete_session(remove_worktree=, force=): remove worktree before deleting
  the row; removal failure keeps the row.
- worktree_state_for(session_id): None for plain/missing sessions, else the
  module's WorktreeState.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 20:21:37 -04:00
felixm 860f1b59bd feat: worktree columns on sessions + migration v2
Add worktree_path and worktree_branch nullable columns to the Session
model, with a migration v2 that ALTERs the existing sessions table.
Tests cover fresh DB stamping at v2, v1→v2 upgrade path, and row-level
defaults (None when unset, populated when provided).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 20:03:38 -04:00
felixm cc49859b08 fix: harden git worktree module (review findings)
- is_git_repo: check out.strip() == "true" (bare repos / .git dirs exit 0 with "false")
- _validate_branch: new shared helper calls check-ref-format; used in all three
  public branch-taking functions to block option-injection (--detach, --all, etc.)
- _ensure_worktrees_excluded: prepend newline when existing content lacks trailing newline
- WorktreeState: make frozen=True (codebase precedent)
- create_worktree invalid-branch ServiceError now includes git stderr
- remove_worktree: log.debug for silently-swallowed branch -d / worktree prune failures
- worktree_state docstring: document git-failure → clean-state behaviour
- Tests: 9 new regression tests; raw subprocess.run commit calls replaced with _commit helper

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 19:59:16 -04:00
felixm bb142d05e4 feat: git worktree module
Adds hqt.git.worktree with slugify, is_git_repo, WorktreeState,
create_worktree, add_worktree_for_branch, worktree_state, and
remove_worktree; includes 25 real-git integration tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 19:51:45 -04:00
felixm 98ea8a1a5c feat: factory-based DB wiring and ServiceError notifications in TUI
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 19:31:06 -04:00
felixm 208a9028e7 refactor: per-operation DB sessions and ServiceError in SessionService
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 19:16:15 -04:00
felixm c93135b338 refactor: per-operation DB sessions in Project/Mcp services
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 19:10:09 -04:00
felixm 5109609b8d feat: add ServiceError and detached-safe session factory
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 19:05:40 -04:00
felixm 8870b8f3ef feat: add user_version-based schema migrations
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 19:02:53 -04:00
felixm a7851e7007 Satisfy project quality gates 2026-06-10 18:23:52 -04:00
felixm 9379e1523c Add vim list nav, fix window-title padding toggle, widen title spacing
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>
2026-06-10 17:43:47 -04:00
felixm 5eea909029 Theme tmux status bar to match Catppuccin Frappé TUI
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>
2026-06-10 17:26:34 -04:00
felixm 90944948f5 Initial commit: hqt — HQ Terminal TUI
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>
2026-06-10 17:06:57 -04:00