backward compat fixes
Signed-off-by: Kai Xia <kaix+github@fastmail.com>
This commit is contained in:
parent
2b9b7720e3
commit
7ba0330fd7
11 changed files with 45 additions and 124 deletions
|
|
@ -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
10
cmd/picoclaw/auth/auth.go
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
// PicoClaw - Ultra-lightweight personal AI agent
|
||||
// License: MIT
|
||||
|
||||
package auth
|
||||
|
||||
var configPath string
|
||||
|
||||
func SetConfigPath(path string) {
|
||||
configPath = path
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue