mods panjie
winget install --id=panjie.mods -e AI on the command line
winget install --id=panjie.mods -e AI on the command line
> [!NOTE] > #### Actively Maintained Fork > > The original Mods was sunset by Charm on > March 9, 2026. This fork is actively maintained with new features and fixes.
<a href="https://github.com/panjie/mods/actions"><img src="https://github.com/panjie/mods/workflows/build/badge.svg" /></a>
An AI agent for your terminal. Mods doesn't just answer questions — it can read and edit your files, run shell commands, search the web, and iterate across many tool calls to actually finish a task. A built-in review step keeps you in charge of anything risky before it happens.
It works with OpenAI, Anthropic, Gemini, Azure OpenAI,
DeepSeek, GLM, Qwen, Kimi, MiniMax, OpenRouter, and local
Ollama models. Any OpenAI-compatible endpoint can be added in mods.yml.

--plan.--minimal prints one item per line — perfect for | gum choose and friends.--web-search uses a supported
provider's hosted search when available, otherwise Tavily or a custom backend.--image, --clipboard-image, or piped
stdin for any vision-capable model.brew install panjie/tap/mods
Or, with Go 1.25+:
go install github.com/panjie/mods@latest
Other ways to install
Build from source with Task:
git clone https://github.com/panjie/mods.git
cd mods
go run github.com/go-task/task/v3/cmd/task@v3.51.1 build # binary lands in bin/mods
go run github.com/go-task/task/v3/cmd/task@v3.51.1 install # installs to ~/.local/bin/mods (or $XDG_BIN_HOME)
The install task honors PREFIX, BINDIR, DESTDIR, and XDG_BIN_HOME.
On all platforms the default install path is $HOME/.local/bin/mods (mods.exe on Windows).
Prebuilt Windows portable ZIPs are published on the releases page. The latest nightly build is published as the nightly prerelease.
Generate shell completions:
mods completion bash > mods.bash
mods completion zsh > _mods
mods completion fish > mods.fish
mods completion powershell > mods.ps1
Run the interactive setup wizard to pick a provider, model, and API key:
mods --config
The wizard walks you through provider and model selection, API key entry,
built-in tools, and review mode — then saves everything to mods.yml
automatically.
The standard config path is $XDG_CONFIG_HOME/mods/mods.yml, or
$HOME/.config/mods/mods.yml when XDG_CONFIG_HOME is unset. If a mods.yml
file exists next to the executable, portable mode uses that file instead.
Sessions are stored in $XDG_DATA_HOME/mods/sessions, or
$HOME/.local/share/mods/sessions when XDG_DATA_HOME is unset.
On first real use, if mods.yml does not exist and there are no saved
sessions, Mods starts this setup wizard automatically. Help, version,
completion, directory, settings, config, list, show, delete, role listing, and
MCP listing commands do not trigger first-run setup.
Prefer to edit the raw YAML? Open it in your $EDITOR:
mods --settings
You can also recursively merge a YAML mapping into mods.yml directly from
the command line. Existing values at the same path are overwritten, while
unmentioned settings are preserved:
mods --settings 'default-api: openai'
mods --settings 'apis:
fujitsu-google:
api-type: google
base-url: https://abc.com
api-key-env: FUJITSU_GOOGLE_API_KEY
models:
gemini-3.0-pro: {}'
The --settings='' spelling is also supported. Avoid passing api-key
values directly because command arguments may be recorded in shell history or
visible to other local processes; prefer api-key-env.
Set a provider and model with the interactive wizard, or edit the YAML directly:
default-api: openai
default-model: gpt-5.4
apis:
openai:
api-key-env: OPENAI_API_KEY
models:
gpt-5.4: {}
export OPENAI_API_KEY=sk-...
# Summarize piped output
git log --oneline -20 | mods -f "group these commits by theme"
# Let Mods read and edit files in the current directory
mods --workspace . "read README.md and suggest three improvements"
# See a plan before any change is applied
mods --plan --workspace . "extract the CLI examples into a separate doc"
# Review uncommitted changes before pushing
git diff | mods -f "review this diff — flag bugs, security issues, and naming problems"
# Bring your vim config in line with current community best practices
mods --workspace "$HOME" --plan "modernize my .vimrc to the most popular 2026 setup, but preserve my keybindings"
# Migrate a codebase from one library to another
mods "replace all requests usage with httpx, keep behavior identical"
# Sweep the repo for stale patterns
mods "find every console.log and replace it with the structured logger"
# Diagnose why tests are failing
go test ./... 2>&1 | mods "explain each failure and suggest the likely fix"
# Make sense of a messy log tail
journalctl -u myapp --since "1h ago" | mods "what went wrong in the last hour?"
# Get up to speed on an unfamiliar codebase
mods "read internal/tools and explain how a tool call flows end-to-end"
# Draft a changelog from recent commits
git log v1.0.0..HEAD --oneline | mods "write a user-facing changelog grouped by theme"
# Add tests for the most important untested functions
mods "find Go functions without tests and add table-driven tests for the top 5"
# Collect every TODO into a prioritized report
mods "scan for TODO/FIXME comments and write prioritized TODO-report.md"
# Pick from a list using pipeline-friendly output
find . -maxdepth 1 -type f | sort | mods --minimal "pick the five most important files" | gum choose
# Ask the live web, then act on the answer
export TAVILY_API_KEY="tvly-..."
mods --web-search "what changed in the latest Go release? update go.mod if relevant"
# Force local Tavily/custom search even when the model offers hosted search
mods --web-search --web-search-backend local "find the latest Go release"
# Ask a vision-capable model about an image
mods --image assets/mods-product.png "suggest alt text for this image"
mods -I "describe the image on my clipboard"
# Save and resume sessions
mods "draft v1.1 release notes from CHANGELOG.md"
mods --continue-last "turn those into a Twitter thread"
mods --list-sessions
# Start a continuous session
mods --chat
mods --chat --continue-last
The session browser supports transcript search: open a session, press / to
find text, use n/N to move between matches, and press w to toggle wrapping
for code, logs, and tables.
Use --chat for a terminal-native conversation when one prompt is not enough.
The inline composer supports multi-line prompts: press Enter to send and
Ctrl+J to add a new line. Press Ctrl+C while composing to leave. Each turn
is saved to the same session so you can resume it later with --continue.
Mods asks for confirmation before any file write or shell command runs. You always see exactly what will execute, and you choose what happens next:
Review: Run: rm -f /path/to/workspace/demo.gif
[Y] Approve [N] Deny [A] Always allow [Ctrl+C] Cancel
Always allows writes in /path/to/workspace
Y — approve this one callN — deny; Mods gets the failure and can reactA — save a per-session rule for the current workspace so similar calls skip the prompt from now onCtrl+C — cancel the whole runPick the mode that fits the task with -V / --review-mode (or review-mode in
mods.yml, or the MODS_REVIEW_MODE env var). Use -N / --no-review as a
shortcut for --review-mode=never:
| Mode | Behavior |
|---|---|
auto | Default. Reviews file writes and shell commands flagged as risky. |
always | Reviews every tool call, including reads and searches. |
never | Disables review entirely. Use only for trusted, automated runs. |
Want a heads-up before any tool fires at all? --plan makes Mods draft a
step-by-step plan for your approval first, then executes once you accept.
mods --review-mode always "rename the fn to calculateTotal across the repo"
mods --plan "refactor the examples to cover more features"
Mods ships with native tools that auto-activate when your prompt needs them:
| Tool | What it does |
|---|---|
fs_read_file | Read UTF-8 files (with offset/limit for large files). |
fs_write_file | Create or overwrite files in the workspace. |
fs_replace | Replace exact text in an existing file. |
fs_search | Search file contents across the workspace. |
fs_apply_patch | Atomically apply unified or Codex-format multi-file edits. |
shell_run | Execute shell commands (prefix-allowable through review). |
Filesystem tools default to auto; shell is enabled by default. Toggle them in
mods.yml:
builtin-tools:
filesystem: auto # auto, true, or false
shell: true
shell-timeout: 30s
workspace: "" # defaults to the current working directory
Pass --workspace to scope filesystem and shell tools to a project workspace. The
status line at the bottom shows what Mods is doing between tool calls
("Reading file: ...", "Running command: ...", "Searching web: ..."). Hide it
with --hide-tool-status, which also suppresses the compact one-line record
each completed tool call leaves in normal output (for example
> ✓ shell_run: ls -la · exit 0).
Use --show-token-usage (or -s) to print the input, output, and total token count for
an interaction to stderr without mixing it into the model response on stdout.
Connect external tools and data sources through Model Context Protocol servers
configured under mcp-servers in mods.yml:
mcp-servers:
github:
command: docker
env:
- GITHUB_PERSONAL_ACCESS_TOKEN=xxxyyy
args:
- run
- "-i"
- "--rm"
- "-e"
- GITHUB_PERSONAL_ACCESS_TOKEN
- "ghcr.io/github/github-mcp-server"
Inspect what's available with mods --list-mcps and mods --list-tools.
Mods is configured for the providers below out of the box. The easiest way to
get started is mods --config — it walks you through picking a provider, model,
and API key interactively. You can also set the matching environment variable
manually and select a model with --api and --model.
| Provider | --api value | Env var | Get a key |
|---|---|---|---|
| OpenAI | openai | OPENAI_API_KEY | platform.openai.com |
| Anthropic | anthropic | ANTHROPIC_API_KEY | console.anthropic.com |
google | GOOGLE_API_KEY | aistudio.google.com | |
| Azure OpenAI | azure | AZURE_OPENAI_KEY | azure.microsoft.com |
| DeepSeek | deepseek | DEEPSEEK_API_KEY | platform.deepseek.com |
| OpenRouter | openrouter | OPENROUTER_API_KEY | openrouter.ai |
| Ollama | ollama | — (local) | ollama.com |
| GLM | glm | ZAI_API_KEY | open.bigmodel.cn |
| Qwen | qwen | DASHSCOPE_API_KEY | dashscope.console.aliyun.com |
| Kimi | kimi | MOONSHOT_API_KEY | platform.moonshot.cn |
| MiniMax | minimax | MINIMAX_API_KEY | www.minimaxi.com |
Direct requests to api.openai.com use the Responses API for every model and
feature. Mods sends store: false and keeps the encrypted response items needed
for stateless reasoning and tool continuation in its local session data. Azure
OpenAI, custom base URLs, and other OpenAI-compatible providers continue to use
Chat Completions.
Official deepseek-v4-flash requests to api.deepseek.com also use the
DeepSeek Responses API
automatically. Mods uses its plaintext reasoning events, hosted web search, and
Codex-compatible free-form apply_patch tool. DeepSeek Responses is stateless,
so complete response items and tool outputs remain in the local session and are
replayed on the next turn. It does not currently accept image or file input;
mods rejects such requests before sending them. To opt out for this model, set
endpoint: chat-completions in mods.yml:
apis:
deepseek:
base-url: https://api.deepseek.com/
models:
deepseek-v4-flash:
endpoint: chat-completions # optional explicit fallback
reasoning-effort: high # low, high, or max with --think
api-type, provider-profile, and endpoint are intentionally separate:
api-type chooses the transport adapter (openai, anthropic, google,
ollama, or azure).provider-profile chooses provider-specific semantics on an
OpenAI-compatible transport (openai, deepseek, qwen, glm, kimi, or
minimax). A model-level value overrides the provider default.endpoint chooses responses or chat-completions for a model.An arbitrarily named gateway can therefore use DeepSeek Responses explicitly:
apis:
company-router:
api-type: openai
base-url: https://gateway.example.com/v1
api-key-env: COMPANY_ROUTER_KEY
models:
deepseek-v4-flash:
provider-profile: deepseek
endpoint: responses
Unknown enum values are rejected instead of silently falling back. Custom
providers must configure base-url; only built-in providers with a known
official endpoint may omit it.
web-search-backend accepts auto (default), local, or provider. In auto
mode DeepSeek Responses uses hosted search without a Tavily key; other endpoints
keep the existing local search behavior. provider fails before the request if
the selected endpoint has no hosted search capability.
Anthropic requests continue to use the Messages API. With -t, mods chooses
adaptive or manual extended thinking for recognized Claude models. During tool
use it keeps complete thinking, signature, redacted-thinking, and tool-use
blocks in local session state and sends them back unchanged with tool results.
For an opaque model on a custom api-type: anthropic endpoint, configure
thinking-type explicitly instead of relying on model-name inference.
Gemini 2.5 uses thinkingBudget (-1 requests a dynamic budget), while Gemini
3 maps reasoning-effort to thinkingLevel. Ollama sends its native think
field and renders message.thinking separately from the final answer. Exact
effort values remain model/provider dependent; unsupported configured values
fail before the HTTP request.
mods --api anthropic --model claude-sonnet-4-6 "explain this error"
mods --api glm --model glm-5.2 "把这个日志总结成中文要点"
mods --api ollama --model llama4 "summarize this log"
Any other OpenAI-compatible endpoint can be added as a custom profile:
mods --config can discover models for providers that expose a model-list
endpoint. If discovery is unavailable, enter the model name in the wizard or add
it manually:
apis:
groq:
base-url: https://api.groq.com/openai/v1
api-key-env: GROQ_API_KEY
models:
llama-3.3-70b-versatile:
aliases: ["groq-llama"]
mods [OPTIONS] [PROMPT...]
mods --help # all options, grouped by purpose
mods --config # interactive setup wizard (recommended for new users)
mods --settings # open mods.yml in $EDITOR
mods --settings '' # recursively merge YAML into mods.yml
mods --dirs # show where mods stores its data
Most advanced defaults (model parameters, themes, MCP, debug, format hints)
live in mods.yml and are documented inline. Run mods --reset-settings to
back up the current file and restore the defaults.
Roles are reusable system prompts. Define one in mods.yml:
roles:
shell:
- you are a shell expert
- you do not explain anything
- you simply output one liners to solve the problems you're asked
- you do not provide any explanation whatsoever, ONLY the command
Then use it:
mods --role shell "list the largest files in the current directory"
mods --list-roles
Built-in runtime prompts can also be overridden in mods.yml. Run
mods --list-prompts to print the available keys and their default text, then
copy the one you want to customize:
prompts:
plan: |
Create a concise plan for approval before making changes.
shell-classifier: |
Analyze this shell command for review.
Return only strict JSON.
Issues and pull requests are welcome on this fork. Use go run github.com/go-task/task/v3/cmd/task@v3.51.1 check to verify
the project compiles and go run github.com/go-task/task/v3/cmd/task@v3.51.1 test to run the test suite before opening a PR.
Real-AI CLI black-box tests are kept behind the integration build tag and
are not part of the default CI suite. They build and execute the mods binary
with isolated config, data, cache, home, and workspace directories. To run the
real-AI scenarios:
export DEEPSEEK_API_KEY=...
go run github.com/go-task/task/v3/cmd/task@v3.51.1 test-blackbox-ai
These scenarios make paid network requests and cover structured pipe input, session continuation across processes, complex read-only shell pipelines, filesystem tool use, and enforcement of the filesystem workspace boundary. The runner uses the first available key in this provider order: DeepSeek, Qwen, OpenAI, Anthropic, GLM, then Google. Google runs the non-tool scenarios because its adapter does not expose built-in filesystem or shell tools.
Set MODS_BLACKBOX_PROVIDER to select a provider explicitly and
MODS_BLACKBOX_MODEL to override its default model:
MODS_BLACKBOX_PROVIDER=qwen MODS_BLACKBOX_MODEL=qwen-plus \
go run github.com/go-task/task/v3/cmd/task@v3.51.1 test-blackbox-ai