bitwarden / bitwarden/agent-access
Feature request: --headless / --no-tui mode for `aac listen` (LaunchAgent / systemd / headless deployments)
- Dominant language
- Rust
- Stars
- 145
- Forks
- 11
- Avg merge
- 20h 57m
- Merged PRs (30d)
- 1
Description
## Feature request: `--headless` / `--no-tui` mode for `aac listen` (LaunchAgent / systemd / headless deployments)
### Summary
`aac listen` currently uses `ratatui` for its interactive TUI display, which requires a real controlling TTY. When run under macOS `launchd`, Linux `systemd`, or any headless service manager, `ratatui` panics at process start with:
```
The application panicked (crashed).
Message: failed to initialize terminal: Os { code: 6, kind: Uncategorized, message: "Device not configured" }
Location: /Users/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ratatui-0.29.0/src/terminal/init.rs:52
```
Request: add a `--headless` (or `--no-tui`) flag to `aac listen` that disables the TUI and emits structured log lines (or JSON events) instead. This unblocks fleet deployments where `aac listen` runs as a supervised system service.
### Version
`aac 0.11.0` (`3b000d15af71be5ddcf8893b099f3a66d386be9d`)
### Reproducer (macOS launchd)
`~/Library/LaunchAgents/com.example.aac_listen.plist`:
```xml
Labelcom.example.aac_listen
ProgramArguments
/opt/homebrew/bin/aac
listen
--reusable-psk
--provider
bitwarden
-v
RunAtLoad
KeepAlive
StandardOutPath/tmp/aac_listen.log
StandardErrorPath/tmp/aac_listen.err
EnvironmentVariables
BW_SESSION...
```
`launchctl load ~/Library/LaunchAgents/com.example.aac_listen.plist` — `/tmp/aac_listen.err` fills with the ratatui panic; `KeepAlive` respawns the process; the crash loop repeats indefinitely.
### Workaround we tried (partial, insufficient)
Wrapping the invocation in `script(1) -q /dev/null` to synthesise a PTY:
```bash
exec /usr/bin/script -q /dev/null /opt/homebrew/bin/aac listen --reusable-psk --provider bitwarden -v
```
`script(1)` provides a pseudo-terminal but ratatui still panics under `launchd`'s session detachment context (empirically observed — panic message unchanged). The only reliable substrate today is a foreground `aac listen` inside `Terminal.app` (real device TTY), which is not viable for autonomous fleet operation.
### Real-world impact
We operate 3 `aac` client daemons (Bitwarden Agent Access consumers) that depend on a single `aac listen` process on the same host. When the LaunchAgent-managed `aac listen` panics on TTY init and crash-loops, every client daemon exits with `Credential request failed: Request denied` (or `Timeout waiting for credential response`) and enters its own crash-loop. This surfaced as a 3-day, 13-hour silent outage in our deployment before we diagnosed it. The only remediation was to fall back to foreground `aac listen` inside a persistent Terminal window — not a defensible production pattern.
### Suggested shape
`aac listen --headless` (or `--no-tui`) that:
- Skips all `ratatui`/`crossterm` initialisation
- Emits structured line-oriented events to stdout (or a `--log-format json` option that emits JSON per event: pair request received, credential request, credential approved, credential denied, session started, session ended, error)
- Retains all other flags (`--reusable-psk`, `--provider`, `--proxy-url`, `--verbose`)
- Optionally: auto-detect headless mode when `isatty(stdout) == false` and switch to line-oriented output automatically, without requiring the explicit flag
### Alternative approaches considered
- **`script(1)` PTY shim** — insufficient (documented above)
- **`expect` / `pty4j` full virtual-terminal wrapper** — heavier substrate; still fragile against ratatui's device-configuration probing
- **Fork ratatui / patch aac source to skip TUI init on no-TTY** — feasible as a local fork but not a durable upstream solution
An upstream `--headless` mode is the cleanest fix and would unblock a common deployment class (system service supervisors) for the broader `aac` user base.
### Files (helpful references)
- ratatui panic location: `ratatui-0.29.0/src/terminal/init.rs:52`
- Related crate: `crossterm` (used by ratatui for device detection)
Happy to test any prototype build. Thanks for `aac` — the credential-tunnel model is exactly what our multi-agent stack needed.
Contributor guide
Research direction
Start at the `aac listen` command and trace where ratatui and crossterm initialize the terminal. Define how the headless path preserves the existing listen flags and emits line-oriented events, then verify it runs under launchd or systemd without TUI initialization and covers the listed session and credential events.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli, devops
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100