Add guest sessions and agent VM defaults

Add daemon-backed workspace and guest-session primitives so host
orchestrators can prepare /root/repo, launch long-lived guest commands,
and attach to pipe-mode sessions over the local stdio mux bridge.

Persist richer session metadata and launch diagnostics, preflight guest
cwd/command requirements, make pipe-mode attach rehydratable from guest
state after daemon restart, and allow submodules when workspace prepare
runs in full_copy mode.

At the same time, stop vm run from auto-attaching opencode, make it
print next-step commands instead, and make glibc guest images more
agent-ready by installing node, opencode, claude, and pi while syncing
opencode/claude/pi auth files into work disks on VM start.

Validation:
- GOCACHE=/tmp/banger-gocache go test ./...
- make build
- banger vm workspace prepare --help
- banger vm session --help
- banger vm session start --help
- banger vm session attach --help
This commit is contained in:
Thales Maciel 2026-04-12 23:48:42 -03:00
parent 497e6dca3d
commit 37c4c091ec
No known key found for this signature in database
GPG key ID: 33112E6833C34679
18 changed files with 3212 additions and 405 deletions

View file

@ -150,6 +150,73 @@ type VMPortsResult struct {
Ports []VMPort `json:"ports"`
}
type GuestSessionStartParams struct {
VMIDOrName string `json:"vm_id_or_name"`
Name string `json:"name,omitempty"`
Command string `json:"command"`
Args []string `json:"args,omitempty"`
CWD string `json:"cwd,omitempty"`
Env map[string]string `json:"env,omitempty"`
StdinMode string `json:"stdin_mode,omitempty"`
Tags map[string]string `json:"tags,omitempty"`
RequiredCommands []string `json:"required_commands,omitempty"`
}
type GuestSessionRefParams struct {
VMIDOrName string `json:"vm_id_or_name"`
SessionIDOrName string `json:"session_id_or_name"`
}
type GuestSessionLogsParams struct {
VMIDOrName string `json:"vm_id_or_name"`
SessionIDOrName string `json:"session_id_or_name"`
Stream string `json:"stream,omitempty"`
TailLines int `json:"tail_lines,omitempty"`
}
type GuestSessionAttachBeginParams struct {
VMIDOrName string `json:"vm_id_or_name"`
SessionIDOrName string `json:"session_id_or_name"`
}
type GuestSessionListResult struct {
Sessions []model.GuestSession `json:"sessions"`
}
type GuestSessionShowResult struct {
Session model.GuestSession `json:"session"`
}
type GuestSessionLogsResult struct {
Session model.GuestSession `json:"session"`
Stream string `json:"stream"`
Path string `json:"path,omitempty"`
Content string `json:"content,omitempty"`
}
type GuestSessionAttachBeginResult struct {
Session model.GuestSession `json:"session"`
AttachID string `json:"attach_id"`
TransportKind string `json:"transport_kind"`
TransportTarget string `json:"transport_target"`
SocketPath string `json:"socket_path,omitempty"`
StreamFormat string `json:"stream_format"`
}
type VMWorkspacePrepareParams struct {
IDOrName string `json:"id_or_name"`
SourcePath string `json:"source_path"`
GuestPath string `json:"guest_path,omitempty"`
Branch string `json:"branch,omitempty"`
From string `json:"from,omitempty"`
Mode string `json:"mode,omitempty"`
ReadOnly bool `json:"readonly,omitempty"`
}
type VMWorkspacePrepareResult struct {
Workspace model.WorkspacePrepareResult `json:"workspace"`
}
type ImageBuildParams struct {
Name string `json:"name,omitempty"`
FromImage string `json:"from_image,omitempty"`