mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
refactor: centralize environment variable key constants (#1730)
* refactor: centralize environment variable key constants * refactor: update environment variable constants and usage in gateway
This commit is contained in:
@@ -12,7 +12,7 @@ const Logo = "🦞"
|
||||
// GetPicoclawHome returns the picoclaw home directory.
|
||||
// Priority: $PICOCLAW_HOME > ~/.picoclaw
|
||||
func GetPicoclawHome() string {
|
||||
if home := os.Getenv("PICOCLAW_HOME"); home != "" {
|
||||
if home := os.Getenv(config.EnvHome); home != "" {
|
||||
return home
|
||||
}
|
||||
home, _ := os.UserHomeDir()
|
||||
@@ -20,7 +20,7 @@ func GetPicoclawHome() string {
|
||||
}
|
||||
|
||||
func GetConfigPath() string {
|
||||
if configPath := os.Getenv("PICOCLAW_CONFIG"); configPath != "" {
|
||||
if configPath := os.Getenv(config.EnvConfig); configPath != "" {
|
||||
return configPath
|
||||
}
|
||||
return filepath.Join(GetPicoclawHome(), "config.json")
|
||||
|
||||
@@ -52,7 +52,7 @@ func (cb *ContextBuilder) WithToolDiscovery(useBM25, useRegex bool) *ContextBuil
|
||||
}
|
||||
|
||||
func getGlobalConfigDir() string {
|
||||
if home := os.Getenv("PICOCLAW_HOME"); home != "" {
|
||||
if home := os.Getenv(config.EnvHome); home != "" {
|
||||
return home
|
||||
}
|
||||
home, err := os.UserHomeDir()
|
||||
@@ -65,7 +65,7 @@ func getGlobalConfigDir() string {
|
||||
func NewContextBuilder(workspace string) *ContextBuilder {
|
||||
// builtin skills: skills directory in current project
|
||||
// Use the skills/ directory under the current working directory
|
||||
builtinSkillsDir := strings.TrimSpace(os.Getenv("PICOCLAW_BUILTIN_SKILLS"))
|
||||
builtinSkillsDir := strings.TrimSpace(os.Getenv(config.EnvBuiltinSkills))
|
||||
if builtinSkillsDir == "" {
|
||||
wd, _ := os.Getwd()
|
||||
builtinSkillsDir = filepath.Join(wd, "skills")
|
||||
|
||||
+2
-1
@@ -6,6 +6,7 @@ import (
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/sipeed/picoclaw/pkg/config"
|
||||
"github.com/sipeed/picoclaw/pkg/fileutil"
|
||||
)
|
||||
|
||||
@@ -39,7 +40,7 @@ func (c *AuthCredential) NeedsRefresh() bool {
|
||||
}
|
||||
|
||||
func authFilePath() string {
|
||||
if home := os.Getenv("PICOCLAW_HOME"); home != "" {
|
||||
if home := os.Getenv(config.EnvHome); home != "" {
|
||||
return filepath.Join(home, "auth.json")
|
||||
}
|
||||
home, _ := os.UserHomeDir()
|
||||
|
||||
@@ -15,7 +15,7 @@ func DefaultConfig() *Config {
|
||||
// Determine the base path for the workspace.
|
||||
// Priority: $PICOCLAW_HOME > ~/.picoclaw
|
||||
var homePath string
|
||||
if picoclawHome := os.Getenv("PICOCLAW_HOME"); picoclawHome != "" {
|
||||
if picoclawHome := os.Getenv(EnvHome); picoclawHome != "" {
|
||||
homePath = picoclawHome
|
||||
} else {
|
||||
userHome, _ := os.UserHomeDir()
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// PicoClaw - Ultra-lightweight personal AI agent
|
||||
// License: MIT
|
||||
//
|
||||
// Copyright (c) 2026 PicoClaw contributors
|
||||
|
||||
package config
|
||||
|
||||
// Runtime environment variable keys for the picoclaw process.
|
||||
// These control the location of files and binaries at runtime and are read
|
||||
// directly via os.Getenv / os.LookupEnv. All picoclaw-specific keys use the
|
||||
// PICOCLAW_ prefix. Reference these constants instead of inline string
|
||||
// literals to keep all supported knobs visible in one place and to prevent
|
||||
// typos.
|
||||
const (
|
||||
// EnvHome overrides the base directory for all picoclaw data
|
||||
// (config, workspace, skills, auth store, …).
|
||||
// Default: ~/.picoclaw
|
||||
EnvHome = "PICOCLAW_HOME"
|
||||
|
||||
// EnvConfig overrides the full path to the JSON config file.
|
||||
// Default: $PICOCLAW_HOME/config.json
|
||||
EnvConfig = "PICOCLAW_CONFIG"
|
||||
|
||||
// EnvBuiltinSkills overrides the directory from which built-in
|
||||
// skills are loaded.
|
||||
// Default: <cwd>/skills
|
||||
EnvBuiltinSkills = "PICOCLAW_BUILTIN_SKILLS"
|
||||
|
||||
// EnvBinary overrides the path to the picoclaw executable.
|
||||
// Used by the web launcher when spawning the gateway subprocess.
|
||||
// Default: resolved from the same directory as the current executable.
|
||||
EnvBinary = "PICOCLAW_BINARY"
|
||||
|
||||
// EnvGatewayHost overrides the host address for the gateway server.
|
||||
// Default: "127.0.0.1"
|
||||
EnvGatewayHost = "PICOCLAW_GATEWAY_HOST"
|
||||
)
|
||||
@@ -66,6 +66,14 @@ var ErrPassphraseRequired = errors.New("credential: enc:// passphrase required")
|
||||
// indicating a wrong passphrase or SSH key. Callers can detect this with errors.Is.
|
||||
var ErrDecryptionFailed = errors.New("credential: enc:// decryption failed (wrong passphrase or SSH key?)")
|
||||
|
||||
// SSHKeyPathEnvVar is the environment variable that specifies the path to the
|
||||
// SSH private key used for enc:// credential encryption and decryption.
|
||||
const SSHKeyPathEnvVar = "PICOCLAW_SSH_KEY_PATH"
|
||||
|
||||
// picoclawHome is a package-local copy of config.EnvHome. It is kept here to
|
||||
// avoid a circular import between pkg/credential and pkg/config.
|
||||
const picoclawHome = "PICOCLAW_HOME"
|
||||
|
||||
const (
|
||||
fileScheme = "file://"
|
||||
encScheme = "enc://"
|
||||
@@ -73,7 +81,6 @@ const (
|
||||
saltLen = 16
|
||||
nonceLen = 12
|
||||
keyLen = 32
|
||||
sshKeyEnv = "PICOCLAW_SSH_KEY_PATH"
|
||||
)
|
||||
|
||||
// Resolver resolves raw credential strings for model_list api_key fields.
|
||||
@@ -248,14 +255,14 @@ func allowedSSHKeyPath(path string) bool {
|
||||
clean := filepath.Clean(path)
|
||||
|
||||
// Exact match with PICOCLAW_SSH_KEY_PATH.
|
||||
if envPath, ok := os.LookupEnv(sshKeyEnv); ok && envPath != "" {
|
||||
if envPath, ok := os.LookupEnv(SSHKeyPathEnvVar); ok && envPath != "" {
|
||||
if clean == filepath.Clean(envPath) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Within PICOCLAW_HOME.
|
||||
if picoHome := os.Getenv("PICOCLAW_HOME"); picoHome != "" {
|
||||
if picoHome := os.Getenv(picoclawHome); picoHome != "" {
|
||||
if isWithinDir(clean, picoHome) {
|
||||
return true
|
||||
}
|
||||
@@ -316,7 +323,7 @@ func pickSSHKeyPath(override string) string {
|
||||
if override != "" {
|
||||
return override
|
||||
}
|
||||
if p, ok := os.LookupEnv(sshKeyEnv); ok {
|
||||
if p, ok := os.LookupEnv(SSHKeyPathEnvVar); ok {
|
||||
return p // respect explicit setting, even if ""
|
||||
}
|
||||
return findDefaultSSHKey()
|
||||
|
||||
@@ -5,13 +5,15 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/sipeed/picoclaw/pkg/config"
|
||||
)
|
||||
|
||||
func ResolveTargetHome(override string) (string, error) {
|
||||
if override != "" {
|
||||
return ExpandHome(override), nil
|
||||
}
|
||||
if envHome := os.Getenv("PICOCLAW_HOME"); envHome != "" {
|
||||
if envHome := os.Getenv(config.EnvHome); envHome != "" {
|
||||
return ExpandHome(envHome), nil
|
||||
}
|
||||
home, err := os.UserHomeDir()
|
||||
|
||||
@@ -10,6 +10,11 @@ import (
|
||||
"github.com/sipeed/picoclaw/pkg/migrate/internal"
|
||||
)
|
||||
|
||||
// OpenclawHomeEnvVar is the environment variable that overrides the source
|
||||
// openclaw home directory when migrating from openclaw to picoclaw.
|
||||
// Default: ~/.openclaw
|
||||
const OpenclawHomeEnvVar = "OPENCLAW_HOME"
|
||||
|
||||
var providerMapping = map[string]string{
|
||||
"anthropic": "anthropic",
|
||||
"claude": "anthropic",
|
||||
@@ -112,7 +117,7 @@ func resolveSourceHome(override string) (string, error) {
|
||||
if override != "" {
|
||||
return internal.ExpandHome(override), nil
|
||||
}
|
||||
if envHome := os.Getenv("OPENCLAW_HOME"); envHome != "" {
|
||||
if envHome := os.Getenv(OpenclawHomeEnvVar); envHome != "" {
|
||||
return internal.ExpandHome(envHome), nil
|
||||
}
|
||||
home, err := os.UserHomeDir()
|
||||
|
||||
@@ -8,6 +8,11 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// CodexHomeEnvVar is the environment variable that overrides the Codex CLI
|
||||
// home directory when resolving the codex auth.json credentials file.
|
||||
// Default: ~/.codex
|
||||
const CodexHomeEnvVar = "CODEX_HOME"
|
||||
|
||||
// CodexCliAuth represents the ~/.codex/auth.json file structure.
|
||||
type CodexCliAuth struct {
|
||||
Tokens struct {
|
||||
@@ -69,7 +74,7 @@ func CreateCodexCliTokenSource() func() (string, string, error) {
|
||||
}
|
||||
|
||||
func resolveCodexAuthPath() (string, error) {
|
||||
codexHome := os.Getenv("CODEX_HOME")
|
||||
codexHome := os.Getenv(CodexHomeEnvVar)
|
||||
if codexHome == "" {
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
|
||||
@@ -387,10 +387,10 @@ func (h *Handler) startGatewayLocked(initialStatus string, existingPid int) (int
|
||||
// GetConfigPath() already reads, so the gateway sub-process uses the same
|
||||
// config file without requiring a --config flag on the gateway subcommand.
|
||||
if h.configPath != "" {
|
||||
cmd.Env = append(cmd.Env, "PICOCLAW_CONFIG="+h.configPath)
|
||||
cmd.Env = append(cmd.Env, config.EnvConfig+"="+h.configPath)
|
||||
}
|
||||
if host := h.gatewayHostOverride(); host != "" {
|
||||
cmd.Env = append(cmd.Env, "PICOCLAW_GATEWAY_HOST="+host)
|
||||
cmd.Env = append(cmd.Env, config.EnvGatewayHost+"="+host)
|
||||
}
|
||||
|
||||
stdoutPipe, err := cmd.StdoutPipe()
|
||||
|
||||
@@ -309,7 +309,7 @@ func loadSkillContent(path string) (string, error) {
|
||||
}
|
||||
|
||||
func globalConfigDir() string {
|
||||
if home := os.Getenv("PICOCLAW_HOME"); home != "" {
|
||||
if home := os.Getenv(config.EnvHome); home != "" {
|
||||
return home
|
||||
}
|
||||
home, err := os.UserHomeDir()
|
||||
@@ -320,7 +320,7 @@ func globalConfigDir() string {
|
||||
}
|
||||
|
||||
func builtinSkillsDir() string {
|
||||
if path := os.Getenv("PICOCLAW_BUILTIN_SKILLS"); path != "" {
|
||||
if path := os.Getenv(config.EnvBuiltinSkills); path != "" {
|
||||
return path
|
||||
}
|
||||
wd, err := os.Getwd()
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/sipeed/picoclaw/pkg/config"
|
||||
)
|
||||
|
||||
var execCommand = exec.Command
|
||||
@@ -19,7 +21,7 @@ func EnsureOnboarded(configPath string) error {
|
||||
}
|
||||
|
||||
cmd := execCommand(FindPicoclawBinary(), "onboard")
|
||||
cmd.Env = append(os.Environ(), "PICOCLAW_CONFIG="+configPath)
|
||||
cmd.Env = append(os.Environ(), config.EnvConfig+"="+configPath)
|
||||
cmd.Stdin = strings.NewReader("n\n")
|
||||
|
||||
output, err := cmd.CombinedOutput()
|
||||
|
||||
@@ -7,20 +7,23 @@ import (
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"github.com/sipeed/picoclaw/pkg/config"
|
||||
)
|
||||
|
||||
// GetPicoclawHome returns the picoclaw home directory.
|
||||
// Priority: $PICOCLAW_HOME > ~/.picoclaw
|
||||
func GetPicoclawHome() string {
|
||||
if home := os.Getenv("PICOCLAW_HOME"); home != "" {
|
||||
if home := os.Getenv(config.EnvHome); home != "" {
|
||||
return home
|
||||
}
|
||||
home, _ := os.UserHomeDir()
|
||||
return filepath.Join(home, ".picoclaw")
|
||||
}
|
||||
|
||||
// GetDefaultConfigPath returns the default path to the picoclaw config file.
|
||||
func GetDefaultConfigPath() string {
|
||||
if configPath := os.Getenv("PICOCLAW_CONFIG"); configPath != "" {
|
||||
if configPath := os.Getenv(config.EnvConfig); configPath != "" {
|
||||
return configPath
|
||||
}
|
||||
return filepath.Join(GetPicoclawHome(), "config.json")
|
||||
@@ -37,7 +40,7 @@ func FindPicoclawBinary() string {
|
||||
binaryName = "picoclaw.exe"
|
||||
}
|
||||
|
||||
if p := os.Getenv("PICOCLAW_BINARY"); p != "" {
|
||||
if p := os.Getenv(config.EnvBinary); p != "" {
|
||||
if info, _ := os.Stat(p); info != nil && !info.IsDir() {
|
||||
return p
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user