From 30473a70318d53eb999d23311ce252b5217125aa Mon Sep 17 00:00:00 2001 From: Robby Cochran Date: Sun, 7 Jun 2026 18:52:42 -0700 Subject: [PATCH] refactor: launcher imports profile.Config from shared internal/profile package Replace duplicated Config struct, KeepSandbox(), and parseConfig() in sandbox/launcher with imports from internal/profile. The launcher module now depends on the parent module via a replace directive (resolved by go.work at build time). Launcher-specific functions (configureGateway, checkProviders, stageFiles, createSandbox, uploadFiles) are kept as-is. Co-Authored-By: Claude Opus 4.6 (1M context) --- sandbox/launcher/go.mod | 4 ++++ sandbox/launcher/main.go | 36 +++-------------------------------- sandbox/launcher/main_test.go | 10 ++++++---- 3 files changed, 13 insertions(+), 37 deletions(-) diff --git a/sandbox/launcher/go.mod b/sandbox/launcher/go.mod index 4d9bc5e..6d652ba 100644 --- a/sandbox/launcher/go.mod +++ b/sandbox/launcher/go.mod @@ -2,4 +2,8 @@ module github.com/robbycochran/harness-openshell/sandbox/launcher go 1.22.4 +require github.com/robbycochran/harness-openshell v0.0.0 + require github.com/BurntSushi/toml v1.6.0 // indirect + +replace github.com/robbycochran/harness-openshell => ../../ diff --git a/sandbox/launcher/main.go b/sandbox/launcher/main.go index 561814f..cbbc5d7 100644 --- a/sandbox/launcher/main.go +++ b/sandbox/launcher/main.go @@ -10,39 +10,9 @@ import ( "strings" "time" - "github.com/BurntSushi/toml" + "github.com/robbycochran/harness-openshell/internal/profile" ) -type Config struct { - Name string `toml:"name"` - From string `toml:"from"` - Command string `toml:"command"` - Keep *bool `toml:"keep"` - Providers []string `toml:"providers"` - Env map[string]string `toml:"env"` -} - -func (c *Config) KeepSandbox() bool { - if c.Keep == nil { - return true - } - return *c.Keep -} - -func parseConfig(path string) (*Config, error) { - var cfg Config - if _, err := toml.DecodeFile(path, &cfg); err != nil { - return nil, fmt.Errorf("parsing %s: %w", path, err) - } - if cfg.Name == "" { - cfg.Name = "agent" - } - if cfg.Command == "" { - cfg.Command = "claude --bare" - } - return &cfg, nil -} - func configureGateway(endpoint, mtlsDir, cli string) error { requiredCerts := []string{"ca.crt", "tls.crt", "tls.key"} var missing []string @@ -146,7 +116,7 @@ func stageFiles(harnessDir string) error { return nil } -func createSandbox(cfg *Config, providers []string, cli string) error { +func createSandbox(cfg *profile.Config, providers []string, cli string) error { fmt.Println("\n=== Creating sandbox ===") for attempt := 1; attempt <= 5; attempt++ { args := []string{"sandbox", "create", "--name", cfg.Name, "--no-tty"} @@ -243,7 +213,7 @@ func main() { os.Exit(1) } - cfg, err := parseConfig(configPath) + cfg, err := profile.ParseFile(configPath) if err != nil { fmt.Fprintf(os.Stderr, "ERROR: %v\n", err) os.Exit(1) diff --git a/sandbox/launcher/main_test.go b/sandbox/launcher/main_test.go index d2b8ec0..139a7d6 100644 --- a/sandbox/launcher/main_test.go +++ b/sandbox/launcher/main_test.go @@ -4,6 +4,8 @@ import ( "os" "path/filepath" "testing" + + "github.com/robbycochran/harness-openshell/internal/profile" ) func TestParseConfig_Full(t *testing.T) { @@ -21,7 +23,7 @@ ANTHROPIC_BASE_URL = "https://inference.local" JIRA_URL = "https://example.atlassian.net" `), 0o644) - cfg, err := parseConfig(path) + cfg, err := profile.ParseFile(path) if err != nil { t.Fatalf("parseConfig: %v", err) } @@ -58,7 +60,7 @@ func TestParseConfig_Defaults(t *testing.T) { from = "quay.io/test/sandbox:latest" `), 0o644) - cfg, err := parseConfig(path) + cfg, err := profile.ParseFile(path) if err != nil { t.Fatalf("parseConfig: %v", err) } @@ -77,7 +79,7 @@ from = "quay.io/test/sandbox:latest" } func TestParseConfig_Missing(t *testing.T) { - _, err := parseConfig("/nonexistent/config.toml") + _, err := profile.ParseFile("/nonexistent/config.toml") if err == nil { t.Error("expected error for missing file") } @@ -88,7 +90,7 @@ func TestParseConfig_Invalid(t *testing.T) { path := filepath.Join(dir, "config.toml") os.WriteFile(path, []byte(`not valid toml {{{{`), 0o644) - _, err := parseConfig(path) + _, err := profile.ParseFile(path) if err == nil { t.Error("expected error for invalid TOML") }