- -l/-r/-d now show their actual grammar as the clap value name
(<[BIND:]PORT:HOST:PORT>, <[BIND:]PORT>) instead of a generic <SPEC>,
matching vmic's convention of showing real syntax in --help. The
grammar is no longer also repeated in the flag's help text, since the
value name already carries it.
- --via changes from a single comma-separated flag to a repeatable one
(Vec<String> + value_delimiter = ','), so both `--via a --via b` and
`--via a,b` work and can be mixed. commands/mod.rs's edits_from_mapping
no longer needs to split the string itself - clap does it.
- Trimmed CLI help text that restated grammar/rationale already covered
by the value name or by --via being required.
- Normalized code comments for tone/format consistency: dropped
cross-references to vmic's own internals as justification (this
codebase should read as self-contained), removed markdown-style
*emphasis* asterisks that don't render in plain comments, tightened
several run-on sentences into plain declarative ones, and fixed one
comment in wipe.rs that inaccurately described close_instance's force
path (it sends SIGKILL, not SIGTERM).
- spec/porthole-spec.md's --via row updated to document the repeatable
form alongside comma-separated.
Cargo.toml/Cargo.lock/atomic.rs also carry an external toml crate bump
and formatting pass picked up from the working tree.
Found both while translating the spec into code:
- `ssh -J a,b,c` alone isn't valid - ssh -J only carries jump hosts
before the final hop; it still needs a positional destination. --via's
last entry has to double as that target, which also makes --via
mandatory (there's no other field naming "the host ssh connects to"),
reversing the earlier "no" in the required column.
- A plain single-pid SIGKILL on `close --force` would leave the `ssh`
child orphaned, since a killed process can't forward anything to it.
Documents sending SIGKILL to the whole process group instead, relying
on the supervisor's own setsid() call making it the group leader.
Bumps to v0.2. Resolves the open questions and design gaps flagged during
review before implementation starts:
- Spells out the supervisor detach/re-exec mechanism (§3), mirroring how
vmic solves the same one-shot-CLI-can't-host-a-daemon problem.
- Forces BatchMode/ExitOnForwardFailure/ConnectTimeout on every ssh
invocation so headless failures surface instead of hanging on a TTY
prompt (§3.1).
- Adds backoff + stderr-based fatal/transient failure classification so
reconnect doesn't retry forever against a permanently broken profile
(§4).
- Collapses the Instance `state` enum to up/reconnecting/error, with
"no instance file" as the sole meaning of closed, removing the prior
ambiguity around close vs. crash vs. down (§2.2, §3).
- Fixes --via's conflicting comma-list-vs-repeated-flag examples by
committing to a straight ssh -J passthrough grammar (§3.1/§5.1).
- Resolves the edit --restart open question: no --restart, stays explicit.
- Simplifies exit codes to 0/1/2 (was a 6-code table with its own TODO).
- Adds a lock file for concurrent-open safety and a log rotation policy.
- Calls out reboot/logout survival as an explicit v0.1 non-goal, with
`open --all` as the only hook left for external autostart wiring (§8).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>