diff --git a/server/config/picoclaw_internal.go b/server/config/picoclaw_internal.go index b9fb6638..84dbe570 100644 --- a/server/config/picoclaw_internal.go +++ b/server/config/picoclaw_internal.go @@ -2,9 +2,12 @@ package config import ( "os" + "os/user" "path/filepath" "strings" "sync" + + "gopkg.in/yaml.v3" ) const ( @@ -21,10 +24,18 @@ func GetPicoclawInternalToken() (string, error) { picoclawInternalToken.mu.Lock() defer picoclawInternalToken.mu.Unlock() + // Always try to read the live pico token from security.yml first + if token := readPicoclawSecurityToken(); token != "" { + picoclawInternalToken.value = token + return token, nil + } + + // Fall back to cached value if picoclawInternalToken.value != "" { return picoclawInternalToken.value, nil } + // Fall back to the legacy token file if token, err := readPicoclawInternalToken(); err == nil { if token != "" { picoclawInternalToken.value = token @@ -59,3 +70,44 @@ func readPicoclawInternalToken() (string, error) { return strings.TrimSpace(string(data)), nil } + +type picoclawSecurityYAML struct { + ChannelList map[string]struct { + Token string `yaml:"token,omitempty"` + Settings *struct { + Token string `yaml:"token,omitempty"` + } `yaml:"settings,omitempty"` + } `yaml:"channel_list,omitempty"` +} + +func readPicoclawSecurityToken() string { + home := os.Getenv("PICOCLAW_HOME") + if home == "" { + u, err := user.Current() + if err != nil { + return "" + } + home = filepath.Join(u.HomeDir, ".picoclaw") + } + + data, err := os.ReadFile(filepath.Join(home, ".security.yml")) + if err != nil { + return "" + } + + var sec picoclawSecurityYAML + if err := yaml.Unmarshal(data, &sec); err != nil { + return "" + } + + entry, ok := sec.ChannelList["pico"] + if !ok { + return "" + } + if entry.Settings != nil { + if t := strings.TrimSpace(entry.Settings.Token); t != "" { + return t + } + } + return strings.TrimSpace(entry.Token) +}