Docs
고급 기능
사용자 정의 명령

사용자 정의 명령

사용자 정의 명령을 사용하면 좋아하는 프롬프트나 자주 사용하는 프롬프트를 Gemini CLI 내의 개인 단축키로 저장하고 재사용할 수 있습니다. 단일 프로젝트에만 적용되는 명령이나 모든 프로젝트에서 전역적으로 사용할 수 있는 명령을 만들어 워크플로를 간소화하고 일관성을 보장할 수 있습니다.

파일 위치 및 우선 순위

Gemini CLI는 두 위치에서 명령을 검색하며, 특정 순서로 로드합니다:

  1. 사용자 명령 (전역): ~/.gemini/commands/에 위치합니다. 이 명령은 작업 중인 모든 프로젝트에서 사용할 수 있습니다.
  2. 프로젝트 명령 (로컬): <your-project-root>/.gemini/commands/에 위치합니다. 이 명령은 현재 프로젝트에만 적용되며 버전 관리에 체크인하여 팀과 공유할 수 있습니다.

프로젝트 디렉터리의 명령이 사용자 디렉터리의 명령과 동일한 이름을 갖는 경우, (로컬) 프로젝트 명령이 항상 사용됩니다. 이를 통해 프로젝트별 버전으로 전역 명령을 재정의할 수 있습니다.

이름 지정 및 네임스페이스

명령의 이름은 commands 디렉터리에 대한 상대 파일 경로에 의해 결정됩니다. 하위 디렉터리는 네임스페이스 명령을 만드는 데 사용되며, 경로 구분 기호(/ 또는 \)는 콜론(:)으로 변환됩니다.

  • ~/.gemini/commands/test.toml 파일은 /test 명령이 됩니다.
  • <project>/.gemini/commands/git/commit.toml 파일은 네임스페이스 명령 /git:commit이 됩니다.

TOML 파일 형식 (v1)

명령 정의 파일은 TOML 형식으로 작성해야 하며 .toml 파일 확장자를 사용해야 합니다.

필수 필드

  • prompt (문자열): 명령이 실행될 때 Gemini 모델로 전송될 프롬프트입니다. 한 줄 또는 여러 줄 문자열이 될 수 있습니다.

선택 필드

  • description (문자열): 명령이 수행하는 작업에 대한 간단한 한 줄 설명입니다. 이 텍스트는 /help 메뉴에서 명령 옆에 표시됩니다. 이 필드를 생략하면 파일 이름에서 일반적인 설명이 생성됩니다.

Handling arguments

Custom commands support two powerful methods for handling arguments. The CLI automatically chooses the correct method based on the content of your command's prompt.

1. Context-aware injection with {{args}}

If your prompt contains the special placeholder {{args}}, the CLI will replace that placeholder with the text the user typed after the command name.

The behavior of this injection depends on where it is used:

A. Raw injection (outside shell commands)

When used in the main body of the prompt, the arguments are injected exactly as the user typed them.

Example (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}}."

The model receives: Please provide a code fix for the issue described here: "Button is misaligned".

B. Using arguments in shell commands (inside !{...} blocks)

When you use {{args}} inside a shell injection block (!{...}), the arguments are automatically shell-escaped before replacement. This allows you to safely pass arguments to shell commands, ensuring the resulting command is syntactically correct and secure while preventing command injection vulnerabilities.

Example (/grep-code.toml):

prompt = """
Please summarize the findings for the pattern `{{args}}`.
 
Search Results:
!{grep -r {{args}} .}
"""

When you run /grep-code It's complicated:

  1. The CLI sees {{args}} used both outside and inside !{...}.
  2. Outside: The first {{args}} is replaced raw with It's complicated.
  3. Inside: The second {{args}} is replaced with the escaped version (e.g., on Linux: "It\'s complicated").
  4. The command executed is grep -r "It's complicated" ..
  5. The CLI prompts you to confirm this exact, secure command before execution.
  6. The final prompt is sent.

2. 기본 인수 처리

prompt에 특수 자리 표시자 {{args}}가 포함되어 있지 않은 경우, CLI는 인수 처리에 기본 동작을 사용합니다.

명령에 인수를 제공하는 경우(예: /mycommand arg1), CLI는 사용자가 입력한 전체 명령을 두 개의 줄 바꿈으로 구분하여 프롬프트 끝에 추가합니다. 이를 통해 모델은 원래 지침과 방금 제공한 특정 인수를 모두 볼 수 있습니다.

인수를 제공하지 않는 경우(예: /mycommand), 프롬프트는 아무것도 추가되지 않은 채 그대로 모델로 전송됩니다.

예시 (changelog.toml):

이 예시는 모델의 역할을 정의하고, 사용자 입력 위치를 설명하며, 예상되는 형식과 동작을 지정하여 강력한 명령을 만드는 방법을 보여줍니다.

# 위치: <project>/.gemini/commands/changelog.toml
# 호출 방법: /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 Format
The command follows this format: `/changelog <version> <type> <message>`
- `<type>` must be one of: "added", "changed", "fixed", "removed".
 
## Behavior
1. 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. !{...}를 사용한 셸 명령 실행

prompt 내에서 직접 셸 명령을 실행하고 그 출력을 주입하여 명령을 동적으로 만들 수 있습니다. 이는 파일 내용을 읽거나 Git 상태를 확인하는 등 로컬 환경에서 컨텍스트를 수집하는 데 이상적입니다.

사용자 정의 명령이 셸 명령 실행을 시도하면, Gemini CLI는 이제 진행하기 전에 사용자에게 확인을 요청합니다. 이는 의도한 명령만 실행되도록 보장하는 보안 조치입니다.

작동 방식:

  1. 명령 주입: !{...} 구문을 사용합니다.
  2. 인수 대체: 블록 내에 {{args}}가 있는 경우 자동으로 셸 이스케이프 처리됩니다 (위의 컨텍스트 인식 주입 참조).
  3. 견고한 파싱: 파서는 중첩된 중괄호(예: JSON 페이로드)가 포함된 복잡한 셸 명령을 올바르게 처리합니다. 참고: !{...} 내부의 내용은 균형 잡힌 중괄호({})를 가져야 합니다. 균형이 맞지 않는 중괄호가 포함된 명령을 실행해야 하는 경우, 외부 스크립트 파일로 래핑하고 !{...} 블록 내에서 해당 스크립트를 호출하는 것을 고려하세요.
  4. 보안 검사 및 확인: CLI는 최종적으로 해결된 명령(인수가 이스케이프 및 대체된 후)에 대해 보안 검사를 수행합니다. 실행될 정확한 명령을 보여주는 대화 상자가 나타납니다.
  5. 실행 및 오류 보고: 명령이 실행됩니다. 명령이 실패하면 프롬프트에 주입된 출력에는 오류 메시지(stderr)와 상태 줄(예: [Shell command exited with code 1])이 포함됩니다. 이는 모델이 실패의 맥락을 이해하는 데 도움이 됩니다.

예시 (git/commit.toml):

이 명령은 스테이징된 git diff를 가져와 모델에게 커밋 메시지 작성을 요청하는 데 사용합니다.

# 위치: <project>/.gemini/commands/git/commit.toml
# 호출 방법: /git:commit
 
description = "Generates a Git commit message based on staged changes."
 
# 프롬프트는 !{...}를 사용하여 명령을 실행하고 출력을 주입합니다.
prompt = """
Please generate a Conventional Commit message based on the following git diff:
 
```diff
!{git diff --staged}
```
 
"""
 

/git:commit을 실행하면, CLI는 먼저 git diff --staged를 실행한 다음, 최종 전체 프롬프트를 모델로 보내기 전에 !{git diff --staged}를 해당 명령의 출력으로 바꿉니다.

4. @{...}를 사용한 파일 내용 주입

@{...} 구문을 사용하여 파일이나 디렉터리 목록의 내용을 프롬프트에 직접 삽입할 수 있습니다. 이는 특정 파일에 작용하는 명령을 만드는 데 유용합니다.

작동 방식:

  • 파일 주입: @{path/to/file.txt}file.txt의 내용으로 대체됩니다.
  • 멀티모달 지원: 경로가 지원되는 이미지(예: PNG, JPEG), PDF, 오디오 또는 비디오 파일을 가리키는 경우, 올바르게 인코딩되어 멀티모달 입력으로 주입됩니다. 다른 바이너리 파일은 정상적으로 처리되고 건너뜁니다.
  • 디렉터리 목록: @{path/to/dir}은 순회하며 디렉터리 및 모든 하위 디렉터리에 있는 각 파일이 프롬프트에 삽입됩니다. 활성화된 경우 .gitignore.geminiignore를 준수합니다.
  • 작업 공간 인식: 명령은 현재 디렉터리와 다른 작업 공간 디렉터리에서 경로를 검색합니다. 작업 공간 내에 있는 경우 절대 경로가 허용됩니다.
  • 처리 순서: @{...}를 사용한 파일 내용 주입은 셸 명령(!{...}) 및 인수 대체({{args}}) 전에 처리됩니다.
  • 파싱: 파서는 @{...} 내부의 내용(경로)에 균형 잡힌 중괄호({})가 있어야 합니다.

예시 (review.toml):

이 명령은 고정된 모범 사례 파일(docs/best-practices.md)의 내용을 주입하고 사용자의 인수를 사용하여 리뷰를 위한 컨텍스트를 제공합니다.

# 위치: <project>/.gemini/commands/review.toml
# 호출 방법: /review FileCommandLoader.ts
 
description = "Reviews the provided context using a best practice guide."
prompt = """
You are an expert code reviewer.
 
Your task is to review {{args}}.
 
Use the following best practices when providing your review:
 
@{docs/best-practices.md}
"""

/review FileCommandLoader.ts를 실행하면, 최종 프롬프트가 모델로 전송되기 전에 @{docs/best-practices.md} 자리 표시자는 해당 파일의 내용으로 바뀌고, {{args}}는 사용자가 제공한 텍스트로 바뀝니다.


예시: "순수 함수" 리팩토링 명령

모델에게 코드 조각을 리팩토링하도록 요청하는 전역 명령을 만들어 보겠습니다.

1. 파일 및 디렉터리 생성:

먼저 사용자 명령 디렉터리가 존재하는지 확인한 다음, 구성을 위한 refactor 하위 디렉터리와 최종 TOML 파일을 만듭니다.

mkdir -p ~/.gemini/commands/refactor
touch ~/.gemini/commands/refactor/pure.toml

2. 파일에 내용 추가:

편집기에서 ~/.gemini/commands/refactor/pure.toml을 열고 다음 내용을 추가합니다. 모범 사례를 위해 선택 사항인 description을 포함하고 있습니다.

# 위치: ~/.gemini/commands/refactor/pure.toml
# 이 명령은 다음과 같이 호출됩니다: /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:pure

그러면 Gemini CLI가 TOML 파일에 정의된 여러 줄 프롬프트를 실행합니다.