Bootstrap vm run tooling before attach

Speed up first use of repo backed VMs by bootstrapping obvious tools before
the best effort LLM harness runs.

Add a host side tooling plan for pinned Go, Node, Python, and Rust versions,
summarize that plan in the uploaded prompt, and run repo mise install plus
guest global mise use -g --pin steps before the bounded opencode inspection.

Keep the harness non fatal, prefer host opencode attach when the client
supports it, fall back to guest opencode over SSH for older clients, and
cover the new flow with CLI plus planner tests.

Validation:
- go test ./internal/cli ./internal/toolingplan
- GOCACHE=/tmp/banger-gocache go test ./...
- make build
This commit is contained in:
Thales Maciel 2026-03-29 11:38:05 -03:00
parent 1e967140c3
commit 4813e844e2
No known key found for this signature in database
GPG key ID: 33112E6833C34679
10 changed files with 1126 additions and 13 deletions

View file

@ -0,0 +1,41 @@
package toolingplan
import (
"encoding/json"
"regexp"
"strings"
)
var (
exactVersionPattern = regexp.MustCompile(`^v?\d+(?:\.\d+){0,2}(?:[-+][0-9A-Za-z.-]+)?$`)
goDirectivePattern = regexp.MustCompile(`(?m)^go\s+([0-9]+(?:\.[0-9]+){1,2})\s*$`)
)
func normalizeExactVersion(value string) (string, bool) {
trimmed := strings.TrimSpace(value)
if !exactVersionPattern.MatchString(trimmed) {
return "", false
}
return strings.TrimPrefix(trimmed, "v"), true
}
func parseGoDirective(goMod string) (string, bool) {
matches := goDirectivePattern.FindStringSubmatch(goMod)
if len(matches) != 2 {
return "", false
}
return matches[1], true
}
type packageJSONMetadata struct {
PackageManager string `json:"packageManager"`
Volta struct {
Node string `json:"node"`
} `json:"volta"`
}
func parsePackageJSON(data string) (packageJSONMetadata, error) {
var meta packageJSONMetadata
err := json.Unmarshal([]byte(data), &meta)
return meta, err
}