create-cli
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCreate CLI
构建CLI
Build CLIs for AI agents. Assume 100% agent usage.
为AI Agent构建命令行界面(CLI)。假设100%面向Agent使用场景。
Default Assumptions
默认假设
- Language: Shell script (bash) by default. Use Python (uv + typer) or TypeScript (bun + commander) only when:
- SDK works better in that language
- Requires specific packages (e.g., data analysis → Python)
- User explicitly requests it
- Non-interactive: Agents cannot respond to prompts—commands just hang
- Parseable output: JSON for machine consumption; human-readable as fallback
- 开发语言:默认使用Shell脚本(bash)。仅在以下情况使用Python(uv + typer)或TypeScript(bun + commander):
- SDK在对应语言中表现更优
- 需要特定包(例如:数据分析场景→Python)
- 用户明确要求
- 非交互式:Agent无法响应提示——命令若等待输入会直接挂起
- 可解析输出:优先使用JSON格式供机器读取;人类可读格式作为备选
Core Principles
核心原则
1. Non-interactive first
1. 优先支持非交互式
Agents cannot answer prompts. Every input must be expressible as a flag.
bash
undefinedAgent无法回答提示信息。所有输入必须能通过标志参数传递。
bash
undefinedBad: hangs the agent
错误示例:会导致Agent挂起
mycli deploy
? Which environment? (use arrow keys)
mycli deploy
? Which environment? (use arrow keys)
Good: works
正确示例:可正常运行
mycli deploy --env staging
- Gate confirmations behind `--yes` or `--force` flags
- If required input is missing, fail immediately with an actionable error—don't prompt
- For optional human interactivity, gate behind `--interactive` flagmycli deploy --env staging
- 将确认操作通过`--yes`或`--force`标志控制
- 若缺少必填输入,立即返回可执行的错误信息——不要等待输入
- 若需支持人类交互式操作,通过`--interactive`标志开启2. Layered discovery
2. 分层式探索
Agents discover incrementally: → . Don't dump all docs upfront.
myclimycli deploy --help- Each subcommand has its own
--help - Every includes Examples (agents pattern-match faster than reading prose)
--help - Suggest next commands in output when helpful
text
Options:
--env Target environment (staging, production)
--tag Image tag (default: latest)
--force Skip confirmation
Examples:
mycli deploy --env staging
mycli deploy --env production --tag v1.2.3
mycli deploy --env staging --forceAgent会逐步探索功能: → 。不要一次性展示全部文档。
myclimycli deploy --help- 每个子命令都有独立的帮助信息
--help - 所有内容需包含示例(Agent通过匹配模式学习的速度快于阅读文字)
--help - 在输出中适时推荐后续可用命令
text
Options:
--env Target environment (staging, production)
--tag Image tag (default: latest)
--force Skip confirmation
Examples:
mycli deploy --env staging
mycli deploy --env production --tag v1.2.3
mycli deploy --env staging --force3. JSON input for complex data
3. 复杂数据使用JSON输入
Prefer for structured input—agents generate it directly with zero translation loss.
--jsonbash
undefined优先使用传递结构化输入——Agent可直接生成JSON,避免信息丢失。
--jsonbash
undefinedAccept full JSON payload
接受完整JSON负载
mycli create --json '{"title": "Doc", "locale": "en_US", "gridProperties": {"frozenRowCount": 1}}'
mycli create --json '{"title": "Doc", "locale": "en_US", "gridProperties": {"frozenRowCount": 1}}'
Also accept JSON from stdin
也支持从标准输入读取JSON
cat config.json | mycli create --stdin
JSON maps directly to API schemas. No need to flatten nested structures into flags.cat config.json | mycli create --stdin
JSON可直接映射到API schema,无需将嵌套结构拆解为标志参数。4. Parseable output
4. 可解析输出
- Provide for structured output; human-readable text as default
--json - On success, return machine-useful data: IDs, URLs, durations, state changes
text
deployed v1.2.3 to staging
url: https://staging.myapp.com
deploy_id: dep_abc123
duration: 34s- Add when useful; keep success output brief but informative
-q/--quiet
- 提供参数输出结构化内容;默认输出人类可读文本
--json - 成功执行时返回机器可用数据:ID、URL、耗时、状态变更信息
text
deployed v1.2.3 to staging
url: https://staging.myapp.com
deploy_id: dep_abc123
duration: 34s- 必要时添加参数;成功输出需简洁且包含关键信息
-q/--quiet
5. Input hardening against hallucinations
5. 针对幻觉问题强化输入验证
Agents don't typo like humans—they hallucinate. Validate defensively:
| Threat | Example | Defense |
|---|---|---|
| Path traversal | | Canonicalize and sandbox to CWD |
| Control characters | Invisible chars below ASCII 0x20 | Reject them |
| Embedded query params | | Reject |
| Pre-encoded URLs | | Reject |
"The agent is not a trusted operator. Build like it."
Agent不会像人类那样打错字——它们会产生幻觉。需进行防御性验证:
| 风险 | 示例 | 防御措施 |
|---|---|---|
| 路径遍历 | | 规范化路径并限制在当前工作目录(CWD)内 |
| 控制字符 | ASCII 0x20以下的不可见字符 | 拒绝此类输入 |
| 嵌入查询参数 | | 拒绝ID中包含 |
| 预编码URL | 用 | 拒绝资源ID中包含 |
"不要信任Agent的操作权限,需按非可信操作者的标准构建CLI。"
6. Idempotency
6. 幂等性
Agents retry constantly. The same successful command run twice should be safe:
bash
$ mycli deploy --env staging --tag v1.2.3
✓ Deployed v1.2.3 to staging
$ mycli deploy --env staging --tag v1.2.3
✓ Already deployed, no-opNo duplicate side effects. Design for crash-only recovery when feasible.
Agent会持续重试命令。成功执行过的命令再次运行应确保安全:
bash
$ mycli deploy --env staging --tag v1.2.3
✓ Deployed v1.2.3 to staging
$ mycli deploy --env staging --tag v1.2.3
✓ Already deployed, no-op避免重复产生副作用。尽可能设计为支持崩溃后恢复的模式。
7. Predictable structure
7. 可预测的结构
Be consistent across subcommands:
- Reuse verbs: if you have somewhere, use
listeverywhere (notlistorshow)get - Avoid ambiguous pairs (vs
update,upgradevsremove) unless sharply differentiateddelete - Share global flags/config/help across subcommands
For complex CLIs managing multiple resource types (like Docker, kubectl), see references/multi-resource-clis.md.
在所有子命令中保持一致性:
- 复用动词:若在某处使用了,则所有场景都使用
list(不要混用list或show)get - 避免模糊的动词对(如vs
update、upgradevsremove),除非两者有明确的差异delete - 在所有子命令中共享全局标志、配置和帮助体系
若需构建管理多种资源类型的复杂CLI(如Docker、kubectl),请参考references/multi-resource-clis.md。
8. Destructive actions
8. 破坏性操作
Preview before committing. Require explicit confirmation flags.
bash
undefined执行前先预览。需通过明确的确认标志触发。
bash
undefinedPreview what would happen
预览执行效果
$ mycli delete --env production --dry-run
Would delete 3 instances in production
- instance-a
- instance-b
- instance-c No changes made.
$ mycli delete --env production --dry-run
Would delete 3 instances in production
- instance-a
- instance-b
- instance-c No changes made.
Execute with confirmation
确认后执行
$ mycli delete --env production --force
✓ Deleted 3 instances
- `--dry-run` validates without executing
- `--force` or `--yes` bypasses confirmation (required for destructive ops)$ mycli delete --env production --force
✓ Deleted 3 instances
- `--dry-run`参数仅验证操作可行性,不执行实际变更
- 破坏性操作需通过`--force`或`--yes`参数跳过确认(必填)9. Schema introspection (for API-backed CLIs)
9. Schema自省(针对基于API的CLI)
Let agents self-serve without static docs baked into prompts:
bash
$ mycli schema drive.files.list
{
"params": {"fields": "string", "pageSize": "integer"},
"scopes": ["drive.readonly"],
...
}The CLI becomes the canonical source of truth for what the API accepts right now.
让Agent无需依赖提示中的静态文档即可自助获取信息:
bash
$ mycli schema drive.files.list
{
"params": {"fields": "string", "pageSize": "integer"},
"scopes": ["drive.readonly"],
...
}CLI将成为当前API接受参数的权威来源。
10. Fail fast with actionable errors
10. 快速失败并返回可执行的错误信息
On missing required flags, exit immediately with a clear message and correct invocation:
text
Error: No image tag specified.
mycli deploy --env staging --tag <image-tag>
Available tags: mycli build list --output tagsDon't hang. Give agents something to self-correct with.
若缺少必填标志,立即退出并返回清晰的错误信息及正确的调用示例:
text
Error: No image tag specified.
mycli deploy --env staging --tag <image-tag>
Available tags: mycli build list --output tags不要挂起进程。为Agent提供可用于自我修正的信息。
11. Solve, don't punt
11. 主动解决问题,而非直接报错
Handle recoverable errors in the CLI rather than failing and forcing the agent to figure it out.
bash
undefined在CLI中处理可恢复的错误,而非直接失败并让Agent自行排查。
bash
undefinedGood: CLI handles the missing file
正确示例:CLI自动处理缺失文件
$ mycli process data.json
File data.json not found, creating with defaults...
✓ Created data.json
$ mycli process data.json
File data.json not found, creating with defaults...
✓ Created data.json
Bad: CLI fails, agent must diagnose and retry
错误示例:CLI直接失败,Agent需自行诊断并重试
$ mycli process data.json
Error: No such file or directory: data.json
When errors are recoverable (missing files, missing directories, stale cache), fix them and continue. Only fail when there's no reasonable recovery path.
**Document magic numbers.** If a constant exists, explain why:
```bash$ mycli process data.json
Error: No such file or directory: data.json
当遇到可恢复的错误(缺失文件、缺失目录、缓存过期)时,自动修复并继续执行。仅当无合理恢复路径时才返回失败。
**记录魔法数值**。若存在常量,请说明原因:
```bashGood: self-documenting
正确示例:自带文档说明
TIMEOUT=30 # HTTP requests typically complete within 30s
RETRIES=3 # Most intermittent failures resolve by second retry
TIMEOUT=30 # HTTP请求通常会在30秒内完成
RETRIES=3 # 大多数间歇性故障会在第二次重试后解决
Bad: voodoo constants
错误示例:无意义的常量
TIMEOUT=47 # Why 47?
RETRIES=5 # Why 5?
If you don't know the right value, the agent won't either.TIMEOUT=47 # 为什么是47?
RETRIES=5 # 为什么是5?
如果你不确定合理数值,Agent也无法知晓。12. Stdin and pipelines
12. 标准输入与管道支持
Agents think in pipelines. Accept stdin and support chaining.
bash
undefinedAgent习惯使用管道操作。需支持标准输入及命令链式调用。
bash
undefinedPipe data between commands
在命令间传递数据
cat config.json | mycli validate --stdin
mycli list --json | mycli process --stdin
cat config.json | mycli validate --stdin
mycli list --json | mycli process --stdin
Chain with other tools
与其他工具链式调用
mycli export --json | jq '.items[]' | mycli import --stdin
- Accept `--stdin` or `-` for input where it makes sense
- Avoid odd positional ordering that breaks piping
- Output should be pipeable (clean stdout, errors to stderr)mycli export --json | jq '.items[]' | mycli import --stdin
- 在合理场景下支持`--stdin`或`-`参数读取输入
- 避免破坏管道操作的奇怪参数顺序
- 输出需支持管道传递(纯净的标准输出,错误信息输出到标准错误)Interview (only if not already done)
需求确认(仅当未完成时)
If requirements aren't already clear from context, ask these questions using :
AskUserQuestion- Command name + purpose: What's the CLI called and what does it do?
- Input sources: Args only, or also stdin/files? Any secrets? (remind: never via flags—use stdin or )
--password-file - Output needs: Does output need to be piped? (if yes, add )
--json - Subcommands: Single command or multiple subcommands?
- Complexity check: Does it need external SDKs/packages? (if yes, ask Python or TypeScript)
Proceed with sensible defaults for unanswered questions.
若上下文未明确需求,请使用询问以下问题:
AskUserQuestion- 命令名称及用途:CLI的名称是什么?主要功能是什么?
- 输入来源:仅支持参数,还是同时支持标准输入/文件?是否涉及敏感信息?(提醒:绝不要通过标志传递敏感信息——请使用标准输入或)
--password-file - 输出需求:输出是否需要支持管道传递?(若是,添加参数)
--json - 子命令:是单命令还是多子命令结构?
- 复杂度检查:是否需要外部SDK/包?(若是,询问使用Python还是TypeScript)
对于未回答的问题,使用合理的默认值推进开发。
Default Conventions
默认约定
- always shows help and ignores other args
-h/--help - prints version to stdout
--version - Primary data to stdout; diagnostics/errors to stderr
- for machine output; consider
--jsonfor stable line-based text--plain - Support for stdin/stdout when input/output is a file
- - Respect ,
NO_COLOR; provideTERM=dumb--no-color - Handle Ctrl-C: exit fast, bounded cleanup, crash-only when possible
- 始终显示帮助信息并忽略其他参数
-h/--help - 将版本信息输出到标准输出
--version - 核心数据输出到标准输出;诊断/错误信息输出到标准错误
- 用于机器可读输出;可考虑
--json参数输出稳定的行文本格式--plain - 当输入/输出为文件时,支持表示标准输入/输出
- - 尊重、
NO_COLOR环境变量;提供TERM=dumb参数--no-color - 处理Ctrl-C:快速退出,有限清理,尽可能支持崩溃后恢复
Testing the CLI
CLI测试
After implementation, test the CLI before reporting done. Don't just check that it runs—verify it behaves correctly for agents.
Required tests:
-
Primary use case works - Run the main workflow the CLI was built for. Verify output matches expectations.
-
Help is useful - Check thatshows usage, flags, and examples. Subcommands should have their own help.
--help -
Non-interactive - Pipe empty input or run without a TTY. The CLI must not hang waiting for prompts. Missing required args should fail fast with an actionable error.
-
Exit codes are correct - Success returns 0. Invalid usage returns non-zero. Check a few failure cases.
-
JSON output parses (ifsupported) - Pipe output through
--jsonor equivalent to verify it's valid JSON with expected fields.jq -
Errors go to stderr - Redirect stdout toand trigger an error. The error message should still appear (via stderr).
/dev/null
If applicable:
-
Input validation - If the CLI accepts paths, IDs, or user-provided strings, test that malformed inputs (traversal paths, control chars, embedded params) are rejected.
-
Idempotency - For state-changing commands, run the same command twice. Second run should be safe (no-op or "already exists").
-
Dry-run works - Ifis supported, verify it shows what would happen without making changes.
--dry-run
Fix any failures before considering the CLI complete.
实现完成后,在提交前测试CLI。不要仅检查是否能运行——需验证其在Agent场景下的行为是否符合预期。
必测项:
-
主用例正常运行 - 运行CLI的核心工作流,验证输出符合预期。
-
帮助信息实用 - 检查是否显示用法、标志及示例。子命令需有独立的帮助信息。
--help -
非交互式验证 - 传递空输入或在无TTY环境下运行。CLI不得因等待提示而挂起。缺少必填参数时需快速返回可执行的错误信息。
-
退出码正确 - 成功执行返回0。无效用法返回非零值。检查若干失败场景。
-
JSON输出可解析(若支持) - 将输出通过
--json或类似工具验证,确保是包含预期字段的有效JSON。jq -
错误信息输出到标准错误 - 将标准输出重定向到并触发错误,错误信息应仍能显示(通过标准错误输出)。
/dev/null
可选测试项(若适用):
-
输入验证 - 若CLI接受路径、ID或用户提供的字符串,测试畸形输入(遍历路径、控制字符、嵌入参数)是否被拒绝。
-
幂等性验证 - 对于状态变更命令,连续运行两次。第二次运行应确保安全(无操作或提示“已存在”)。
-
试运行功能正常 - 若支持,验证其仅展示执行效果而不产生实际变更。
--dry-run
修复所有测试失败项后,再确认CLI开发完成。
Language Notes
语言说明
- Shell script (bash): Default. Prefer long options (--env, --force) over short (-e, -f).
- Python: uv + typer. Choose when SDK is Python or needs data processing.
- TypeScript: bun + commander. Choose when SDK is JS/TS.
- Shell脚本(bash):默认选择。优先使用长选项(--env, --force)而非短选项(-e, -f)。
- Python:使用uv + typer。当SDK为Python或需要数据处理时选择。
- TypeScript:使用bun + commander。当SDK为JS/TS时选择。
References
参考资料
- - Extended philosophy, edge cases (man pages, distribution, analytics), full rationale behind the core principles
references/cli-guidelines.md - - Field masks, NDJSON streaming, output limiting for CLIs that return large results
references/context-window-discipline.md - - Env vars for tokens, service accounts, headless auth patterns
references/auth-for-agents.md - - Protecting against prompt injection in API responses
references/response-sanitization.md - - Noun-verb pattern for complex CLIs managing multiple resource types (like Docker, kubectl)
references/multi-resource-clis.md
- - 扩展理念、边缘场景(手册页、分发、分析)、核心原则的完整依据
references/cli-guidelines.md - - 字段掩码、NDJSON流、针对返回大量结果的CLI的输出限制
references/context-window-discipline.md - - 用于令牌、服务账号、无头认证模式的环境变量
references/auth-for-agents.md - - 防止API响应中的提示注入
references/response-sanitization.md - - 管理多种资源类型的复杂CLI所使用的名词-动词模式(如Docker、kubectl)
references/multi-resource-clis.md