agentcli-go
Shared Go CLI helpers and framework modules.
Module: github.com/gh-xj/agentcli-go
Repo: github.com/gh-xj/agentcli-go | Versioning: v0.x.y (pre-1.0)
API Surface
| File | Exported Symbols |
|---|
| INLINECODE3 | INLINECODE4 — zerolog setup, respects -v/ INLINECODE6 |
| INLINECODE7 |
ParseArgs(args),
RequireArg(args, name),
GetArg(args, name),
HasFlag(args, name) |
|
exec.go |
RunCommand(name, args...),
RunOsascript(script),
Which(bin),
CheckDependency(bin) |
|
fs.go |
FileExists(path),
EnsureDir(path),
GetBaseName(path) |
|
core_context.go |
AppContext{Meta, Values},
NewAppContext(ctx) |
|
lifecycle.go |
Hook interface (
Preflight,
Postflight),
RunLifecycle(app, hook, run) |
|
errors.go |
CLIError,
ResolveExitCode(err),
ExitSuccess,
ExitUsage |
|
scaffold.go |
ScaffoldNew(baseDir, name, module),
ScaffoldAddCommand(rootDir, name, desc, preset),
Doctor(rootDir) DoctorReport |
|
cobrax/cobrax.go |
Execute(RootSpec, args) int,
NewRoot(RootSpec) *cobra.Command,
CommandSpec,
RootSpec |
|
configx/configx.go |
Load(Options) map[string]any,
Decode[T](raw),
NormalizeEnv(prefix, environ) |
Scaffold Workflows
New project
agentcli new --name my-tool --module github.com/me/my-tool
# or programmatically:
agentcli.ScaffoldNew(".", "my-tool", "github.com/me/my-tool")
Generates:
main.go,
cmd/root.go,
internal/app/,
internal/config/,
internal/io/,
internal/tools/smokecheck/,
pkg/version/,
test/,
Taskfile.yml, INLINECODE56
Add command
agentcli add command --name sync --preset file-sync
agentcli add command --name deploy --desc "run deploy checks"
Presets:
file-sync,
http-client, INLINECODE59
Doctor check
agentcli doctor [--dir ./my-tool]
# returns DoctorReport JSON with findings
Golden Project Layout
CODEBLOCK3
cobrax Pattern
CODEBLOCK4
Persistent flags auto-wired: --verbose/-v, --config, --json, --no-color
Values accessible via app.Values["json"], app.Values["config"], etc.
configx Pattern
CODEBLOCK5
Taskfile Tasks
| Task | Purpose |
|---|
| INLINECODE66 | Canonical CI: preflight + lint + test + build + smoke + schema checks |
| INLINECODE67 |
Local aggregate (wraps ci) |
|
task lint | go vet + golangci-lint |
|
task smoke | Deterministic smoke tests (subset of unit tests) |
|
task schema:check | Validate JSON contracts against schemas |
|
task docs:check | Ensure skill docs match CLI help signatures |
|
task fmt | Format all Go files |
Rules
- - Flat package — everything in
package agentcli, no sub-packages (except cobrax, configx) - Exported only — all functions PascalCase; this is a library
- No business logic — generic utilities only; must be reused across 2+ projects to qualify
log.Fatal allowed in RequireArg, CheckDependency (CLI-oriented helpers)- Minimal deps — zerolog, lo, cobra only; justify new additions
Out of Scope
- - Project-specific logic (put that in consuming projects)
- Adding functions used by only one project
agentcli-go
共享的Go CLI辅助工具和框架模块。
模块: github.com/gh-xj/agentcli-go
仓库: github.com/gh-xj/agentcli-go | 版本管理: v0.x.y(1.0前版本)
API 接口
| 文件 | 导出符号 |
|---|
| log.go | InitLogger() — zerolog配置,支持-v/--verbose |
| args.go |
ParseArgs(args)、RequireArg(args, name)、GetArg(args, name)、HasFlag(args, name) |
| exec.go | RunCommand(name, args...)、RunOsascript(script)、Which(bin)、CheckDependency(bin) |
| fs.go | FileExists(path)、EnsureDir(path)、GetBaseName(path) |
| core_context.go | AppContext{Meta, Values}、NewAppContext(ctx) |
| lifecycle.go | Hook接口(Preflight、Postflight)、RunLifecycle(app, hook, run) |
| errors.go | CLIError、ResolveExitCode(err)、ExitSuccess、ExitUsage |
| scaffold.go | ScaffoldNew(baseDir, name, module)、ScaffoldAddCommand(rootDir, name, desc, preset)、Doctor(rootDir) DoctorReport |
| cobrax/cobrax.go | Execute(RootSpec, args) int、NewRoot(RootSpec) *cobra.Command、CommandSpec、RootSpec |
| configx/configx.go | Load(Options) map[string]any、Decode
T、NormalizeEnv(prefix, environ) |
脚手架工作流
新建项目
bash
agentcli new --name my-tool --module github.com/me/my-tool
或以编程方式:
agentcli.ScaffoldNew(., my-tool, github.com/me/my-tool)
生成:main.go、cmd/root.go、internal/app/、internal/config/、internal/io/、internal/tools/smokecheck/、pkg/version/、test/、Taskfile.yml、README.md
添加命令
bash
agentcli add command --name sync --preset file-sync
agentcli add command --name deploy --desc 运行部署检查
预设:file-sync、http-client、deploy-helper
诊断检查
bash
agentcli doctor [--dir ./my-tool]
返回包含检查结果的DoctorReport JSON
黄金项目布局
my-tool/
├── main.go # os.Exit(cmd.Execute(os.Args[1:]))
├── cmd/
│ ├── root.go # cobrax.Execute(RootSpec{...})
│ └── .go # func Command() command
├── internal/
│ ├── app/{bootstrap,lifecycle,errors}.go
│ ├── config/{schema,load}.go
│ ├── io/output.go
│ └── tools/smokecheck/main.go
├── pkg/version/version.go
├── test/
│ ├── e2e/cli_test.go
│ └── smoke/version.schema.json
└── Taskfile.yml
cobrax 模式
go
// cmd/root.go
return cobrax.Execute(cobrax.RootSpec{
Use: my-tool,
Short: my-tool CLI,
Meta: agentcli.AppMeta{Name: my-tool, Version: version.Version},
Commands: []cobrax.CommandSpec{
{Use: sync, Short: 同步文件, Run: SyncCommand().Run},
},
}, args)
持久化标志自动绑定:--verbose/-v、--config、--json、--no-color
通过 app.Values[json]、app.Values[config] 等访问值。
configx 模式
go
raw, err := configx.Load(configx.Options{
Defaults: map[string]any{env: default},
FilePath: configPath, // 可选的JSON文件
Env: configx.NormalizeEnv(MYTOOL_, os.Environ()),
Flags: map[string]string{env: flagVal},
})
cfg, err := configx.Decodeconfig.Config
// 优先级:默认值 < 文件 < 环境变量 < 标志
Taskfile 任务
| 任务 | 用途 |
|---|
| task ci | 标准CI:预检 + 代码检查 + 测试 + 构建 + 冒烟测试 + 模式检查 |
| task verify |
本地聚合(封装ci) |
| task lint | go vet + golangci-lint |
| task smoke | 确定性冒烟测试(单元测试子集) |
| task schema:check | 验证JSON合约与模式匹配 |
| task docs:check | 确保技能文档与CLI帮助签名一致 |
| task fmt | 格式化所有Go文件 |
规则
- - 扁平包 — 所有内容在 package agentcli 中,无子包(cobrax、configx 除外)
- 仅导出 — 所有函数使用帕斯卡命名法;这是一个库
- 无业务逻辑 — 仅通用工具;必须在2个以上项目中复用才能纳入
- 允许 log.Fatal 在 RequireArg、CheckDependency 中使用(面向CLI的辅助函数)
- 最小依赖 — 仅zerolog、lo、cobra;新增依赖需说明理由
不包含范围
- - 项目特定逻辑(放在使用项目中)
- 添加仅被一个项目使用的函数