v2.12.0 — Bitwarden Password Manager SSH integration
Bitwarden Password Manager SSH integration
Servonaut now resolves SSH keys from your Bitwarden Password Manager vault through a server-side ref system. Personal and team-scoped refs are supported; local `~/.ssh` remains a fallback.
New CLI commands
```bash
servonaut ssh # connect via BW-resolved key (or local fallback)
servonaut servers verify # probe the BW key + report verify status to the audit log
```
The resolution chain walks personal → team → local in that order. BW key bodies live in a 0600 ephemeral tmpfile under `~/.servonaut/tmp/` that's wiped + unlinked on exit; a 24-hour sweeper handles crash-recovery on next startup.
New TUI surfaces (v2 default)
- "SSH" column on the instance table — at-a-glance verify-status badge. Renders "—" when no ref is stored or when `ssh_verified_at` is NULL per the server contract.
- R. Manage SSH Ref action — add / edit / delete the per-instance BW item ref. Modal lets you set `item_id`, optional `collection_id`, optional `vault_url`.
- V. Verify SSH action — runs the local probe and POSTs the result. Updates the row in place.
- Settings → Bitwarden SSH Vault section — configure your personal BW vault wiring (vault URL, default collection).
- Both R and V are top-level shortcuts on InstanceListScreen — no drilling into the actions menu required.
Discoverability fixes
- The actions menu now has three entry points: press Enter, press O (Open), or double-click a row. The footer always shows `o Actions` so users can discover the menu.
- DataTable was previously consuming Enter without surfacing it — this is fixed via the new `on_data_table_row_selected` handler.
Mercure relay listener
- Subscribes to both `/cli/{uid}/commands` (legacy) and `/cli/{uid}/ai-tool-calls` (new, PR #74 server-side) on one SSE connection.
- Bounded LRU dedup (256 entries, 5-min TTL) keyed by `tool_call_id` so the dual-publish transition window doesn't cause double-execution.
Wire contract guards (regression-tested)
- `ssh_credential_ref` is the body field — never `ref`. Test asserts `"ref" not in body`.
- `ssh_verified_at` is NULL whenever status ≠ `verified` — enforced client-side too, even if the server somehow returns a timestamp on a non-verified status.
- Provider whitelist `aws|ovh|hetzner` + instance_id regex `[A-Za-z0-9_\-]{1,64}` validated client-side so malformed inputs fail locally instead of round-tripping.
Test count
3985 passing, 5 skipped (+327 new tests covering all surfaces).
Coordination
Backend epic landed in prod earlier this week. CLI side is feature-complete. See #27 for the full PR.