create-cli

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Create 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
undefined
Agent无法回答提示信息。所有输入必须能通过标志参数传递。
bash
undefined

Bad: 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` flag
mycli deploy --env staging

- 将确认操作通过`--yes`或`--force`标志控制
- 若缺少必填输入,立即返回可执行的错误信息——不要等待输入
- 若需支持人类交互式操作,通过`--interactive`标志开启

2. Layered discovery

2. 分层式探索

Agents discover incrementally:
mycli
mycli deploy --help
. Don't dump all docs upfront.
  • Each subcommand has its own
    --help
  • Every
    --help
    includes Examples (agents pattern-match faster than reading prose)
  • 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 --force
Agent会逐步探索功能:
mycli
mycli deploy --help
。不要一次性展示全部文档。
  • 每个子命令都有独立的
    --help
    帮助信息
  • 所有
    --help
    内容需包含示例(Agent通过匹配模式学习的速度快于阅读文字)
  • 在输出中适时推荐后续可用命令
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 --force

3. JSON input for complex data

3. 复杂数据使用JSON输入

Prefer
--json
for structured input—agents generate it directly with zero translation loss.
bash
undefined
优先使用
--json
传递结构化输入——Agent可直接生成JSON,避免信息丢失。
bash
undefined

Accept 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
    --json
    for structured output; human-readable text as default
  • 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
    -q/--quiet
    when useful; keep success output brief but informative
  • 提供
    --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:
ThreatExampleDefense
Path traversal
../../.ssh
Canonicalize and sandbox to CWD
Control charactersInvisible chars below ASCII 0x20Reject them
Embedded query params
fileId?fields=name
Reject
?
and
#
in IDs
Pre-encoded URLs
%2e%2e
for
..
Reject
%
in resource IDs
"The agent is not a trusted operator. Build like it."
Agent不会像人类那样打错字——它们会产生幻觉。需进行防御性验证:
风险示例防御措施
路径遍历
../../.ssh
规范化路径并限制在当前工作目录(CWD)内
控制字符ASCII 0x20以下的不可见字符拒绝此类输入
嵌入查询参数
fileId?fields=name
拒绝ID中包含
?
#
的情况
预编码URL
%2e%2e
表示
..
拒绝资源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-op
No 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
    list
    somewhere, use
    list
    everywhere (not
    show
    or
    get
    )
  • Avoid ambiguous pairs (
    update
    vs
    upgrade
    ,
    remove
    vs
    delete
    ) unless sharply differentiated
  • 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
  • 避免模糊的动词对(如
    update
    vs
    upgrade
    remove
    vs
    delete
    ),除非两者有明确的差异
  • 在所有子命令中共享全局标志、配置和帮助体系
若需构建管理多种资源类型的复杂CLI(如Docker、kubectl),请参考references/multi-resource-clis.md

8. Destructive actions

8. 破坏性操作

Preview before committing. Require explicit confirmation flags.
bash
undefined
执行前先预览。需通过明确的确认标志触发。
bash
undefined

Preview 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 tags
Don'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
undefined

Good: 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

当遇到可恢复的错误(缺失文件、缺失目录、缓存过期)时,自动修复并继续执行。仅当无合理恢复路径时才返回失败。

**记录魔法数值**。若存在常量,请说明原因:

```bash

Good: 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
undefined
Agent习惯使用管道操作。需支持标准输入及命令链式调用。
bash
undefined

Pipe 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
:
  1. Command name + purpose: What's the CLI called and what does it do?
  2. Input sources: Args only, or also stdin/files? Any secrets? (remind: never via flags—use stdin or
    --password-file
    )
  3. Output needs: Does output need to be piped? (if yes, add
    --json
    )
  4. Subcommands: Single command or multiple subcommands?
  5. Complexity check: Does it need external SDKs/packages? (if yes, ask Python or TypeScript)
Proceed with sensible defaults for unanswered questions.
若上下文未明确需求,请使用
AskUserQuestion
询问以下问题:
  1. 命令名称及用途:CLI的名称是什么?主要功能是什么?
  2. 输入来源:仅支持参数,还是同时支持标准输入/文件?是否涉及敏感信息?(提醒:绝不要通过标志传递敏感信息——请使用标准输入或
    --password-file
  3. 输出需求:输出是否需要支持管道传递?(若是,添加
    --json
    参数)
  4. 子命令:是单命令还是多子命令结构?
  5. 复杂度检查:是否需要外部SDK/包?(若是,询问使用Python还是TypeScript)
对于未回答的问题,使用合理的默认值推进开发。

Default Conventions

默认约定

  • -h/--help
    always shows help and ignores other args
  • --version
    prints version to stdout
  • Primary data to stdout; diagnostics/errors to stderr
  • --json
    for machine output; consider
    --plain
    for stable line-based text
  • Support
    -
    for stdin/stdout when input/output is a file
  • Respect
    NO_COLOR
    ,
    TERM=dumb
    ; provide
    --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:
  1. Primary use case works - Run the main workflow the CLI was built for. Verify output matches expectations.
  2. Help is useful - Check that
    --help
    shows usage, flags, and examples. Subcommands should have their own help.
  3. 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.
  4. Exit codes are correct - Success returns 0. Invalid usage returns non-zero. Check a few failure cases.
  5. JSON output parses (if
    --json
    supported) - Pipe output through
    jq
    or equivalent to verify it's valid JSON with expected fields.
  6. Errors go to stderr - Redirect stdout to
    /dev/null
    and trigger an error. The error message should still appear (via stderr).
If applicable:
  1. Input validation - If the CLI accepts paths, IDs, or user-provided strings, test that malformed inputs (traversal paths, control chars, embedded params) are rejected.
  2. Idempotency - For state-changing commands, run the same command twice. Second run should be safe (no-op or "already exists").
  3. Dry-run works - If
    --dry-run
    is supported, verify it shows what would happen without making changes.
Fix any failures before considering the CLI complete.
实现完成后,在提交前测试CLI。不要仅检查是否能运行——需验证其在Agent场景下的行为是否符合预期。
必测项:
  1. 主用例正常运行 - 运行CLI的核心工作流,验证输出符合预期。
  2. 帮助信息实用 - 检查
    --help
    是否显示用法、标志及示例。子命令需有独立的帮助信息。
  3. 非交互式验证 - 传递空输入或在无TTY环境下运行。CLI不得因等待提示而挂起。缺少必填参数时需快速返回可执行的错误信息。
  4. 退出码正确 - 成功执行返回0。无效用法返回非零值。检查若干失败场景。
  5. JSON输出可解析(若支持
    --json
    ) - 将输出通过
    jq
    或类似工具验证,确保是包含预期字段的有效JSON。
  6. 错误信息输出到标准错误 - 将标准输出重定向到
    /dev/null
    并触发错误,错误信息应仍能显示(通过标准错误输出)。
可选测试项(若适用):
  1. 输入验证 - 若CLI接受路径、ID或用户提供的字符串,测试畸形输入(遍历路径、控制字符、嵌入参数)是否被拒绝。
  2. 幂等性验证 - 对于状态变更命令,连续运行两次。第二次运行应确保安全(无操作或提示“已存在”)。
  3. 试运行功能正常 - 若支持
    --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

参考资料

  • references/cli-guidelines.md
    - Extended philosophy, edge cases (man pages, distribution, analytics), full rationale behind the core principles
  • references/context-window-discipline.md
    - Field masks, NDJSON streaming, output limiting for CLIs that return large results
  • references/auth-for-agents.md
    - Env vars for tokens, service accounts, headless auth patterns
  • references/response-sanitization.md
    - Protecting against prompt injection in API responses
  • references/multi-resource-clis.md
    - Noun-verb pattern for complex CLIs managing multiple resource types (like Docker, kubectl)
  • references/cli-guidelines.md
    - 扩展理念、边缘场景(手册页、分发、分析)、核心原则的完整依据
  • references/context-window-discipline.md
    - 字段掩码、NDJSON流、针对返回大量结果的CLI的输出限制
  • references/auth-for-agents.md
    - 用于令牌、服务账号、无头认证模式的环境变量
  • references/response-sanitization.md
    - 防止API响应中的提示注入
  • references/multi-resource-clis.md
    - 管理多种资源类型的复杂CLI所使用的名词-动词模式(如Docker、kubectl)