1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
# Reference: built-in tools
> Neutral description of the tools declared to the model. A tool never returns a Go error for an ordinary failure: the failure text is returned to the model as the tool's output. Every tool records its call in the loop detector; the same tool, input and output three times in a row appends `[LOOP_DETECTED: …]` to the output.
## `bash`
Always declared.
| Field | Type | Description |
|-------|------|-------------|
| `command` | string | The shell command to run. |
| Aspect | Behaviour |
|--------|-----------|
| Shell | `bash -c <command>`, a new shell per call, no stdin. |
| Working directory | The process directory in terminal mode; the session `cwd` in ACP mode. |
| Timeout | 30 s; the output then ends with `[error: 30s timeout exceeded]`. |
| Output | stdout and stderr merged, truncated to `maxOutput` characters. |
| Non-zero exit | Output ends with `[exit code: exit status N]`. |
| Terminal display | `🛠️ bash: <command>` before running, then up to `previewLines` lines dimmed and indented, or `(no output)`. |
| ACP | Tool call of kind `execute`; permission requested before running; a refusal returns `[command rejected by the user]` with status `failed`. |
## `read_skill`
Declared only when `skillsDir` holds at least one skill (`<name>.md` or `<name>/SKILL.md`).
| Field | Type | Description |
|-------|------|-------------|
| `name` | string | Skill name, exactly as listed in the tool description. |
| Aspect | Behaviour |
|--------|-----------|
| Description | Fixed sentence followed by the catalogue: one ` <name> — <description>` line per skill, sorted by name. |
| Output | The full markdown of `<skillsDir>/<name>.md`, or of `<skillsDir>/<name>/SKILL.md` when there is no flat file, truncated to `maxOutput`. |
| Unknown name | `No skill named "x". Available skills: a, b, c` |
| Path safety | Only the base name of `name` is used; no directory traversal. |
| Terminal display | `📖 read_skill: <name>`; the content is not echoed. |
| ACP | Tool call of kind `read`; no permission dialog. |
## `read_file`
Declared when `editTools: true`.
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `path` | string | — | File path, relative to the working directory. |
| `start` | int | `0` | First line (1-based); `0` = from the start. |
| `end` | int | `0` | Last line (1-based, inclusive); `0` = to the end. |
| `numbered` | bool | `false` | Prefix each line with its number. |
| Aspect | Behaviour |
|--------|-----------|
| Missing file | `<path> does not exist. Create it with write_file` |
| Output | The lines, truncated to `maxOutput`; the final newline is kept only when the end of the file is shown. |
| ACP | Kind `read`, with the absolute path as location. |
## `write_file`
Declared when `editTools: true`.
| Field | Type | Description |
|-------|------|-------------|
| `path` | string | File path, relative to the working directory; parent directories are created. |
| `content` | string | The whole content of the file. |
| Aspect | Behaviour |
|--------|-----------|
| Existing file | Entirely replaced. |
| Identical content | Nothing is written; the result says so. |
| Output | A one-line headline and the diff against the previous content. |
| ACP | Kind `edit`; permission requested; the change travels as a diff (new-file diff when created). |
## `edit_file`
Declared when `editTools: true`.
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `path` | string | — | Path of an existing file. |
| `edits` | array of `{old, new}` | — | Replacements, all resolved against the original file. |
| `edits[].old` | string | — | Exact text to find, present exactly once. |
| `edits[].new` | string | — | Replacement; empty deletes the matched text. |
| `dry_run` | bool | `false` | Report what would change, write nothing. |
| Rule | Consequence when broken |
|------|-------------------------|
| `old` appears exactly once | Refused: not found, or ambiguous. |
| Two edits must not overlap, nest or repeat | Refused. |
| Edits are resolved against the original text, never in cascade | — |
| Any refused edit | Nothing is written. |
| Aspect | Behaviour |
|--------|-----------|
| Output | A one-line headline (edits applied, lines added and deleted, first changed line) and the diff with line numbers. |
| ACP | Kind `edit`; permission requested; the change travels as a diff with old and new text. |
## Counters shown after a turn
| Counter | Counts |
|---------|--------|
| `⚙ N command(s)` | `bash` tool responses in the turn. |
| `📝 N file op(s)` | `read_file`, `write_file`, `edit_file` responses. |
| `📖 N skill(s)` | `read_skill` responses. |
|