Files
shiro-neko/README.md
T
Muhammad Zakir Ramadhan 2fa6ee247b Add batch reads, @file completion, interruptible commands, tool sets
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.
2026-09-03 01:37:48 +07:00

148 lines
5.9 KiB
Markdown

<p align="center">
<img src="./assets/logo.png" height="300">
</p>
<h1 align="center">Shiro Neko</h1>
<p align="center">
An agentic coding CLI. It reads your code, edits it, runs your tests, and asks when the
request is ambiguous — in a terminal UI, with every mutating action gated behind an
approval prompt.
</p>
## Install
A single prebuilt binary. No runtime, no `node_modules`.
```bash
# macOS, Linux
curl -fsSL https://raw.githubusercontent.com/zakirkun/shiro-neko/main/scripts/install.sh | sh
# Windows
irm https://raw.githubusercontent.com/zakirkun/shiro-neko/main/scripts/install.ps1 | iex
```
Both verify the download against the release checksums before installing. Builds are
published for `linux-x64`, `linux-arm64`, `darwin-x64`, `darwin-arm64`, and `windows-x64`.
Or from source:
```bash
git clone https://github.com/zakirkun/shiro-neko
cd shiro-neko
bun install
bun run install:local # builds and puts `shiro` on PATH
```
## First run
```bash
shiro
```
With no API key configured it opens provider setup: pick an endpoint, paste a key, choose
from the models that endpoint actually reports. Settings land in
`~/.shiro-neko/config.json`. Run `/provider` any time to change them.
```
shiro-neko 0.1.0-beta.1 openai/gpt-5 session 0193ab2c
agent: default thinking: medium
cwd: /home/you/project
skills: debug, refactor, review, test
plugins: guard, time
approvals: on for write_file, edit_file, multi_edit, bash, mcp__*
/help for commands
> why does the pagination test fail?
```
## What it does
**Answers about your code, grounded in your code.** `grep` goes through ripgrep when it is
installed and honours `.gitignore`. `list_dir` gives an ignore-aware tree so it stops globbing
blindly to orient, and `read_many_files` pulls a batch in one round trip. `read_file` refuses
binaries rather than filling the context with mojibake.
**Edits with your approval.** Every `write_file`, `edit_file`, `multi_edit`, and `bash` call
stops for a `y`/`a`/`n` decision, with a coloured diff for edits. `multi_edit` is atomic, so
a failing match leaves the file untouched rather than half-changed. The `guard` plugin
refuses irreversible commands outright — `rm -rf`, `git reset --hard`, force pushes,
`DROP TABLE` — and `--yolo` cannot bypass it.
**Shows its work.** Reasoning streams to a collapsed panel you can expand with `ctrl-r`, the
tool in flight is named as it runs, and `bash` output streams live instead of arriving all at
once when the command exits. `ctrl-c` kills a runaway command without ending the turn.
**Takes prompts while it works.** Type during a turn and it queues; the queue drains in order
when the turn ends. `esc` interrupts and clears it. `@` completes workspace paths.
**Reads git without touching it.** `git_status`, `git_diff`, `git_log`, `git_show`, and
`git_blame` are approval-free, because they spawn git with a fixed argument list and cannot
mutate anything.
**Asks instead of guessing.** When a request has two readings that lead to different work,
the agent puts a question on screen with options.
**Delegates searches.** `task` spawns a read-only subagent whose findings come back as one
message, so a search across forty files does not fill the main context. Its progress
streams to a panel.
**Remembers between sessions.** Decisions, working commands, and traps go into per-project
memory that is injected at the start of every future session.
**Survives long tasks.** The task list and project memory live outside the message array,
so they survive both automatic pruning and `/compact`.
**Runs headless.** `shiro -p "review this diff" --json` for scripts and CI.
**Keeps the tool list affordable.** Fourteen built-in tools, grouped into sets. Each costs
about 550 characters of schema on every request, so `{ "toolSets": [] }` trims back to the six
core ones and a disabled set reaches neither the wire nor the prompt.
## Documentation
| Guide | Contents |
|---|---|
| [Configuration](docs/configuration.md) | config file, environment variables, every flag |
| [Tools](docs/tools.md) | every tool, tool sets, the approval model, the guard |
| [Agents and thinking](docs/agents.md) | variants, thinking levels, read-only modes |
| [Skills](docs/skills.md) | the bundled skills and writing your own |
| [Plugins](docs/plugins.md) | the plugin interface and the builtins |
| [Memory and state](docs/memory.md) | memory, task lists, sessions, compaction |
| [MCP](docs/mcp.md) | connecting Model Context Protocol servers |
| [Headless mode](docs/headless.md) | `-p`, JSON events, exit codes, CI recipes |
| [Architecture](docs/architecture.md) | how the loop works and why it is built this way |
| [Development](docs/development.md) | building, testing, releasing |
| [Roadmap](ROADMAP.md) | what is next and what has been declined |
| [TODO](TODO.md) | the current work list |
## Commands
Type `/` and a menu appears, narrowing as you type.
```
/help /agent [name] /think [level] /provider /models /model <id>
/skills /plugins /init /context /todos /notes /memory
/tools /compact /cost /sessions /resume <id> /save /clear /exit
```
`esc` dismisses a panel, interrupts a running turn, and clears the queue. `ctrl-c` kills the
running command but keeps the turn. `ctrl-r` expands the reasoning panel. `@` completes a
workspace path. Up and down recall earlier prompts.
## Status
Working: the agent loop, tool approvals, subagents, skills, plugins, per-project memory,
session persistence, MCP, markdown rendering, headless mode, five-platform builds, streaming
reasoning display, the mid-turn prompt queue, gateable tool sets, read-only git tools, batch
reads, `@file` completion, and interruptible commands.
Next up is in [TODO.md](TODO.md); the longer view and what has been declined are in
[ROADMAP.md](ROADMAP.md). The short version of what is missing: a summary of what compaction
discarded, `web_fetch`, and a cheaper model for subagent searches.
## License
MIT. See [LICENSE](LICENSE).