Tools, six built-in to fourteen: - read_many_files: up to 20 paths read concurrently, each with its own window. An unreadable path is reported in its own block instead of throwing. - multi_edit: several edits to one file, validated in memory first so a late failure cannot leave the file half-written. - list_dir: ignore-aware depth-limited tree. - git_status/diff/log/show/blame: read-only, spawned with a fixed argv rather than a shell string, which is what makes them safe to auto-approve. toolSets gates them. core is always on; edit-plus and git are optional. A disabled set reaches neither the wire nor the system prompt, since a prompt naming an absent tool teaches calls that cannot succeed. Interface: - Reasoning streams to a collapsed panel, ctrl-r expands, dropped when the turn ends: it is progress, not the answer. - The tool in flight is named from tool-input-start, before its arguments finish streaming, and cleared on its result. - Prompts typed mid-turn queue and drain in order. esc clears the queue as well as aborting. - @ opens a path picker fed by the ignore-aware walker. Prefix matches rank above substring matches, so @src/ means "under src/". The walk runs on the first @, not at startup. ctrl-c kills the command in flight and keeps the turn. The call throws rather than returning, so the model cannot read a killed command as one that ran and failed on its own terms. The kill takes the whole process tree: killing cmd /c alone left the real command holding both pipes open, so the read never returned and the interrupt did nothing for 19 seconds. Two pruning fixes: - A tool result whose tool call was pruned is now dropped with it. Pruning counts messages, so the cut landed between an assistant tool-call and the tool message answering it, producing 400 "No tool call found for function call output with call_id ...". The reverse pairing is left alone: a call awaiting its result is what a suspended approval looks like. - ignore.ts called statFs without importing it, so walk() crashed on the first symlink. 482 tests, up from 404. Docs synced across README, ROADMAP, TODO, and all of docs/: tool sets, the new tools, ctrl-c semantics, the tool-start event, and the two hand-maintained tool-name lists recorded as a known weakness.
143 lines
5.3 KiB
Markdown
143 lines
5.3 KiB
Markdown
# Configuration
|
|
|
|
Settings come from three places. Later wins:
|
|
|
|
1. `~/.shiro-neko/config.json`
|
|
2. environment variables
|
|
3. command-line flags
|
|
|
|
## The config file
|
|
|
|
Written by `/provider`, editable by hand. Every field is optional.
|
|
|
|
```json
|
|
{
|
|
"provider": "openai",
|
|
"model": "gpt-5",
|
|
"baseURL": "https://api.openai.com/v1",
|
|
"apiKey": "sk-...",
|
|
"presetId": "openai",
|
|
"agent": "default",
|
|
"thinking": "medium",
|
|
"maxRetries": 3,
|
|
"plugins": ["guard", "time"],
|
|
"toolSets": ["edit-plus", "git"],
|
|
"mcpServers": {
|
|
"fs": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "."] }
|
|
}
|
|
}
|
|
```
|
|
|
|
| Field | Meaning |
|
|
|---|---|
|
|
| `provider` | wire protocol: `anthropic` or `openai`. Not the vendor — Groq, OpenRouter, and Ollama all speak `openai` |
|
|
| `model` | model id as the endpoint names it |
|
|
| `baseURL` | API root. Defaults to the official endpoint for the provider |
|
|
| `apiKey` | sent as `Authorization: Bearer` for `openai`, `x-api-key` for `anthropic` |
|
|
| `presetId` | which preset `/provider` chose, so it can show what is configured |
|
|
| `agent` | default variant: `default`, `quick`, `deep`, `plan`, `review` |
|
|
| `thinking` | default level: `off`, `low`, `medium`, `high`, `max` |
|
|
| `maxRetries` | retries per model call for transient failures. Default 3 |
|
|
| `plugins` | which plugins to enable. Omit for `["guard", "time"]` |
|
|
| `toolSets` | optional tool sets beyond `core`: `edit-plus`, `git`. Omit for all of them. See [tools](tools.md) |
|
|
| `mcpServers` | see [MCP](mcp.md) |
|
|
|
|
## Provider presets
|
|
|
|
`/provider` offers these. Each sets `baseURL` and the wire protocol for you.
|
|
|
|
| Preset | Protocol | Endpoint |
|
|
|---|---|---|
|
|
| Anthropic | `anthropic` | `api.anthropic.com/v1` |
|
|
| OpenAI | `openai` | `api.openai.com/v1` |
|
|
| OpenRouter | `openai` | `openrouter.ai/api/v1` |
|
|
| Groq | `openai` | `api.groq.com/openai/v1` |
|
|
| DeepSeek | `openai` | `api.deepseek.com/v1` |
|
|
| xAI | `openai` | `api.x.ai/v1` |
|
|
| Ollama | `openai` | `localhost:11434/v1` |
|
|
| LM Studio | `openai` | `localhost:1234/v1` |
|
|
| Custom OpenAI-compatible | `openai` | you supply it |
|
|
| Custom Anthropic-compatible | `anthropic` | you supply it |
|
|
|
|
After the key is entered, `GET /v1/models` is called and the list becomes a picker. If the
|
|
endpoint does not implement it, you type the model id instead — the setup still completes.
|
|
|
|
## Environment variables
|
|
|
|
| Variable | Effect |
|
|
|---|---|
|
|
| `SHIRO_PROVIDER` | overrides `provider` |
|
|
| `SHIRO_MODEL` | overrides `model` |
|
|
| `SHIRO_BASE_URL` | overrides `baseURL` |
|
|
| `SHIRO_API_KEY` | overrides `apiKey` |
|
|
| `ANTHROPIC_API_KEY` | used when `provider` is `anthropic` and no key is set |
|
|
| `OPENAI_API_KEY` | used when `provider` is `openai` and no key is set |
|
|
| `SHIRO_HOME` | relocates config, sessions, memory, history, and user skills |
|
|
| `SHIRO_INSTALL_DIR` | where `install:local` and the installers put the binary |
|
|
| `SHIRO_REPO` | which GitHub repo the installers download from |
|
|
| `SHIRO_VERSION` | pins the version the installers fetch |
|
|
|
|
`SHIRO_HOME` is what the test suite uses to keep a run out of your real config.
|
|
|
|
## Flags
|
|
|
|
```
|
|
shiro [options]
|
|
shiro -p "prompt" headless, prints to stdout
|
|
cat file | shiro -p prompt read from stdin
|
|
```
|
|
|
|
| Flag | Effect |
|
|
|---|---|
|
|
| `-p`, `--print [prompt]` | headless mode. Needs `--yolo` for tool use |
|
|
| `--json` | with `-p`, one JSON event per line |
|
|
| `-c`, `--continue` | resume the newest session for this directory |
|
|
| `-r`, `--resume <id>` | resume by session id or unique prefix |
|
|
| `--agent <name>` | `default`, `quick`, `deep`, `plan`, `review` |
|
|
| `--think <level>` | `off`, `low`, `medium`, `high`, `max` |
|
|
| `--provider <name>` | `anthropic` or `openai` |
|
|
| `--model <id>` | model id |
|
|
| `--base-url <url>` | API root |
|
|
| `--no-mcp` | skip MCP servers |
|
|
| `--no-subagent` | omit the `task` tool |
|
|
| `--no-instructions` | ignore `AGENTS.md` and friends |
|
|
| `--no-skills` | ignore builtin and project skills |
|
|
| `--no-plugins` | disable all plugins, including the guard |
|
|
| `--no-memory` | do not load or write project memory |
|
|
| `--yolo` | skip every approval prompt |
|
|
| `-v`, `--version` | version, bun version, platform, source or compiled |
|
|
| `-h`, `--help` | usage |
|
|
|
|
## Where things live
|
|
|
|
```
|
|
~/.shiro-neko/
|
|
config.json provider, model, key, defaults
|
|
sessions/<uuid>.json transcripts, token counts, cost, task list
|
|
memory/<hash>.json durable per-project notes
|
|
history/<hash>.json prompt history for up-arrow recall
|
|
skills/*.md your own skills
|
|
```
|
|
|
|
Project files:
|
|
|
|
```
|
|
<project>/
|
|
AGENTS.md instructions injected into the system prompt
|
|
.shiro/skills/*.md project skills, override user and builtin
|
|
.shiroignore extra ignore rules on top of .gitignore
|
|
```
|
|
|
|
Memory and history file names are SHA-256 prefixes of the absolute project path, because a
|
|
path is not a safe filename.
|
|
|
|
## OpenAI reasoning models
|
|
|
|
Newer OpenAI models reject function tools on `/v1/chat/completions` and require
|
|
`/v1/responses`. For `api.openai.com` both are chained: a 400, 404, 405, 415, 422, or 501
|
|
on the first switches to the second, sticks for the rest of the session, and prints one
|
|
notice. Retryable failures — 429 and 5xx — are left to the SDK's backoff instead.
|
|
|
|
Third-party endpoints get a plain chat-completions model with no fallback probe, since they
|
|
do not implement `/v1/responses`.
|