gill is a CLI between your code and an LLM. It provides low-level control and ergonomics for sending prompts with your code to OpenAI's API.
- Flexible Prompt Building: Compose and send prompts with messages (
-m), whole files (-f) or line ranges within files (-l) using interleaved and stacked arguments:
gill -m "What does this function do?" -f src/main.py -l 14-23 45- -m "Explain line by line."- Test mode: Learn what prompts your commands make without sending to the API with a
--testflag:
gill --test -m "Please explain the bug in these lines." -f foo.py -l 33-86 -m "This, too:" -f bar.py -l 15-20Output:
Please explain the bug in these lines.
```foo.py, lines 33-86
# Code from foo.py lines 33-86...
```
This, too:
```bar.py, lines 15-20
# Code from bar.py lines 15-20...
```
- Save System Prompt: Initialize gill at the project directory and edit the system prompt used in API calls:
gill init
nano $(gill sysprompt)- Project-Level Configs: Change the system prompt and the current OpenAI model used by the API:
gill config listOutput:
[llm]
model = "gpt-4.1-mini"
[chats]
head = "7ea...827.chat"
Change the model used:
gill config set llm.model gpt-4.1Clear the chat with:
gill chat clearTo use this tool, you need an OpenAI API key saved in the environment:
export OPENAI_API_KEY="sk-...your_key_here..."
echo $OPENAI_API_KEYOn Windows Powershell:
$env:OPENAI_API_KEY = "sk-...your_key_here..."The official package, gillmore, is available on PyPI.
Use pipx for a global CLI install without interfering with system Python:
pipx install gillmore
pipx ensurepath # Ensures the gill command is in the path
gill --test -m "Hello world!" # You may need to restart your shell for the command to workOrder is preserved.
gill ([-m|--message <text> ...]) [-f|--file <filename> ...] [-l|--line <range> ...] ...Use --test flag to print the prompt created, rather than sending to API:
gill --test [-m|--message <text> ...] [-f|--file <filename> ...] [-l|--line <range> ...] ...-
Flags are stored until another is given, so arguments can always be stacked after a flag.
-
Files are stored until another is given and
-lapplies to the most recent file given. This gives the flexibility to insert messages in between lines without losing reference to file. -
IMPORTANT: If a line of a file is never inserted before a new file, or before the end of the prompt, then the whole file is inserted at the position the file was given.
Line ranges for -l flags are always inclusive and can be specified in various ways:
- Single line:
-l 8 - Finite Inclusive Range:
-l 12-15or any of-l 12--15,-l 12,15,-l 12.15,-l 12..15 - From beginning or till end: start of file till line 12 with
-l -12or line 12 till end of file with-l 12-. Or the other delimiters--,,,.,.. - Multiple
-lflags/args can stack for multiple excerpts from one file.
As in the git CLI, initialize a gill project with gill init or gill init [<directory>].
Access the file path to the system prompt used in API calls with gill sysprompt. Then read with cat $(gill sysprompt) or edit with your choice of editor, e.g. nano $(gill sysprompt).
Chat is automatically created with gill init and tracked as you use. Clear the chat with a simple gill chat clear. Sending a new prompt will then use the updated gill sysprompt contents.
Configurations may be changed with gill config set <section.key> value, currently the only valid <section.key> is llm.model (and model.head which should not be manually changed.) Print all configs with gill config list or a single value with gill config <section.key>.
Therefore, change the OpenAI model used by the API with gill config set llm.model gpt-4.1, or any other OpenAI model value.
gill -m "What's the capital of Australia?"gill -m "Explain this script line-by-line: " -f myscript.pygill -m "What does this function do?" -f ./src/main.cpp -l 120-145gill -m "Compare these two:" -f file1.py -l 2-10 -f file2.py -l 3-8gill -m "A bug is happening in these segments." -f bug.py -l 14-23 45- -m "Here's the log:" -f error.log -l 2gill --test -m "Explain this function." -f my.py -l 22-40Relevant file or line excerpts are embedded as Markdown fenced code blocks with filenames and line info for clarity. Messages are inserted as plain text sections, separated by new lines.
gill --test -m "Please explain the bug in these lines." -f foo.py -l 33-86 -m "This, too:" -f bar.py -l 15-20Output:
Please explain the bug in these lines.
```foo.py, lines 33-86
# foo.py lines 33-86...
```
This, too:
```bar.py, lines 15-20
# bar.py lines...
```
Planned features, ordered by priority:
- Tests
- More chat commands
- Insert scraped webpage contents by URL
- Completions
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
While you are free to release derivative works under any compatible license, we strongly encourage using permissive licenses such as Apache 2.0 or MIT, and avoiding copyleft licenses like GPL if possible, to maximize compatibility and adoption.