Add "stop" and "rename" to the Alt+p tool palette so a session can be
managed from inside its own harness window, mirroring the TUI's s/r keys:
- stop kills the harness window (stop_session_for_window).
- rename prompts for a nickname, pre-filled with the current one. The
name is read from /dev/tty via readline (the fzf pipe leaves our stdin
spent) and never passes through tmux's command parser, so there's
nothing to quote-escape.
Extract require_session_id_for_window as the shared resolve-or-raise
guard behind the tool/stop/rename branches, dropping the duplicated
"not an hqt session window" check.
Also removes the now-shipped feature plans and specs under docs/.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Hook the existing tmux window-index reset into the Alt+p tool palette,
special-cased like clone: selecting 'reset-windows' compacts the hqt
session's window indexes (keeping the home window at 0) via
TmuxManager.reset_window_indexes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fix pre-existing ty error in action_new_session by typing the sandbox
element as SandboxPolicy | None instead of object.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
nvim/lazygit emit OSC title sequences; without allow-rename off a tool
could overwrite the window name and scramble the styled @hqt_label.
Mirrors the window-option setup in new_window. Surfaced by final
integration review.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Address three integration gaps found in review:
- Bind ~/.gitconfig read-only in the sandbox base layer so `git commit`
finds user.name/email inside the jail (spec §3).
- Bind a worktree session's repo common .git dir writable: the worktree's
real gitdir lives at <repo>/.git/worktrees/<branch>, outside the bound
cwd, so git was broken in sandboxed worktree sessions.
- doctor now gates on sandbox.is_available() (the single source of truth
shared with the New Session dialog) rather than a raw shutil.which, so
it agrees with the service on non-Linux platforms (spec §6).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds a non-fatal bubblewrap check to the doctor command that reports whether
the bwrap binary is available. This is necessary for sandboxed sessions and
the check is displayed alongside other system requirement checks.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds sandbox_available param to NewSessionScreen, renders Switch/Select/
Switch widgets for sandbox on/off, filesystem access (rw/ro), and network
toggle. When bwrap is unavailable the switch is disabled and a warning label
is shown. The _policy_from staticmethod maps widget values to SandboxPolicy.
The result tuple gains SandboxPolicy | None as its fifth element. app.py
passes sandbox_available=sandbox.is_available() when opening the dialog and
unpacks the new element to forward sandbox= to create_session.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Opens a fresh harness session with the same project, harness, and model
as the source window, creating a new sibling hqt-<id> conversation.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Import `hqt.sandbox` module and `SandboxPolicy` in service.py
- Add `_sandbox_policy` helper to decode persisted JSON policy from a session row
- Add `_wrap_command` helper that calls `sandbox.is_available` / `sandbox.wrap` and raises `ServiceError` when bwrap is unavailable for a sandboxed session
- Add `sandbox: SandboxPolicy | None = None` parameter to `create_session`; persist as `sandbox_json`, pass `sandboxed=` to `build_spawn_config`, wrap command before spawning
- Update `_get_resume_config` to pass `sandboxed=` to `build_resume_config` and wrap the resulting command
- Update rung-2 path in `_respawn_with_fallback` to pass `sandboxed=` and wrap the fresh-spawn command
- Add three new tests covering: sandboxed create wraps command, unsandboxed create does not wrap, and ServiceError on missing bwrap
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds a nullable sandbox_json TEXT column to the sessions table via a new
version-3 migration. Updates LATEST_VERSION to 3 and adjusts existing
migration tests to account for the new column and version number.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add sandbox_skip_permission_flags class attr and sandbox_binds() method
to HarnessConfigurator ABC; thread sandboxed: bool = False through all
build_spawn_config / build_resume_config signatures. Claude and Codex
append their respective skip-permission flags when sandboxed=True; Kiro
and Generic accept the param but add no flags.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Core sandbox infrastructure for isolating harness sessions. Bind defines
read-only/writable path bindings, SandboxPolicy specifies filesystem and
network isolation modes, and is_available() is the single source of truth
for bubblewrap availability across the application.
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>