← ClaudeAtlas

ai-first-clilisted

This skill should be used when designing, building, or reviewing a command-line tool that AI agents will call, not just humans. Use it when deciding output format (JSON vs text), error handling, exit codes, flags, discoverability, dependencies and packaging, or autonomous-operation safety for a CLI. Also use it when asked how to make an existing CLI agent-friendly, or to evaluate a tool against the agent-first design philosophy. Grounded in Vercel's cloud-for-agents methodology.
yzfly/ai-first-cli · ★ 0 · AI & Automation · score 67
Install: claude install-skill yzfly/ai-first-cli
# AI-First CLI 设计哲学 ## 核心命题 **CLI 的首要读者正在从人变成 agent。** 过去 CLI 为人优化(漂亮的表格、交互式提示、彩色输出、man page);agent-first 的 CLI 把这些当成"次要降级路径",把**机器可调用、可预测、可解析**当成主路径——同时不牺牲人的体验。 一句话判据:**一个 agent 读完命令的输出,应该确切知道下一步做什么——不用猜、不用幻觉命令、不用卡住。** 这不是给旧 CLI 加个 `--json` 就完事。是把"使用者会读报错、会手动调试、会读文档"这套人类假设**整个倒过来**重做接口。Vercel 把它推到极致:CLI 转零依赖自更新签名二进制、Sandbox 内跑 Docker、甚至造了 Zero 语言让编译器吐 JSON 诊断给 agent 修。详见 `references/vercel-case-study.md`。 ## 何时用本技能 - 设计 / 重写一个会被 AI agent 调用的 CLI - 评审一个 CLI 是否"agent 友好" - 纠结:要不要做 MCP server,还是把 CLI 做好就够了 - 决定输出格式、错误结构、退出码、flag、打包方式 - 给现有工具加 agent 安全护栏(dry-run、输入校验、幂等) 不适用:纯人机交互的本地工具(如个人 dotfiles 脚本),或决策已被 lint/schema 机械约束的场景。 ## 十二条原则(速查) | # | 原则 | 一句话 | |---|------|--------| | 1 | 机器输出是默认,不是选项 | `--json` 结构化信封;TTY 给人看,管道给机器 | | 2 | stdout/stderr 分流 | 数据走 stdout,诊断/日志/错误走 stderr,管道才干净 | | 3 | 接收原始 payload | 允许直接传与 API schema 同构的 JSON,LLM 零翻译损失 | | 4 | 错误要可执行 | 退出码 + 稳定错误码 + message + 修复命令 + 重试提示 | | 5 | 自描述、可发现 | `--help`、schema introspection、`explain CODE`,CLI 是"此刻 API 接受什么"的唯一真相源 | | 6 | 默认非交互 | 每个提示都有 flag 绕过;env var 认证,无浏览器登录 | | 7 | 零依赖、自包含 | 单一签名二进制,快启动、可信、沙箱里无依赖链惊喜 | | 8 | 可组合(Unix) | 可 pipe、读 stdin、NDJSON 流式分页 | | 9 | 自治护栏 | `--dry-run`、幂等键、输入加固、响应净化防注入 | | 10 | 省 token | 字段裁剪、分页、简洁输出,别撑爆上下文窗口 | | 11 | 确定性优先 | 稳定输出契约 + 版本化 schema,agent 要可预测胜过聪明 | | 12 | 一核多面 | CLI / MCP / SDK / env var 共享同一核心能力 | ## 原则展开(关键的几条) **1 + 2 双形态输出。** 检测 TTY:交互终端给人类友好输出,非 TTY(被管道/agent 调用)默认结构化。或显式 `--json`。结构化信封要稳定:`{ "ok": bool, "data": ..., "error": ... }`。数据只走 stdout,这样 `cmd