vm run redesign: one command, three modes

`vm run` now covers bare sandbox (no args), workspace sandbox (path),
and workspace+command (path -- cmd) in a single entry point. Replaces
the old print-next-steps-and-exit behaviour: bare and workspace modes
drop into interactive ssh, command mode execs via ssh and propagates
the remote exit code through banger's own exit status.

- path argument is optional; --branch / --from still require a path.
- workspace prep and mise tooling bootstrap only run when a path is
  given; command mode skips the bootstrap.
- remote command exit status is wrapped as exitCodeError so main() can
  propagate it instead of collapsing every failure to 1.
- README: promote vm run with three-mode examples; demote vm create
  to a scripting primitive.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Thales Maciel 2026-04-17 14:00:45 -03:00
parent 8f4be112c2
commit feb679a301
No known key found for this signature in database
GPG key ID: 33112E6833C34679
4 changed files with 376 additions and 225 deletions

View file

@ -2,6 +2,7 @@ package main
import (
"context"
"errors"
"fmt"
"os"
"os/signal"
@ -16,6 +17,10 @@ func main() {
cmd := cli.NewBangerCommand()
if err := cmd.ExecuteContext(ctx); err != nil {
var exitErr interface{ ExitCode() int }
if errors.As(err, &exitErr) {
os.Exit(exitErr.ExitCode())
}
fmt.Fprintf(os.Stderr, "banger: %v\n", err)
os.Exit(1)
}