package hub import ( "fmt" "os" "os/exec" "path/filepath" "strings" ) // Install clones a GitHub repo (owner/repo or full URL) and installs the team. func Install(repoRef, agentsDir, skillsDir string) error { url := repoRef if !strings.HasPrefix(repoRef, "http") { url = "https://github.com/" + repoRef } tmp, err := os.MkdirTemp("", "agent-team-hub-*") if err != nil { return err } defer os.RemoveAll(tmp) cmd := exec.Command("git", "clone", "--depth=1", url, tmp) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { return fmt.Errorf("git clone: %w", err) } // Copy agents/ if err := copyDir(filepath.Join(tmp, "agents"), agentsDir); err != nil { return fmt.Errorf("install agents: %w", err) } // Copy skills/ if err := copyDir(filepath.Join(tmp, "skills"), skillsDir); err != nil { return fmt.Errorf("install skills: %w", err) } return nil } func copyDir(src, dst string) error { if _, err := os.Stat(src); os.IsNotExist(err) { return nil // optional dir, skip } os.MkdirAll(dst, 0755) entries, err := os.ReadDir(src) if err != nil { return err } for _, e := range entries { srcPath := filepath.Join(src, e.Name()) dstPath := filepath.Join(dst, e.Name()) if e.IsDir() { if err := copyDir(srcPath, dstPath); err != nil { return err } } else { data, err := os.ReadFile(srcPath) if err != nil { return err } os.MkdirAll(filepath.Dir(dstPath), 0755) if err := os.WriteFile(dstPath, data, 0644); err != nil { return err } } } return nil }