Commit Graph

12 Commits

Author SHA1 Message Date
leetcrypt c6eeb9b897 feat(sandbox): port-in-use consent gate + uniform sudo capture
GUI launch (docker/podman) now pre-flights the noVNC port (6080): if it's
already bound, a modal names the holding pid and asks before killing it and
proceeding — never a blind `bind: address already in use` collision.

Sudo capture is now uniform across every backend installer. Previously only
Docker fed the masked-modal password through `--stdin-pass`/`sudo -S`; the
captured password was silently dropped for Podman/Multipass and never wired
for VirtualBox, and those scripts used bare `sudo` (which hangs/corrupts a
raw-mode tty). Now:
- shared `run_ensure()` feeds the password to any ensure-*.sh via stdin
- podman/multipass/vbox scripts gain the docker sudo ladder
  (interactive `sudo` / `--yes` `sudo -n` / `--stdin-pass` `sudo -S -p ''`)
- podman's apt path wrapped in `sh -c` so one sudo covers update+install
- vbox GUI path preflights `sudo_ready()` with actionable guidance, falling
  back to fail-fast `sudo -n` instead of a tty hang

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-08 11:00:09 -07:00
leetcrypt 20091a9c26 feat(sandbox): podman backend + goose AI harness + noVNC GUI sandbox
Add Podman as a rootless/daemonless sandbox backend alongside Docker,
Multipass and Local, and wire Goose in as the default agentic harness
for the granted `!task` path (bridge execs `<engine> exec <name> goose
run` and streams output to chat; auto-degrades to the simple one-shot
injector when goose is absent).

Add an optional GUI sandbox track (XFCE + TigerVNC + websockify/noVNC on
:6080) summoned via `/sbx <engine> gui`, plus container-side provisioning
in sandbox-bootstrap.sh and a host-side ensure-podman.sh prereq helper.

Refresh the in-app command help to the backend-led `/sbx <engine> [gui]`
grammar and minor ui tweaks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-08 10:38:18 -07:00
leetcrypt eec1714735 feat(layout): input-bar + chat/clergy resize, masked sudo-for-docker, edit-mode unlock
Make the message-input bar part of the F5 resize cycle so its height is
adjustable without a sandbox (multi-line/wrapped inputs are now readable),
and let chat/clergy borrow height from the compose box when no terminal is
present. Add Option C masked sudo prompt that feeds `sudo -S` over stdin to
install/start Docker — the password never reaches chat, the PTY, or outbound
frames, and Docker Desktop on Linux is detected so no sudo is requested.

Fix a freeze where clicking the compose box entered layout-edit mode and
silently swallowed every keystroke: clicking the input bar no longer enters
edit mode, and typing any printable char now drops out of edit mode and types.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-07 16:10:27 -07:00
leetcrypt 9959e09fe2 docs(scripts): add --help to remaining scripts; document scripts + layout in README
CI / rust client (hh) (macos-latest) (push) Waiting to run
CI / rust client (hh) (ubuntu-latest) (push) Waiting to run
CI / rust coverage (push) Waiting to run
CI / python server (3.10) (push) Waiting to run
CI / python server (3.11) (push) Waiting to run
CI / python server (3.12) (push) Waiting to run
CI / headless e2e smoke (push) Waiting to run
CI / dependency audit (push) Waiting to run
CI / secret scanning (push) Waiting to run
- Add a -h/--help guard (prints the usage header) to the five scripts
  that lacked one: smoke.sh, smoke-e2e.sh, test-features.sh,
  demo-save-load.sh, sandbox-bootstrap.sh. All 15 hh/scripts/*.sh now
  respond to --help.
- README: new "Scripts" section detailing every script (setup, hosting,
  sandbox provisioning, tests) and noting each takes --help; plus an
  archive note for the film-* recording scripts.
- README: new "Window layout" section documenting live pane resizing
  (F4 fullscreen, click/F5 to select + arrows to resize) and the
  /layout save/load/list/rm/reset presets, with matching keybinding-table
  rows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-07 13:20:07 -07:00
leetcrypt cab266588d chore(scripts): archive film demos, fold join.sh into connect.sh
CI / rust client (hh) (macos-latest) (push) Waiting to run
CI / rust client (hh) (ubuntu-latest) (push) Waiting to run
CI / rust coverage (push) Waiting to run
CI / python server (3.10) (push) Waiting to run
CI / python server (3.11) (push) Waiting to run
CI / python server (3.12) (push) Waiting to run
CI / headless e2e smoke (push) Waiting to run
CI / dependency audit (push) Waiting to run
CI / secret scanning (push) Waiting to run
Trim newcomer-facing clutter in hh/scripts/ without changing the running
product or CI.

- Move the one-off demo-recording scripts (film-save-load.sh,
  film-virtualbox.sh) to scripts/archive/ — they depend on external
  personal tooling (asciinema, video-toolkit, edge-tts, xdotool) and were
  never wired into the README or CI.
- Delete join.sh: it duplicated connect.sh's join with fewer options
  (hardcoded port, plaintext-only). Its only unique behaviour — a
  pre-join git pull (gitea→origin, ff-only) + rebuild — is now an opt-in
  `--sync` flag on connect.sh, leaving one canonical joiner.

No scripts or docs referenced the removed/moved files, so nothing else
needed updating.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-07 13:12:46 -07:00
leetcrypt c9cdd2feca feat(sbx): install Docker/Multipass on demand from /sbx launch
CI / rust client (hh) (macos-latest) (push) Waiting to run
CI / rust client (hh) (ubuntu-latest) (push) Waiting to run
CI / rust coverage (push) Waiting to run
CI / python server (3.10) (push) Waiting to run
CI / python server (3.11) (push) Waiting to run
CI / python server (3.12) (push) Waiting to run
CI / headless e2e smoke (push) Waiting to run
CI / dependency audit (push) Waiting to run
CI / secret scanning (push) Waiting to run
Previously, launching a sandbox on a machine without the backend binary
died with a raw "not installed" error and no path forward. Now the
missing backend can be installed in-line, gated on explicit consent, so
a fresh checkout can go from zero to a running sandbox without leaving
the TUI.

Folded into the existing `/sbx launch` verb rather than a new command
(menu is already dense): `/sbx launch docker|multipass [image] install`.
The `install` token opts in; without it the user gets an actionable
error naming the exact retry. The token is filtered out of positional
image parsing so it never shadows a custom image.

The install runs off-thread inside the existing spawn_launch task,
before provisioning, so the TUI never blocks and the *launching guard is
cleared via BrokerMsg on failure. A fresh Docker install also leaves its
daemon up, so launch proceeds straight through.

Scripts (detect-first, never silent, --plan dry-run, idempotent if
already present):
- ensure-multipass.sh (new): Linux→snap (clear failure if snapd absent),
  macOS→brew cask, Windows→winget.
- ensure-docker.sh: new --install mode using Docker's OFFICIAL,
  GPG-verified apt repo (docker-ce) on Debian/Ubuntu, with dnf
  (Fedora/RHEL) and pacman (Arch) fallbacks. Deliberately avoids piping
  get.docker.com into a root shell. Existing daemon-start path intact.

sbx.rs: docker_installed()/multipass_installed() detectors and
ensure_docker_install()/ensure_multipass_install() wrappers; ENSURE_MULTIPASS const.

ui.rs: help text documents the [install] option on both backends.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-07 00:35:19 -07:00
leetcrypt 6160d957f5 feat(sbx): create fresh VirtualBox VMs via cloud-init (/sbx launch vbox new)
CI / rust client (hh) (macos-latest) (push) Waiting to run
CI / rust client (hh) (ubuntu-latest) (push) Waiting to run
CI / rust coverage (push) Waiting to run
CI / python server (3.10) (push) Waiting to run
CI / python server (3.11) (push) Waiting to run
CI / python server (3.12) (push) Waiting to run
CI / headless e2e smoke (push) Waiting to run
CI / dependency audit (push) Waiting to run
CI / secret scanning (push) Waiting to run
The existing vbox paths only open pre-made images; there was no way to
build one from scratch. Add `/sbx launch vbox new [name]` backed by
scripts/vbox-new.sh: download an Ubuntu cloud image, convert it to a VDI,
build a cloud-init NoCloud seed that creates a sudo login user and installs
the sandbox-tools.json toolchain on first boot, then create + boot the VM.

VirtualBox guests can't be exec'd into like docker/multipass, so cloud-init
is the provisioning channel. Generates a one-time login password (or takes
--pass) and authorizes a local SSH key if present. Runs off-thread; rolls
back a half-built VM on failure.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-06 22:33:37 -07:00
leetcrypt d448314e5e feat(sbx): VM dev-toolchain bootstrap + save/load parity across backends
Reorganize the help menu into one VIRTUAL MACHINES cluster covering all
backends, and bring docker/multipass/vbox to save+load parity:

- Launch-time dev toolchain: sandbox-bootstrap.sh + editable
  sandbox-tools.json (vim/curl guaranteed), installed in docker AND
  multipass sandboxes at provision time.
- Vbox load: vm_restore + `/sbx vmload <vm> [label]` (restore snapshot
  then boot the GUI).
- Multipass load: `/sbx load` is now backend-aware (locate_snapshot +
  SnapKind), mp_restore re-attaches the shared shell; teardown stops
  (not purges) an instance that still has snapshots so they survive
  `/sbx stop`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-06 22:29:24 -07:00
leetcrypt 7624cb04f7 feat(ux): F1 toggles help, --user flag, connect.sh fresh-build
CI / rust client (hh) (macos-latest) (push) Waiting to run
CI / rust client (hh) (ubuntu-latest) (push) Waiting to run
CI / rust coverage (push) Waiting to run
CI / python server (3.10) (push) Waiting to run
CI / python server (3.11) (push) Waiting to run
CI / python server (3.12) (push) Waiting to run
CI / headless e2e smoke (push) Waiting to run
CI / dependency audit (push) Waiting to run
CI / secret scanning (push) Waiting to run
- app.rs: F1 now closes the help overlay (toggle), not just opens it
- host-house.sh: add --user/--name flag to override the $USER default seat
- connect.sh: incremental cargo build before launch so the UI is never a
  stale release binary; --no-build escape hatch for toolchain-less joiners

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-06 21:51:54 -07:00
leetcrypt d948cdb63e fix(scripts): host-house.sh builds from main by default
CI / rust client (hh) (macos-latest) (push) Waiting to run
CI / rust client (hh) (ubuntu-latest) (push) Waiting to run
CI / rust coverage (push) Waiting to run
CI / python server (3.10) (push) Waiting to run
CI / python server (3.11) (push) Waiting to run
CI / python server (3.12) (push) Waiting to run
CI / headless e2e smoke (push) Waiting to run
CI / dependency audit (push) Waiting to run
CI / secret scanning (push) Waiting to run
Add a BRANCH guard (default: main) so launching the house never demos a
stale checkout. ensure_branch() switches to $BRANCH before the cargo build,
refuses when the tree is dirty (won't clobber uncommitted work), and no-ops
when already on-branch or when BRANCH= is passed to keep the current checkout.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-06 21:40:41 -07:00
leetcrypt 4a73eb04b9 feat(scripts): all-in-one host-house.sh; free stale port; fail-fast join sync
CI / rust client (hh) (macos-latest) (push) Waiting to run
CI / rust client (hh) (ubuntu-latest) (push) Waiting to run
CI / rust coverage (push) Waiting to run
CI / python server (3.10) (push) Waiting to run
CI / python server (3.11) (push) Waiting to run
CI / python server (3.12) (push) Waiting to run
CI / headless e2e smoke (push) Waiting to run
CI / dependency audit (push) Waiting to run
CI / secret scanning (push) Waiting to run
- host-house.sh: one tmux session hosting a room (server window) plus your own
  GUI client window — builds, frees the port, waits for /health, then attaches.
- host-room.sh: free_port() kills any stale LISTENer squatting on the port so
  the bind can't fail with "address already in use".
- join.sh: cap each remote pull with `timeout` + GIT_TERMINAL_PROMPT=0 so an
  unreachable remote fails fast instead of hanging.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-06 19:45:52 -07:00
leetcrypt 1fa8c332ed chore: consolidate all shell scripts into hh/scripts/
CI / rust client (hh) (macos-latest) (push) Waiting to run
CI / rust client (hh) (ubuntu-latest) (push) Waiting to run
CI / rust coverage (push) Waiting to run
CI / python server (3.10) (push) Waiting to run
CI / python server (3.11) (push) Waiting to run
CI / python server (3.12) (push) Waiting to run
CI / headless e2e smoke (push) Waiting to run
CI / dependency audit (push) Waiting to run
CI / secret scanning (push) Waiting to run
Move the 14 hack-house scripts (bootstrap, lets-hack, host-room, smoke,
demo/film harnesses, connect/join, ensure-docker/vbox) into hh/scripts/
and fix their path resolution for the deeper location. Update cross-refs:
sbx.rs script consts, app.rs hints, CI, direnv .envrc, README, and docs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-06 17:49:32 -07:00