Files
shiro-neko/docs/tools.md
T
Muhammad Zakir Ramadhan 5b8503fcd9 Initial commit: shiro-neko 0.1.0-beta.1
Agentic coding CLI on Bun, Ink, and the AI SDK.

Core: streamText loop with SDK-level tool approval so a denied call provably never executes; endpoint fallback for OpenAI reasoning models; retry with backoff.

Tools: read/write/edit/glob/grep/bash, path-jailed, gitignore-aware, ripgrep with a JS fallback, binary rejection, live bash streaming.

Agents: five variants crossing thinking level with tool restriction; plan and review withhold mutating tools from the model.

Extensibility: frontmatter skills with on-demand bodies, plugin host with blocking hooks, MCP stdio and HTTP, read-only subagents.

State: durable per-project memory, session task lists, session persistence, compaction that repairs provider-item dependencies.

Distribution: five-platform cross-compiled binaries with checksums, install scripts, CI on three operating systems.

404 tests, typecheck clean.
2026-09-02 17:30:18 +07:00

173 lines
5.2 KiB
Markdown

# Tools
## The approval model
Three categories.
**Free.** Read-only, no prompt: `read_file`, `glob`, `grep`, `task`.
**Session tools.** Also free, because they touch the agent's own state rather than your
files: `todo_write`, `remember`, `recall`, `forget`, `skill`, `ask`, and anything a plugin
marks auto-approved.
**Gated.** Every call stops for a decision: `write_file`, `edit_file`, `bash`, and every
`mcp__*` tool.
```
edit_file wants to run
src/users.ts +2 -1
export function paginate(offset: number, total: number) {
- if (offset < total) return next();
+ if (offset <= total) return next();
}
y allow once | a always allow edit_file | n deny
```
`a` whitelists that tool for the rest of the session. `n` tells the model it was denied and
to ask what to do instead. `--yolo` skips all prompts.
**The guard runs before all of this.** It is not an approval — it is a refusal, and `--yolo`
does not reach it. See [plugins](plugins.md).
## File tools
### `read_file`
```
path file path relative to the workspace root
offset first line, 1-based
limit max lines, default 2000
```
Returns contents with 1-based line numbers. Refuses binaries: a NUL byte in the first 8 KB
means the file is not text, and a model that reads a 90 MB executable has burned its whole
context on nothing.
### `write_file`
```
path file path
content full contents
```
New files and full rewrites only. Creates parent directories.
### `edit_file`
```
path file path
oldString exact text to find, whitespace and indentation included
newString replacement
replaceAll replace every occurrence instead of requiring exactly one
```
`oldString` must match byte-for-byte and appear exactly once unless `replaceAll` is set.
An ambiguous match is an error naming the count, which pushes the model to add surrounding
context rather than guessing which occurrence it meant.
### `glob`
```
pattern e.g. "src/**/*.ts"
limit max paths, default 200
includeIgnored also return files git ignores
```
Walks the tree honouring `.gitignore` and `.shiroignore`, skipping `.git` and
`node_modules` unconditionally. Nested ignore files apply only within their own directory,
as git does. Returns posix paths relative to the workspace root.
### `grep`
```
pattern regex source
include glob limiting the search, default "**/*"
ignoreCase case-insensitive
includeIgnored also search files git ignores
```
Shells out to ripgrep when it is on PATH — roughly 15x faster on a real repo — and falls
back to a JavaScript walker otherwise. Output is `path:line: text` either way, so the model
sees one format regardless. Skips binaries. Caps at 200 hits.
### `bash`
```
command shell command
timeout ms, default 120000, max 600000
```
Runs in the workspace root through `bash -lc` or `cmd /c`. Output streams live to the panel
above the input rather than appearing all at once when the command exits — a two-minute test
run is otherwise indistinguishable from a hang. Both pipes are drained concurrently, since a
command that fills one while you block on the other deadlocks.
Returns exit code, stdout, stderr, and a note if a signal killed it.
## Agent tools
### `task`
```
description short label shown to you
prompt self-contained instructions
kind "explore" (default) or "review"
```
Spawns a read-only subagent with `read_file`, `glob`, and `grep` only. It returns one
report, so the parent pays for findings rather than the whole search transcript. It sees
none of the parent conversation, so its prompt has to stand alone.
`explore` finds and reports. `review` critiques code in severity order. Progress streams to
the subagent panel.
### `ask`
```
question one specific question
options choices, recommendation first, each with an optional detail
multiple allow more than one
```
Stops the turn and puts the question on screen. With options it is a picker; without, free
text. `esc` skips, which tells the model to decide and state its assumption.
Withheld entirely in headless mode — a question with no one to answer it would hang.
### `todo_write`
```
todos the complete list: content, status, optional note
```
Statuses: `pending`, `in_progress`, `done`, `blocked`. Send the whole list each time; it
replaces the previous one. Warns when more than one task is `in_progress`, when nothing is
`in_progress` while work remains, or when a `blocked` task has no note.
### `remember`, `recall`, `forget`
Durable per-project notes. See [memory](memory.md).
### `skill`
```
name skill name from the catalogue
```
Loads the body of a skill. See [skills](skills.md).
## Path safety
Every path a tool receives goes through a jail: resolved against the workspace root, then
checked that it did not escape. `../../etc/passwd` and absolute paths outside the root are
both refused before any filesystem call.
The model's output is a trust boundary. It can emit any string, so the check happens on
every call rather than being assumed.
## Output caps
Any single tool result is truncated at 30,000 characters with a note saying how much was
cut. `grep` stops at 200 hits, `glob` at 200 paths, `read_file` at 2000 lines by default.
Without caps one `grep` for `function` can end a session.