From 258a216e543c00196f26c50ded435c5195bd2c0a Mon Sep 17 00:00:00 2001 From: chengkebin Date: Sat, 6 Jun 2026 16:34:04 +0800 Subject: [PATCH 01/13] =?UTF-8?q?feat(go):=20Phase=200+1=20=E2=80=94=20Go?= =?UTF-8?q?=20=E9=87=8D=E5=86=99=E5=9C=B0=E5=9F=BA=E4=B8=8E=E6=A0=B8?= =?UTF-8?q?=E5=BF=83=20CLI=EF=BC=8Cnpm=20=E5=88=86=E5=8F=91=20Go=20?= =?UTF-8?q?=E4=BA=8C=E8=BF=9B=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 0:Go 骨架 + npm 分发管道 - cobra root(--version/--help/NoArgs),ldflags 注入版本 - npm launcher(require.resolve 平台子包二进制并 spawn 透传 exit code) - scripts/build-go.sh:交叉编译 5 平台(darwin/linux x64+arm64、win32 x64) → dist-native/ 原始二进制 + dist-npm/ 主包(optionalDependencies)+平台子包(os/cpu) - scripts/gen-pkg.mjs 生成各包 package.json Phase 1:地基层 + 核心命令(端到端验证) - errs/fsutil/paths/config:错误码、原子写、目录布局、schema (json.Unmarshal 覆盖默认值复现 deepMerge;点号路径 get/set/unset/coerce/mask) - keychain/creds:security|secret-tool shell-out;env/file/keychain/inline 引用; api-key 分层解析 + multi-key + gateway token(忠实移植 store.ts) - notif:通知查询匹配 + app 中英文别名 + date-key 收集(读侧) - output/clictx/prompt/daemon(lock 读侧):json|pretty|table|ndjson 输出对齐 JS - cli:handler wrapper + 全局 flags + config/profile/auth/notification/doctor 与现有 TS 实现同仓共存,不影响现有 npm 发布线(并行重写策略)。 Co-Authored-By: Claude Opus 4.8 --- .gitignore | 5 + cmd/yc/main.go | 11 + go.mod | 10 + go.sum | 10 + internal/cli/cmd_auth.go | 218 ++++++++++++++ internal/cli/cmd_config.go | 216 ++++++++++++++ internal/cli/cmd_doctor.go | 128 +++++++++ internal/cli/cmd_notification.go | 327 +++++++++++++++++++++ internal/cli/cmd_profile.go | 120 ++++++++ internal/cli/handler.go | 76 +++++ internal/cli/root.go | 46 +++ internal/clictx/clictx.go | 50 ++++ internal/config/config.go | 180 ++++++++++++ internal/config/dotpath.go | 182 ++++++++++++ internal/creds/refs.go | 140 +++++++++ internal/creds/store.go | 478 +++++++++++++++++++++++++++++++ internal/daemon/lock.go | 46 +++ internal/daemon/proc_unix.go | 20 ++ internal/daemon/proc_windows.go | 15 + internal/errs/errors.go | 80 ++++++ internal/fsutil/fsutil.go | 95 ++++++ internal/keychain/keychain.go | 84 ++++++ internal/notif/query.go | 303 ++++++++++++++++++++ internal/notif/types.go | 41 +++ internal/output/output.go | 201 +++++++++++++ internal/paths/paths.go | 109 +++++++ internal/prompt/prompt.go | 79 +++++ internal/version/version.go | 11 + npm/cli/README.md | 23 ++ npm/cli/bin/yc.js | 43 +++ scripts/build-go.sh | 82 ++++++ scripts/gen-pkg.mjs | 52 ++++ 32 files changed, 3481 insertions(+) create mode 100644 cmd/yc/main.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 internal/cli/cmd_auth.go create mode 100644 internal/cli/cmd_config.go create mode 100644 internal/cli/cmd_doctor.go create mode 100644 internal/cli/cmd_notification.go create mode 100644 internal/cli/cmd_profile.go create mode 100644 internal/cli/handler.go create mode 100644 internal/cli/root.go create mode 100644 internal/clictx/clictx.go create mode 100644 internal/config/config.go create mode 100644 internal/config/dotpath.go create mode 100644 internal/creds/refs.go create mode 100644 internal/creds/store.go create mode 100644 internal/daemon/lock.go create mode 100644 internal/daemon/proc_unix.go create mode 100644 internal/daemon/proc_windows.go create mode 100644 internal/errs/errors.go create mode 100644 internal/fsutil/fsutil.go create mode 100644 internal/keychain/keychain.go create mode 100644 internal/notif/query.go create mode 100644 internal/notif/types.go create mode 100644 internal/output/output.go create mode 100644 internal/paths/paths.go create mode 100644 internal/prompt/prompt.go create mode 100644 internal/version/version.go create mode 100644 npm/cli/README.md create mode 100644 npm/cli/bin/yc.js create mode 100755 scripts/build-go.sh create mode 100644 scripts/gen-pkg.mjs diff --git a/.gitignore b/.gitignore index 03577fc..a2e7544 100644 --- a/.gitignore +++ b/.gitignore @@ -4,9 +4,14 @@ node_modules # 构建产物 dist dist-native +dist-npm *.tgz *.tsbuildinfo +# Go(本地散落的二进制;go vendor 用 /vendor 顶层,勿用裸 vendor 误伤 src/vendor) +/yc +/vendor/ + # 环境变量与密钥 .env .env.local diff --git a/cmd/yc/main.go b/cmd/yc/main.go new file mode 100644 index 0000000..e51d654 --- /dev/null +++ b/cmd/yc/main.go @@ -0,0 +1,11 @@ +// Command yc 是 yoooclaw CLI 的 Go 实现入口。 +// +// 真实命令树与业务实现在 internal/cli 下逐步补齐(见 Go 重写计划 Phase 1+); +// 本文件只负责装配 root 命令并执行。 +package main + +import "github.com/YoooClaw/cli/internal/cli" + +func main() { + cli.Execute() +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..f950f13 --- /dev/null +++ b/go.mod @@ -0,0 +1,10 @@ +module github.com/YoooClaw/cli + +go 1.26.4 + +require github.com/spf13/cobra v1.10.2 + +require ( + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/spf13/pflag v1.0.9 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..a6ee3e0 --- /dev/null +++ b/go.sum @@ -0,0 +1,10 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= +github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/cli/cmd_auth.go b/internal/cli/cmd_auth.go new file mode 100644 index 0000000..8e4880a --- /dev/null +++ b/internal/cli/cmd_auth.go @@ -0,0 +1,218 @@ +package cli + +import ( + "strconv" + "strings" + + "github.com/YoooClaw/cli/internal/clictx" + "github.com/YoooClaw/cli/internal/config" + "github.com/YoooClaw/cli/internal/creds" + "github.com/YoooClaw/cli/internal/daemon" + "github.com/YoooClaw/cli/internal/errs" + "github.com/YoooClaw/cli/internal/prompt" + "github.com/spf13/cobra" +) + +func newAuthCmd() *cobra.Command { + c := &cobra.Command{Use: "auth", Short: "凭据与鉴权 🟢/🟡"} + + setKey := &cobra.Command{Use: "set-api-key ", Short: "设置/轮换 account 级 default api-key(- 从 stdin 读)🟢", Args: cobra.ExactArgs(1), RunE: run(authSetAPIKey)} + setKey.Flags().Bool("keychain", false, "写入 OS keychain 而非文件") + + addKey := &cobra.Command{Use: "add-api-key ", Short: "新增一条 multi-key api-key(- 从 stdin 读)🟢", Args: cobra.ExactArgs(1), RunE: run(authAddAPIKey)} + addKey.Flags().String("label", "", "api-key label([a-z0-9-]{1,32})") + addKey.Flags().Bool("default", false, "设为 default key") + addKey.Flags().Bool("force", false, "label 已存在时覆盖") + + listKeys := &cobra.Command{Use: "list-api-keys", Short: "列出 api-key 条目(key 自动遮罩)🟢", Args: cobra.NoArgs, RunE: run(authListAPIKeys)} + rmKey := &cobra.Command{Use: "remove-api-key