Files
agent-lib/internal/client/config.go
T

112 lines
2.9 KiB
Go
Raw Normal View History

// Package client implements the employee side: config loading, work-repo
// pull, inventory, manifest and deployment into the OpenCode target.
package client
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"runtime"
)
// ClientConfig is the admin-protected fleet configuration for sync.
type ClientConfig struct {
RepoURL string `json:"repo_url"`
Ref string `json:"ref,omitempty"`
Token string `json:"token,omitempty"`
TokenUser string `json:"token_user,omitempty"`
}
// ConfigEnv names the override environment variables.
const (
ConfigEnv = "AGENT_LIB_CONFIG"
StateDirEnv = "AGENT_LIB_STATE_DIR"
defaultConfig = `{
"repo_url": "",
"ref": "",
"token": "",
"token_user": ""
}`
)
// DefaultConfigPath returns the admin-protected config location per platform:
// ProgramData on Windows, /etc on Linux/macOS.
func DefaultConfigPath() string {
if runtime.GOOS == "windows" {
if pd := os.Getenv("ProgramData"); pd != "" {
return filepath.Join(pd, "agent-lib", "config.json")
}
return `C:\ProgramData\agent-lib\config.json`
}
return "/etc/agent-lib/config.json"
}
// LoadClientConfig reads the config from flagPath, the override env, or the
// platform default — in that order.
func LoadClientConfig(flagPath string) (*ClientConfig, error) {
path := flagPath
if path == "" {
path = os.Getenv(ConfigEnv)
}
if path == "" {
path = DefaultConfigPath()
}
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("reading client config %s: %w", path, err)
}
var cfg ClientConfig
if err := json.Unmarshal(data, &cfg); err != nil {
return nil, fmt.Errorf("client config %s is not valid JSON: %w", path, err)
}
if cfg.RepoURL == "" {
return nil, fmt.Errorf("client config %s: repo_url is required", path)
}
return &cfg, nil
}
// StateDir returns the client state directory: the override env, then the
// platform default (LocalAppData on Windows, XDG state elsewhere).
func StateDir() (string, error) {
if d := os.Getenv(StateDirEnv); d != "" {
return d, nil
}
if runtime.GOOS == "windows" {
base := os.Getenv("LocalAppData")
if base == "" {
return "", fmt.Errorf("LocalAppData is not set")
}
return filepath.Join(base, "agent-lib"), nil
}
if xdg := os.Getenv("XDG_STATE_HOME"); xdg != "" {
return filepath.Join(xdg, "agent-lib"), nil
}
home, err := os.UserHomeDir()
if err != nil {
return "", err
}
return filepath.Join(home, ".local", "state", "agent-lib"), nil
}
// StatePaths bundles the well-known files inside the state dir.
type StatePaths struct {
Root string
CacheDir string
Manifest string
LogFile string
}
func ResolveStatePaths() (StatePaths, error) {
root, err := StateDir()
if err != nil {
return StatePaths{}, err
}
return StatePaths{
Root: root,
CacheDir: filepath.Join(root, "work-repo"),
Manifest: filepath.Join(root, "manifest.json"),
LogFile: filepath.Join(root, "sync.log"),
}, nil
}