自定义命令
自定义命令允许你保存并重复使用你最喜欢或最常使用的提示词作为 Gemini CLI 中的个人快捷方式。你可以创建特定于单个项目的命令,也可以创建在所有项目中都可用的全局命令,以此简化你的工作流程并确保一致性。
文件位置和优先级
Section titled “文件位置和优先级”Gemini CLI 从两个位置发现命令,按特定顺序加载:
- 用户命令(全局): 位于
~/.gemini/commands/。这些命令在你工作的任何项目中都可用。 - 项目命令(本地): 位于
<your-project-root>/.gemini/commands/。这些命令特定于当前项目,并且可以检入版本控制,以便与你的团队共享。
如果项目目录中的命令与用户目录中的命令名称相同,则将始终使用项目命令。这允许项目用特定版本的命令覆盖全局命令。
命名和命名空间
Section titled “命名和命名空间”命令的名称由其相对于其 commands 目录的文件路径确定。子目录用于创建带命名空间的命令,路径分隔符(/ 或 \)会被转换为冒号(:)。
- 位于
~/.gemini/commands/test.toml的文件将成为命令/test。 - 位于
<project>/.gemini/commands/git/commit.toml的文件将成为命名空间命令/git:commit。
TOML 文件格式(v1)
Section titled “TOML 文件格式(v1)”你的命令定义文件必须采用 TOML 格式,并使用 .toml 文件扩展名。
prompt(字符串):当执行命令时将发送给 Gemini 模型的提示词。这可以是一行或多行字符串。
【译文】
description(字符串): 命令的简短一行描述。此文本将显示在/help菜单中,紧邻您的命令。如果您省略此字段,将从文件名生成一个通用描述。
自定义命令支持两种强大的处理参数的方法。CLI 会根据您的命令的 prompt 的内容自动选择正确的方法。
1. 带有 {{args}} 的上下文感知注入
Section titled “1. 带有 {{args}} 的上下文感知注入”如果您的 prompt 包含特殊的占位符 {{args}},CLI 将用用户在命令名后输入的文本替换该占位符。
这种行为取决于它被使用的地方:
A. 原始注入(在 shell 命令之外)
当在提示的主体内使用时,参数会按照用户输入的确切形式注入。
示例 (git/fix.toml):
# Invoked via: /git:fix "Button is misaligned"
description = "Generates a fix for a given issue."prompt = "Please provide a code fix for the issue described here: {{args}}."模型接收:
Please provide a code fix for the issue described here: "Button is misaligned".
B. 在 shell 命令中使用参数(在 !{...} 块内部)
当您在 shell 注入块内部使用 {{args}} (!{...}) 时,参数在替换之前会自动进行 shell 转义。这允许您安全地将参数传递给 shell 命令,确保生成的命令在语法上正确且安全,同时防止命令注入漏洞。
示例 (/grep-code.toml):
prompt = """Please summarize the findings for the pattern `{{args}}`.
Search Results:!{grep -r {{args}} .}"""当您运行 /grep-code It\'s complicated:
- CLI 发现
{{args}}在!{...}外部和内部都被使用。 - 外部:第一个
{{args}}以原始形式替换为It\'s complicated。 - 内部:第二个
{{args}}替换为转义版本(例如,在 Linux 上:"It\'s complicated")。 - 执行的命令是
grep -r "It\'s complicated" .。 - CLI 在执行前要求您确认这个确切且安全的命令。
- 最终提示发送。
2. 默认参数处理
Section titled “2. 默认参数处理”如果你的 prompt 不包含特殊的占位符 {{args}},CLI 会使用默认行为来处理参数。
如果你向命令提供参数(例如,/mycommand arg1),CLI 会将你输入的完整命令附加到提示符的末尾,并由两个换行符分隔。这允许模型同时看到原始指令和你刚刚提供的特定参数。
如果你不提供任何参数(例如,/mycommand),提示符将原样发送给模型,不附加任何内容。
示例 (changelog.toml):
这个示例展示了如何通过定义模型的角色、解释用户输入的位置以及指定预期的格式和行为来创建健壮的命令。
# In: <project>/.gemini/commands/changelog.toml# Invoked via: /changelog 1.2.0 added "Support for default argument parsing."
description = "Adds a new entry to the project\'s CHANGELOG.md file."prompt = """# Task: Update Changelog
You are an expert maintainer of this software project. A user has invoked a command to add a new entry to the changelog.
**The user\'s raw command is appended below your instructions.**
Your task is to parse the `<version>`, `<change_type>`, and `<message>` from their input and use the `write_file` tool to correctly update the `CHANGELOG.md` file.
## Expected FormatThe command follows this format: `/changelog <version> <type> <message>`- `<type>` must be one of: "added", "changed", "fixed", "removed".
## Behavior1. Read the `CHANGELOG.md` file.2. Find the section for the specified `<version>`.3. Add the `<message>` under the correct `<type>` heading.4. If the version or type section doesn\'t exist, create it.5. Adhere strictly to the "Keep a Changelog" format."""当你运行 /changelog 1.2.0 added "New feature" 时,最终发送给模型的文本将是原始提示符加上两个换行符以及你输入的命令。
3. 使用 !{...} 执行 Shell 命令
Section titled “3. 使用 !{...} 执行 Shell 命令”你可以通过直接在 prompt 中执行 Shell 命令并注入其输出来使你的命令动态化。这对于从本地环境收集上下文非常理想,比如读取文件内容或检查 Git 的状态。
当一个自定义命令尝试执行 Shell 命令时,Gemini CLI 现在会提示你确认是否继续。这是一项安全措施,以确保只有预期的命令能够运行。
工作原理:
注入命令: 使用 !{...} 语法。
参数替换: 如果在块中存在 {{args}},它将自动进行 shell 转义(请参阅上面的带参数的上下文感知注入)。
健壮解析: 解析器正确处理包含嵌套花括号的复杂 shell 命令,例如 JSON 负载。注意: !{...} 内部的内容必须具有平衡的花括号({ 和 })。如果你需要执行包含不平衡括号的命令,请考虑将其包裹在外部脚本文件中,并在 !{...} 块内调用该脚本。
安全检查与确认: CLI 对最终解析的命令(在参数转义和替换后)执行安全检查。将显示一个对话框,显示要执行的精确命令。
执行与错误报告: 执行命令。如果命令失败,注入到提示的输出将包括错误信息(stderr),然后是状态行,例如,[Shell command exited with code 1]。这有助于模型理解失败的上下文。
示例 (git/commit.toml):
此命令获取暂存的 git diff,并使用它来请求模型编写一个提交信息。
【翻译】
# In: <project>/.gemini/commands/git/commit.toml# Invoked via: /git:commit
description = "Generates a Git commit message based on staged changes."
# The prompt uses !{...} to execute the command and inject its output.prompt = """Please generate a Conventional Commit message based on the following git diff:
```diff!{git diff --staged}```
"""When you run /git:commit, the CLI first executes git diff --staged, then
replaces !{git diff --staged} with the output of that command before sending
the final, complete prompt to the model.
4. Injecting file content with @{...}
Section titled “4. Injecting file content with @{...}”You can directly embed the content of a file or a directory listing into your
prompt using the @{...} syntax. This is useful for creating commands that
operate on specific files.
How it works:
- File injection:
@{path/to/file.txt}is replaced by the content offile.txt. - Multimodal support: If the path points to a supported image (e.g., PNG, JPEG), PDF, audio, or video file, it will be correctly encoded and injected as multimodal input. Other binary files are handled gracefully and skipped.
- Directory listing:
@{path/to/dir}is traversed and each file present within the directory and all subdirectories is inserted into the prompt. This respects.gitignoreand.geminiignoreif enabled. - Workspace-aware: The command searches for the path in the current directory and any other workspace directories. Absolute paths are allowed if they are within the workspace.
- Processing order: File content injection with
@{...}is processed before shell commands (!{...}) and argument substitution ({{args}}). - Parsing: The parser requires the content inside
@{...}(the path) to have balanced braces ({and}).
Example (review.toml):
This command injects the content of a fixed best practices file
(docs/best-practices.md) and uses the user’s arguments to provide context for
the review.
CODE_BLOCK_5
When you run /review FileCommandLoader.ts, the @{docs/best-practices.md}
placeholder is replaced by the content of that file, and {{args}} is replaced
by the text you provided, before the final prompt is sent to the model.
Example: A “Pure Function” refactoring command
Section titled “Example: A “Pure Function” refactoring command”Let’s create a global command that asks the model to refactor a piece of code.
1. Create the file and directories:
First, ensure the user commands directory exists, then create a refactor
subdirectory for organization and the final TOML file.
CODE_BLOCK_6
2. Add the content to the file:
Open ~/.gemini/commands/refactor/pure.toml in your editor and add the
following content. We are including the optional description for best
practice.
# This command will be invoked via: /refactor:pure
description = "Asks the model to refactor the current context into a pure function."
prompt = """Please analyze the code I\'ve provided in the current context.Refactor it into a pure function.
Your response should include:1. The refactored, pure function code block.2. A brief explanation of the key changes you made and why they contribute to purity."""3. 运行命令:
就这样!你现在可以在 CLI 中运行你的命令了。首先,你可能需要向上下文中添加一个文件,然后调用你的命令:
> @my-messy-function.js> /refactor:pureGemini CLI 将会执行你在 TOML 文件中定义的多行提示。
【注意】:由于代码块(如```toml
Invoked via: /git:fix “Button is misaligned”
Section titled “Invoked via: /git:fix “Button is misaligned””description = “Generates a fix for a given issue.” prompt = “Please provide a code fix for the issue described here: {{args}}.”