backward compat fixes

Signed-off-by: Kai Xia <kaix+github@fastmail.com>
This commit is contained in:
Kai Xia 2026-02-16 00:11:22 +11:00
parent 2b9b7720e3
commit 7ba0330fd7
11 changed files with 45 additions and 124 deletions

View file

@ -6,7 +6,7 @@ package main
import (
"fmt"
"github.com/sipeed/picoclaw/cmd/picoclaw/auth"
authpkg "github.com/sipeed/picoclaw/cmd/picoclaw/auth"
"github.com/spf13/cobra"
)
@ -20,9 +20,13 @@ var authCmd = &cobra.Command{
}
func init() {
authCmd.AddCommand(auth.LoginCmd)
authCmd.AddCommand(auth.LogoutCmd)
authCmd.AddCommand(auth.StatusCmd)
authCmd.PersistentPreRun = func(cmd *cobra.Command, args []string) {
authpkg.SetConfigPath(getConfigPath())
}
authCmd.AddCommand(authpkg.LoginCmd)
authCmd.AddCommand(authpkg.LogoutCmd)
authCmd.AddCommand(authpkg.StatusCmd)
}
func authHelp() {

10
cmd/picoclaw/auth/auth.go Normal file
View file

@ -0,0 +1,10 @@
// PicoClaw - Ultra-lightweight personal AI agent
// License: MIT
package auth
var configPath string
func SetConfigPath(path string) {
configPath = path
}

View file

@ -37,15 +37,6 @@ func init() {
LoginCmd.Flags().BoolVar(&loginDeviceCode, "device-code", false, "Use device code flow (for headless environments)")
}
func getConfigPath() string {
home, _ := os.UserHomeDir()
return fmt.Sprintf("%s/.picoclaw/config.json", home)
}
func loadConfig() (*config.Config, error) {
return config.LoadConfig(getConfigPath())
}
func loginImpl() {
switch loginProvider {
case "openai":
@ -81,10 +72,10 @@ func loginOpenAI(useDeviceCode bool) {
os.Exit(1)
}
appCfg, err := loadConfig()
appCfg, err := config.LoadConfig(configPath)
if err == nil {
appCfg.Providers.OpenAI.AuthMethod = "oauth"
if err := config.SaveConfig(getConfigPath(), appCfg); err != nil {
if err := config.SaveConfig(configPath, appCfg); err != nil {
fmt.Printf("Warning: could not update config: %v\n", err)
}
}
@ -107,7 +98,7 @@ func loginPasteToken(provider string) {
os.Exit(1)
}
appCfg, err := loadConfig()
appCfg, err := config.LoadConfig(configPath)
if err == nil {
switch provider {
case "anthropic":
@ -115,7 +106,7 @@ func loginPasteToken(provider string) {
case "openai":
appCfg.Providers.OpenAI.AuthMethod = "token"
}
if err := config.SaveConfig(getConfigPath(), appCfg); err != nil {
if err := config.SaveConfig(configPath, appCfg); err != nil {
fmt.Printf("Warning: could not update config: %v\n", err)
}
}

View file

@ -34,7 +34,7 @@ func logoutImpl() {
os.Exit(1)
}
appCfg, err := loadConfig()
appCfg, err := config.LoadConfig(configPath)
if err == nil {
switch logoutProvider {
case "openai":
@ -42,7 +42,7 @@ func logoutImpl() {
case "anthropic":
appCfg.Providers.Anthropic.AuthMethod = ""
}
config.SaveConfig(getConfigPath(), appCfg)
config.SaveConfig(configPath, appCfg)
}
fmt.Printf("Logged out from %s\n", logoutProvider)
@ -52,11 +52,11 @@ func logoutImpl() {
os.Exit(1)
}
appCfg, err := loadConfig()
appCfg, err := config.LoadConfig(configPath)
if err == nil {
appCfg.Providers.OpenAI.AuthMethod = ""
appCfg.Providers.Anthropic.AuthMethod = ""
config.SaveConfig(getConfigPath(), appCfg)
config.SaveConfig(configPath, appCfg)
}
fmt.Println("Logged out from all providers")

View file

@ -46,7 +46,7 @@ func init() {
AddCmd.Flags().StringVarP(&cronName, "name", "n", "", "Job name (required)")
AddCmd.Flags().StringVarP(&cronMessage, "message", "m", "", "Message for agent (required)")
AddCmd.Flags().StringVarP(&cronCronExpr, "cron", "c", "", "Cron expression (e.g. '0 9 * * *')")
AddCmd.Flags().StringVarP(&cronTo, "to", "", "", "Recipient for delivery")
AddCmd.Flags().StringVar(&cronTo, "to", "", "Recipient for delivery")
AddCmd.Flags().StringVar(&cronChannel, "channel", "", "Channel for delivery")
AddCmd.Flags().Int64VarP(&cronEvery, "every", "e", 0, "Run every N seconds")
AddCmd.Flags().BoolVarP(&cronDeliver, "deliver", "d", false, "Deliver response to channel")

View file

@ -6,7 +6,6 @@ package main
import (
"embed"
"fmt"
"io"
"io/fs"
"os"
"path/filepath"
@ -57,61 +56,6 @@ func onboard() {
fmt.Println(" 2. Chat: picoclaw agent -m \"Hello!\"")
}
func copyDirectory(src, dst string) error {
return filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
relPath, err := filepath.Rel(src, path)
if err != nil {
return err
}
dstPath := filepath.Join(dst, relPath)
if info.IsDir() {
return os.MkdirAll(dstPath, info.Mode())
}
srcFile, err := os.Open(path)
if err != nil {
return err
}
defer srcFile.Close()
dstFile, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, info.Mode())
if err != nil {
return err
}
defer dstFile.Close()
_, err = fmtCopy(dstFile, srcFile)
return err
})
}
func fmtCopy(dst *os.File, src *os.File) (int64, error) {
buf := make([]byte, 32*1024)
var written int64
for {
n, err := src.Read(buf)
if n > 0 {
wn, err := dst.Write(buf[:n])
if err != nil {
return written, err
}
written += int64(wn)
}
if err != nil {
if err == io.EOF {
return written, nil
}
return written, err
}
}
}
func copyEmbeddedToTarget(targetDir string) error {
// Ensure target directory exists
if err := os.MkdirAll(targetDir, 0755); err != nil {

View file

@ -86,28 +86,7 @@ func copyDirectory(src, dst string) error {
}
defer dstFile.Close()
_, err = fmtCopy(dstFile, srcFile)
_, err = io.Copy(dstFile, srcFile)
return err
})
}
func fmtCopy(dst *os.File, src *os.File) (int64, error) {
buf := make([]byte, 32*1024)
var written int64
for {
n, err := src.Read(buf)
if n > 0 {
wn, err := dst.Write(buf[:n])
if err != nil {
return written, err
}
written += int64(wn)
}
if err != nil {
if err == io.EOF {
return written, nil
}
return written, err
}
}
}

View file

@ -44,18 +44,11 @@ func listBuiltinImpl() {
skillFile := filepath.Join(builtinSkillsDir, skillName, "SKILL.md")
description := "No description"
if _, err := os.Stat(skillFile); err == nil {
data, err := os.ReadFile(skillFile)
if err == nil {
content := string(data)
if idx := strings.Index(content, "\n"); idx > 0 {
firstLine := content[:idx]
if strings.Contains(firstLine, "description:") {
descLine := strings.Index(content[idx:], "\n")
if descLine > 0 {
description = strings.TrimSpace(content[idx+descLine : idx+descLine])
}
}
if data, err := os.ReadFile(skillFile); err == nil {
for _, line := range strings.Split(string(data), "\n") {
if strings.HasPrefix(line, "description:") {
description = strings.TrimSpace(strings.TrimPrefix(line, "description:"))
break
}
}
}

View file

@ -12,6 +12,7 @@ import (
var RemoveCmd = &cobra.Command{
Use: "remove <name>",
Aliases: []string{"uninstall"},
Short: "Remove installed skill",
Long: `Remove an installed skill by name.`,
Args: cobra.ExactArgs(1),

View file

@ -4,8 +4,6 @@
package skillspkg
import (
"path/filepath"
"github.com/sipeed/picoclaw/pkg/skills"
)
@ -37,5 +35,5 @@ func getWorkspace() string {
}
func getBuiltinSkillsDir() string {
return filepath.Join(workspace, "../picoclaw/skills")
return builtinSkillsDir
}

View file

@ -17,9 +17,10 @@ var (
gitCommit string
buildTime string
goVersion string
logo = "🦞"
)
const logo = "🦞"
// formatVersion returns the version string with optional git commit
func formatVersion() string {
v := version