From 8b5f3430a1be69cc070574784f58d7635df79c2f Mon Sep 17 00:00:00 2001 From: cole Date: Sun, 15 Feb 2026 19:21:27 +0800 Subject: [PATCH] chore: update go-resty to v2.17.2 and clean up docs/plans --- ...26-02-15-macos-launchd-autostart-design.md | 52 ---- ...-macos-launchd-autostart-implementation.md | 252 ------------------ go.mod | 2 +- go.sum | 4 +- 4 files changed, 3 insertions(+), 307 deletions(-) delete mode 100644 docs/plans/2026-02-15-macos-launchd-autostart-design.md delete mode 100644 docs/plans/2026-02-15-macos-launchd-autostart-implementation.md diff --git a/docs/plans/2026-02-15-macos-launchd-autostart-design.md b/docs/plans/2026-02-15-macos-launchd-autostart-design.md deleted file mode 100644 index 8c9b6383b..000000000 --- a/docs/plans/2026-02-15-macos-launchd-autostart-design.md +++ /dev/null @@ -1,52 +0,0 @@ -# macOS 开机启动 (launchd) 设计方案 - -## 概述 - -添加 `picoclaw install` 命令,自动生成 macOS launchd 的 plist 配置文件并安装到 `~/Library/LaunchAgents/`,实现开机自动启动 `picoclaw gateway`。 - -## 详细设计 - -### 1. plist 文件内容 - -```xml - - - - - Label - io.picoclaw.gateway - ProgramArguments - - /usr/local/bin/picoclaw - gateway - - RunAtLoad - - KeepAlive - - - -``` - -### 2. 命令设计 - -| 命令 | 描述 | -|------|------| -| `picoclaw install` | 安装 launchd plist(当前用户) | -| `picoclaw install --uninstall` | 卸载 launchd plist | -| `picoclaw install --status` | 查看安装状态 | - -### 3. 实现位置 - -在 `cmd/picoclaw/main.go` 中添加 `install` case。 - -### 4. 可执行文件路径 - -- 优先使用 `which picoclaw` 查找已安装路径 -- 如果找不到,提示用户需要先 `go install` 或手动复制 - -## 实现步骤 - -1. 在 main.go 添加 install case -2. 实现 installCmd() 函数 -3. 添加 uninstall 和 status 子命令 diff --git a/docs/plans/2026-02-15-macos-launchd-autostart-implementation.md b/docs/plans/2026-02-15-macos-launchd-autostart-implementation.md deleted file mode 100644 index e9d329fce..000000000 --- a/docs/plans/2026-02-15-macos-launchd-autostart-implementation.md +++ /dev/null @@ -1,252 +0,0 @@ -# macOS 开机启动 (launchd) 实现计划 - -> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. - -**Goal:** 在 picoclaw 项目中添加 `picoclaw install` 命令,实现 macOS 开机自动启动 `picoclaw gateway` - -**Architecture:** 通过生成 launchd plist 配置文件到 `~/Library/LaunchAgents/` 目录,实现用户级开机自启动 - -**Tech Stack:** Go, macOS launchd - ---- - -## 实现步骤 - -### Task 1: 添加 install case 到 main.go - -**Files:** -- Modify: `cmd/picoclaw/main.go:126-145` - -**Step 1: 在 main.go 的 switch 语句中添加 install case** - -在 `case "cron":` 之前添加: - -```go -case "install": - installCmd() -``` - -**Step 2: 运行测试验证** - -Run: `go build ./cmd/picoclaw/` -Expected: 编译成功(因为 installCmd 尚未定义,会有警告) - ---- - -### Task 2: 实现 installCmd 函数 - -**Files:** -- Modify: `cmd/picoclaw/main.go:199-216` - -**Step 1: 添加 installCmd 函数和帮助信息** - -在 `printHelp()` 函数后添加: - -```go -func installCmd() { - args := os.Args[2:] - for _, arg := range args { - switch arg { - case "--uninstall": - uninstallInstall() - return - case "--status": - statusInstall() - return - case "--help", "-h": - installHelp() - return - } - } - doInstall() -} - -func installHelp() { - fmt.Println("\nInstall commands:") - fmt.Println(" picoclaw install Install launchd plist (current user)") - fmt.Println(" picoclaw install --uninstall Uninstall launchd plist") - fmt.Println(" picoclaw install --status Show install status") -} - -func doInstall() { - // 查找 picoclaw 可执行文件路径 - execPath, err := findExecutable() - if err != nil { - fmt.Printf("Error: %v\n", err) - os.Exit(1) - } - - // 生成 plist 内容 - plistContent := generatePlist(execPath) - - // 写入文件 - plistPath := filepath.Join(os.Getenv("HOME"), "Library", "LaunchAgents", "io.picoclaw.gateway.plist") - if err := os.WriteFile(plistPath, []byte(plistContent), 0644); err != nil { - fmt.Printf("Error writing plist: %v\n", err) - os.Exit(1) - } - - fmt.Printf("✓ Installed launchd plist to %s\n", plistPath) - fmt.Println("Run 'picoclaw install --status' to check status") -} - -func findExecutable() (string, error) { - // 使用 which 查找 - cmd := exec.Command("which", "picoclaw") - out, err := cmd.Output() - if err == nil { - return strings.TrimSpace(string(out)), nil - } - - // 尝试常见路径 - commonPaths := []string{ - "/usr/local/bin/picoclaw", - "/usr/bin/picoclaw", - filepath.Join(os.Getenv("HOME"), "go", "bin", "picoclaw"), - } - - for _, p := range commonPaths { - if _, err := os.Stat(p); err == nil { - return p, nil - } - } - - return "", fmt.Errorf("picoclaw not found in PATH. Please run 'go install' first or ensure picoclaw is in your PATH") -} - -func generatePlist(execPath string) string { - return ` - - - - Label - io.picoclaw.gateway - ProgramArguments - - ` + execPath + ` - gateway - - RunAtLoad - - KeepAlive - - - -` -} - -func uninstallInstall() { - plistPath := filepath.Join(os.Getenv("HOME"), "Library", "LaunchAgents", "io.picoclaw.gateway.plist") - if _, err := os.Stat(plistPath); os.IsNotExist(err) { - fmt.Println("No launchd plist found.") - return - } - - // 先 unload - exec.Command("launchctl", "unload", plistPath).Run() - - if err := os.Remove(plistPath); err != nil { - fmt.Printf("Error removing plist: %v\n", err) - os.Exit(1) - } - - fmt.Printf("✓ Removed %s\n", plistPath) -} - -func statusInstall() { - plistPath := filepath.Join(os.Getenv("HOME"), "Library", "LaunchAgents", "io.picoclaw.gateway.plist") - - if _, err := os.Stat(plistPath); os.IsNotExist(err) { - fmt.Println("Status: Not installed") - fmt.Println("Run 'picoclaw install' to install") - return - } - - fmt.Println("Status: Installed") - fmt.Printf("Path: %s\n", plistPath) - - // 检查是否正在运行 - cmd := exec.Command("launchctl", "list", "io.picoclaw.gateway") - out, err := cmd.Output() - if err == nil { - fmt.Println("\nRunning: Yes") - fmt.Println(string(out)) - } else { - fmt.Println("\nRunning: No") - } -} -``` - -**Step 2: 添加 import** - -确保已导入 `os/exec`: - -```go -import ( - // ... 其他 import - "os/exec" -) -``` - -**Step 3: 运行测试验证** - -Run: `go build ./cmd/picoclaw/` -Expected: 编译成功 - -**Step 4: 手动测试** - -```bash -./picoclaw install --help -./picoclaw install --status -``` - ---- - -### Task 3: 更新帮助信息 - -**Files:** -- Modify: `cmd/picoclaw/main.go:201-215` - -**Step 1: 在 printHelp 中添加 install 命令** - -在 Commands 列表中添加: - -```go -fmt.Println(" install Install/uninstall launchd service (macOS)") -``` - ---- - -### Task 4: 测试完整流程 - -**Step 1: 构建并测试安装** - -```bash -go build -o picoclaw ./cmd/picoclaw/ -./picoclaw install -./picoclaw install --status -``` - -Expected: 成功创建 plist 文件 - -**Step 2: 测试卸载** - -```bash -./picoclaw install --uninstall -./picoclaw install --status -``` - -Expected: 成功删除 plist 文件 - ---- - -### Task 5: 提交代码 - -```bash -git add cmd/picoclaw/main.go -git commit -m "feat: add macOS launchd autostart support - -- Add 'picoclaw install' command -- Support install, uninstall, and status options -- Auto-detect picoclaw executable path" -``` diff --git a/go.mod b/go.mod index c321ec7b9..8b7b75bbd 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( github.com/bytedance/sonic/loader v0.5.0 // indirect github.com/cloudwego/base64x v0.1.6 // indirect github.com/github/copilot-sdk/go v0.1.23 - github.com/go-resty/resty/v2 v2.17.1 // indirect + github.com/go-resty/resty/v2 v2.17.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/google/jsonschema-go v0.4.2 // indirect github.com/grbit/go-json v0.11.0 // indirect diff --git a/go.sum b/go.sum index 18da86f62..84a94df31 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,8 @@ github.com/github/copilot-sdk/go v0.1.23 h1:uExtO/inZQndCZMiSAA1hvXINiz9tqo/MZgQ github.com/github/copilot-sdk/go v0.1.23/go.mod h1:GdwwBfMbm9AABLEM3x5IZKw4ZfwCYxZ1BgyytmZenQ0= github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w= github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q= -github.com/go-resty/resty/v2 v2.17.1 h1:x3aMpHK1YM9e4va/TMDRlusDDoZiQ+ViDu/WpA6xTM4= -github.com/go-resty/resty/v2 v2.17.1/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA= +github.com/go-resty/resty/v2 v2.17.2 h1:FQW5oHYcIlkCNrMD2lloGScxcHJ0gkjshV3qcQAyHQk= +github.com/go-resty/resty/v2 v2.17.2/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=