news 2026/10/15 20:32:13

为什么你的 CLI 需要一份规范?深入理解 Usage——CLI 界的 OpenAPI 完全解读

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
为什么你的 CLI 需要一份规范?深入理解 Usage——CLI 界的 OpenAPI 完全解读

【免费下载链接】usage

A specification for CLIs

项目地址:https://gitcode.com/gh_mirrors/usage/usage
点击查看免费下载

写 CLI 的人大多有过这种烦恼:帮助信息写在代码里,补全脚本另写一份,文档手工维护,三者经常对不上。Usage 就是为此而生的CLI 规范(CLI specification):你用一份 KDL 文件描述命令、标志(flags)、参数和帮助文本,然后由它统一生成 shell 补全、--help输出、Markdown 参考文档、man page,甚至 TypeScript / Python 类型化 SDK。一句话概括:Define your CLI once. Generate the tools around it.

一、问题:CLI 的"接口契约"散落各处

回想一下 HTTP 服务的世界:OpenAPI 让接口文档、客户端、Mock 都来自同一份定义。而 CLI 呢?

  • 帮助文本 → 散落在代码字符串里
  • 补全脚本 → 手写,或者用框架自动生成但无法自定义
  • 文档站 → 复制粘贴,版本漂移
  • 调用方的代码 → 没有类型信息,全靠猜

结果是同一份接口信息被维护了 N 份,而且没有任何工具能检查"这次改动是不是 breaking change"。

Usage 的思路和 OpenAPI 完全一致:先把 CLI 的接口写成一份规范,其余产物全部从规范派生。🎯

二、什么是 Usage?三个身份,一份规范

Usage 同时是三样东西(详见 README.md):

身份说明
📄一份可移植的 KDL 规范*.usage.kdl文件,描述命令树、标志、参数、配置、补全
🛠️一条命令行工具usage,负责 lint、生成补全/文档/manpage/SDK、检查接口 diff
⚙️一个 Rust 框架usage-rs,从 struct 派生类型化解析器,并导出可移植规范

规范语言选的是KDL——"读起来像配置文件,嵌套起来像 XML"。语法非常直觉,看这个最小示例(取自 docs/spec/index.md):

bin "mycli" about "Process project files" flag "-f --force" help="Overwrite existing output" flag "-v --version" help="Print the CLI version" arg "<dir>" help="The directory to use" // 尖括号 = 必填 arg "[file]" help="The file to read" // 方括号 = 可选

<file>表示必填位置参数,[file]表示可选,key=value属性补充元数据——十行就能把一个小工具的接口讲清楚。

三、核心能力:一份规范能生成什么?

1. 解析、帮助与 shell 补全

规范描述的就是接口语义:哪个标志全局(global=#true)、哪个取值有枚举(choices)、子命令如何嵌套。lib/src/complete/ 下实现了 bash、zsh、fish、PowerShell、Nu 五种 shell 的补全逻辑,全部从同一份规范派生,天然保持一致。

2. 文档与 man page 一键生成

usage generate markdown --file mycli.usage.kdl --out-file reference.md usage generate manpage --file mycli.usage.kdl --out-file mycli.1

参考实现见 cli/src/cli/generate/markdown.rs 与 cli/src/cli/generate/manpage.rs。接口变了?重新生成即可,文档漂移问题从根上消失。

3. 类型化 SDK:给"调用你 CLI 的代码"用

如果别的产品要通过子进程调用你的 CLI,Usage 可以生成TypeScript / Python SDK(见 lib/src/sdk/),调用方拿到的是类型化客户端而不是拼字符串——这正是 OpenAPI 生态里"代码生成客户端"在 CLI 世界的对应物。

4. 配置解析与优先级规则

规范可以声明 flag 由配置文件、环境变量或默认值回退支撑,优先级恒定为CLI flag > 环境变量 > 配置文件 > 默认值,实现位于 config/src/resolve.rs。相关规则详见 docs/spec/resolution.md。

5. 命令"效果"声明:为 AI Agent 时代做准备

比较有前瞻性的是effect字段,声明一条命令会对外部世界做什么:

effect含义
read只读检查,幂等
write创建/修改状态
destructive可能删除或不可逆覆盖,值得二次确认

AI 编码助手拿到这份规范后,可以直接获得一份"只读命令白名单",而不用每次都问用户。相关测试见 conformance/tests/effect.rs。

6. 接口 diff:CLI 版的 breaking change 检查

usage diff可以比较两版规范,在发布前发现移除标志、改名参数这类破坏性变更(实现见 cli/src/cli/diff.rs)。这对维护多版本 CLI 的团队非常实用。

四、四条接入路径:总有一条适合你

docs/index.md 把用户分成了四类,每类都有明确入口:

  1. 新建 Rust CLI:struct +#[usage(...)]派生,代码即规范(docs/rust/quickstart.md)
  2. 已有 CLI:从 clap、Cobra、kong、urfave 等框架导出规范,应用代码一行不改(docs/spec/integrations.md,Cobra 转换实现见 integrations/cobra/convert.go)
  3. Shell 脚本:在注释里声明参数,Usage 帮你解析并注入环境变量(docs/cli/scripts.md)
  4. 纯规范工作流:手写 KDL,用 CLI 生成一切产物(docs/guide/getting-started.md)

项目还内置了外部工具实测:benches/external/ 目录里有fd、starship、tokei的真实规范与"损失清单"(losses),诚实展示哪些接口特性规范能覆盖、哪些还差一点——这种透明度很少见。

五、快速上手:5 分钟体验完整闭环

# 安装(三选一) brew install usage # 或 mise use -g usage cargo install usage-cli --locked # 假设已写好 mycli.usage.kdl usage lint mycli.usage.kdl # 校验规范 usage generate completion zsh mycli --file mycli.usage.kdl --install # 装补全 usage generate markdown --file mycli.usage.kdl --out-file reference.md

规范语法与完整示例在 docs/spec/index.md,各节点(cmd、flag、arg、config、complete……)的字段级参考在 docs/spec/reference/。想看真实世界的规范长什么样,仓库自带了不少:examples/kitchen-sink.usage.kdl、examples/with-examples.usage.kdl,以及从 mise 等复杂工具导出的 benches/mise.usage.kdl。

六、为什么值得认真对待?

  • ✅单一事实源:帮助、补全、文档、SDK 永远同步
  • ✅生态互通:KDL 规范与语言/框架无关,Rust、Go(预览版,见 go/argv/)、脚本都能消费它
  • ✅可验证:lint抓错误,diff抓破坏性变更
  • ✅面向 AI 协作:effect声明让 Agent 安全地自动执行命令
  • ✅测试严谨:conformance/tests/ 下有上百个一致性测试,corpus/ 提供结构化用例集

如果你的 CLI 正在被用户、脚本、Agent 从多个入口调用,一份规范不再是"锦上添花",而是接口工程的基本盘——就像每个严肃的 API 都该有一份 OpenAPI 一样。

下一步建议:从你最头疼的那个 CLI 开始,试着手写一份 20 行的usage.kdl,运行一次usage lint和usage generate markdown,你就会明白这份规范的价值。🚀

【免费下载链接】usage

A specification for CLIs

项目地址:https://gitcode.com/gh_mirrors/usage/usage
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 20:31:48

双目立体匹配核心:区域匹配算法原理与工程实践

双目立体匹配这个话题&#xff0c;我在实际项目里断断续续折腾了好几年。如果让我给刚接触三维视觉的人推荐一个最值得先吃透的算法&#xff0c;我大概率会推荐区域匹配&#xff08;Area-based Matching&#xff09;——它是局部匹配算法里最直观、最容易编码、也是整条计算链路…

作者头像 李华
网站建设 2026/10/15 20:29:24

Rust RFC 0879 解读:二进制与八进制数字字面量的词法分析重构

文档 【免费下载链接】rfcs RFCs for changes to Rust 项目地址&#xff1a; https://gitcode.com/gh_mirrors/rf/rfcs 点击查看 免费下载 导读 本文围绕 RFC 仓库中的 text/0879-small-base-lexing.md&#xff08;RFC 879&#xff09;展开&#xff0c;深入讲解 Rust 编译器词…

作者头像 李华
网站建设 2026/10/15 20:25:22

JMeter 5.6.2压力测试实战:从线程组到报告解读

简介&#xff1a;Apache JMeter 5.6.2 是由 Apache 组织维护的开源纯 Java 压力测试工具&#xff0c;具备跨平台特性&#xff0c;可运行于 Windows、Linux、macOS。其用途在于模拟大量用户并发访问&#xff0c;评估 Web 应用、数据库、FTP 服务器等静态与动态资源的高并发稳定性…

作者头像 李华
网站建设 2026/10/15 20:23:36

Path of Building 完整指南:3 分钟规划好你的流放之路 Build

Path of Building 完整指南&#xff1a;3 分钟规划好你的流放之路 Build 【免费下载链接】PathOfBuilding Offline build planner for Path of Exile. 项目地址: https://gitcode.com/GitHub_Trending/pa/PathOfBuilding 还在凭感觉估算一件装备、一个天赋点到底带来多少…

作者头像 李华
网站建设 2026/10/15 20:22:41

Faster R-CNN源码解析:从RPN到RoI Head的PyTorch实现细节

最近重看了一遍 simple-faster-rcnn-pytorch 的源码&#xff0c;好几处当年囫囵吞枣跳过去的细节&#xff0c;这次总算想明白了。这个库可太适合拿来啃了——它没有把网络结构塞进一个几千行的 mega 文件里&#xff0c;RPN、RoI Head、Proposal 筛选这些都是单独模块&#xff0…

作者头像 李华