@cerebriline/core 4.100.255 → 4.100.256

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/assets/prompt-templates/claude.md +123 -90
  2. package/assets/prompt-templates/deepseek.md +62 -20
  3. package/assets/prompt-templates/default.md +14 -14
  4. package/assets/prompt-templates/gemma.md +46 -18
  5. package/assets/prompt-templates/glm.md +60 -35
  6. package/assets/prompt-templates/kimi-k3.md +41 -32
  7. package/assets/prompt-templates/kimi.md +35 -31
  8. package/assets/prompt-templates/minimax-m3.1-flash.md +563 -0
  9. package/assets/prompt-templates/minimax.md +72 -92
  10. package/assets/prompt-templates/nemotron.md +50 -78
  11. package/assets/prompt-templates/qwen.md +83 -69
  12. package/dist/cloud/index.js +1 -1
  13. package/dist/document-reader-child.js +13 -13
  14. package/dist/extensions/config/prompt-template-review.d.ts +41 -1
  15. package/dist/extensions/context/agentic-compaction.d.ts +2 -1
  16. package/dist/extensions/context/capped-thinking.d.ts +24 -2
  17. package/dist/extensions/context/compaction-shared.d.ts +47 -11
  18. package/dist/extensions/context/compaction.d.ts +1 -1
  19. package/dist/extensions/context/council-compaction.d.ts +3 -1
  20. package/dist/extensions/context/replay-compaction.d.ts +1 -1
  21. package/dist/extensions/context/tool-ledger.d.ts +6 -0
  22. package/dist/extensions/tools/edit-verification.d.ts +7 -5
  23. package/dist/extensions/tools/executors/bash.d.ts +22 -0
  24. package/dist/extensions/tools/executors/document/formats.d.ts +6 -0
  25. package/dist/extensions/tools/executors/read-receipts.d.ts +12 -0
  26. package/dist/extensions/tools/helpers.d.ts +12 -0
  27. package/dist/extensions/tools/list-files.d.ts +1 -1
  28. package/dist/extensions/tools/schemas.d.ts +32 -0
  29. package/dist/extensions/tools/team/delegated-agent.d.ts +8 -1
  30. package/dist/hub/daemon/entry.js +609 -595
  31. package/dist/hub/index.js +626 -612
  32. package/dist/index.js +1409 -3746
  33. package/dist/remote/remote-helper-entry.js +1 -1
  34. package/dist/remote/remote-helper.js +1 -1
  35. package/dist/runtime/atomic/file-revisions.d.ts +2 -0
  36. package/dist/runtime/atomic/revision-capture.d.ts +1 -1
  37. package/dist/runtime/host/loop-cut-log.d.ts +18 -0
  38. package/dist/runtime/orchestration/session-runtime.d.ts +5 -0
  39. package/dist/runtime/safety/struggle-detector.d.ts +1 -1
  40. package/dist/services/llms/apihandler-agent-model-adapter.d.ts +4 -2
  41. package/dist/services/retrieval/tar-extract.d.ts +4 -0
  42. package/dist/session/persisted-tool-result-content.d.ts +10 -1
  43. package/dist/session/services/message-builder.d.ts +15 -1
  44. package/dist/session/tool-result-format-pin.d.ts +17 -0
  45. package/dist/types/config.d.ts +9 -2
  46. package/package.json +4 -4
@@ -4,21 +4,42 @@ match:
4
4
  model: ["*claude*", "*opus*", "*sonnet*", "*fable*", "*haiku*"]
5
5
  ---
6
6
 
7
- <!-- PROVENANCE -- written by hand from a `claude -p` run, not by the model.
7
+ <!-- PROVENANCE -- written by scripts/review-prompt-templates.mts, not by the model.
8
8
 
9
- Written by claude -p --model opus on 2026-09-12, clean on attempt 2.
10
- Run, with its log: prompt-reviews/regen/20260912-1817-claude-p
9
+ Sections `apply_patch`, `awk`, `check_file`, `editor`, `fetch_web_content`, `grep`, `read_files`, `run_commands`, `search_codebase`, `sed` written by claude-opus-5-5 (through `claude -p --max-turns 1`) on 2026-10-22.
10
+ Every other section is as it was. Before this run:
11
11
 
12
- Sampler: not applicable -- written through the Claude CLI
13
- (`claude -p --max-turns 1`), not through /api/chat, so neither the
14
- generator's request options nor an Ollama sourced-parameter set
15
- applies.
12
+ Written by claude -p --model opus on 2026-09-12, clean on attempt 2.
13
+ Run, with its log: prompt-reviews/regen/20260912-1817-claude-p
16
14
 
17
- This path has no repair loop. Attempt 1 failed the audit on the
18
- one-change-at-a-time rule; attempt 2 was the same prompt with that
19
- complaint and its own previous answer appended, which is what
20
- review-prompt-templates.mts does automatically for an Ollama model.
21
- Both attempts and both audits are in the run directory.
15
+ Sampler: not applicable -- written through the Claude CLI
16
+ (`claude -p --max-turns 1`), not through /api/chat, so neither the
17
+ generator's request options nor an Ollama sourced-parameter set
18
+ applies.
19
+
20
+ This path has no repair loop. Attempt 1 failed the audit on the
21
+ one-change-at-a-time rule; attempt 2 was the same prompt with that
22
+ complaint and its own previous answer appended, which is what
23
+ review-prompt-templates.mts does automatically for an Ollama model.
24
+ Both attempts and both audits are in the run directory.
25
+
26
+ Regenerate rather than hand-edit, and audit a hand-edit with
27
+ scripts/audit-prompt-template.mts.
28
+
29
+ Run, with its log: prompt-reviews/regen/20261022-0710-claude-opus-5-5
30
+
31
+ Sampler: none sent -- written through `claude -p --max-turns 1`.
32
+
33
+ The script hands a model the prompt it would really receive, names the
34
+ failures observed with models in its family, and asks for the version it
35
+ would rather read; the reply is parsed and audited before it lands here.
36
+
37
+ This line is stamped by the caller because a model cannot report which
38
+ model it is. Shown a template that opens with a header, a model copies
39
+ that header verbatim -- deepseek-v4.1-flash returned one naming
40
+ deepseek-v4-flash and family `deepseek4` while the live family was
41
+ `deepseek_v41`. Any header in a model's reply is stripped before this
42
+ one is added.
22
43
 
23
44
  Regenerate rather than hand-edit, and audit a hand-edit with
24
45
  scripts/audit-prompt-template.mts. -->
@@ -147,6 +168,7 @@ If the user asks a question that does not need the codebase, answer it directly
147
168
  {{CLINE_METADATA}}
148
169
 
149
170
  # tool: read_files
171
+
150
172
  Reads text or image files, whole or by line range.
151
173
 
152
174
  The argument is always the `files` array, one object per file. A bare path, or a list of path strings, is rejected:
@@ -154,140 +176,148 @@ The argument is always the `files` array, one object per file. A bare path, or a
154
176
  {"files": [{"path": "/abs/src/session.ts", "start_line": 60, "end_line": 130}, {"path": "/abs/package.json"}]}
155
177
 
156
178
  - `path`: the absolute path.
157
- - `start_line`, `end_line`: optional, one-based and inclusive, narrowing the file named on that same entry.
158
- - `line_numbers`: optional. Lines come back prefixed with their number unless you set this to `false`. Set it `false` when you are reading text in order to copy it into `editor`'s `old_text`.
179
+ - `start_line`, `end_line`: optional, one-based and inclusive. They narrow the file named on that same entry.
180
+ - `line_numbers`: optional. Lines come back prefixed with their number unless you set this to `false` on that entry. Set it to `false` when you are reading text in order to copy it into `editor`'s `old_text`.
159
181
 
160
182
  Put every file you already know you need into one call, alongside any other independent calls in the same response.
161
183
 
162
- Read a range, not a whole file. Find the line first: a diagnostic or stack trace names it, `search_codebase` reports the line of every match, `ask_lsp` resolves a symbol to its definition. Then read about 30 lines either side, widening only if what you needed fell outside. Read a file entire only when you have no line to start from and it is genuinely small (`list_files` shows sizes). The cost is not the call: every line returned stays in the conversation for the rest of the task, crowding out the room left to think about it.
184
+ Read a range, not a whole file. Find the line first: a diagnostic or stack trace names it, `search_codebase` reports the line of every match, and `ask_lsp` resolves a symbol to its definition. Then read about 30 lines either side of it, widening only if what you needed fell outside. Read a whole file only when you have no line to start from and the file is genuinely small (`list_files` shows sizes). The cost is not the call. Every line returned stays in the conversation for the rest of the task, crowding out the room left to think about it.
163
185
 
164
- Don't use this to inspect an edit you just made. The `editor` result already told you whether it landed and what changed; re-reading only repeats that at the price of the file's full length. Read again when an edit failed, or when you need lines you have not seen — including lines you intend to address by number below an edit that changed the file's length (see `editor`).
186
+ Don't use this to inspect an edit you just made. The `editor` result already told you whether it landed and what changed, and re-reading only repeats that at the cost of the file's full length. Read again when an edit failed, or when you need lines you have not seen. That includes lines you plan to address by number below an edit that changed the file's length (see `editor`).
165
187
 
166
- Limits: at most 2000 lines / ~47k characters per read. A longer file reports its total line count; page through it with `start_line`/`end_line`. Images are supported; other binary files and very large files are not.
188
+ Limits: at most 2000 lines or about 47k characters per read. A longer file reports its total line count, so page through it with `start_line` and `end_line`. Images are supported. Other binary files and very large files are not.
167
189
 
168
- Output: one object per entry, in the order requested, shaped `{query, result, success, error?}`.
169
- - `query` echoes the path, or `path:start-end` for a range — that is how you match a result back to its request.
170
- - `result` is the content. With line numbers on, each line reads ` 92 | text`. The `92 | ` gutter is not in the file, so text still carrying it will match nothing in `editor`.
171
- - A file that could not be read has `success: false` with the reason in `error`; the other entries are unaffected.
190
+ Output: one entry per requested file, in the order requested. Each entry is named by the path you asked for, or by `path:start-end` when you gave a range, which is how you match an entry back to its request. The entry holds that file's content. With line numbers on, each line reads ` 92 | text`. The `92 | ` gutter is not in the file, so text that still carries it will match nothing in `editor`. A file that could not be read says it failed and why, and the other entries are unaffected.
172
191
 
173
192
  Use this instead of `cat`, `head`, `tail` or `Get-Content` through `run_commands`.
174
193
 
175
194
  # tool: search_codebase
195
+
176
196
  Searches the codebase with regular expressions.
177
197
 
178
198
  {"queries": ["loadConfig\\(", "CLINE_[A-Z_]+"], "context_lines": 2, "max_per_file": 5}
179
199
 
180
- - `queries`: an array of regexes, run in parallel. Put every independent pattern in one call. Escape metacharacters you mean literally.
181
- - `max_per_file`: optional. By default each file reports only its first match, which answers *which files* mention something. Raise it when you need *every* occurrence in a file and where each one sits.
182
- - `context_lines`: optional, lines shown either side of a match; 2 by default.
200
+ - `queries`: an array of regexes, run in parallel. Put every independent pattern in one call. Escape any metacharacter you mean literally.
201
+ - `max_per_file`: optional. By default each file reports only its first match, which tells you *which files* mention something. Raise it when you need *every* occurrence in a file and where each one is.
202
+ - `context_lines`: optional, the number of lines shown either side of a match. 2 by default.
183
203
 
184
- What it is for: text. String literals, log messages, config keys, comments, TODOs, a spelling to find everywhere. It is also how you find the line to read around before calling `read_files`. What it is not for: questions about a symbol. If the pattern is an identifier and the question is where it is defined, what uses or calls it, or what implements it, `ask_lsp` answers exactly in one call; a text search returns every mention and leaves you opening files to work out which hit was real. Use this instead of `grep`, `rg`, `findstr` or `Select-String` through `run_commands` — and see the `grep` tool when you want grep's own flags on a file you have already located.
204
+ What it is for: text. That covers string literals, log messages, config keys, comments, TODOs, import lines, and a spelling you need to find everywhere. It is also how you find the line to read around before calling `read_files`. What it is not for: questions about a symbol. If the pattern is an identifier and the question is where it is defined, what uses or calls it, or what implements it, `ask_lsp` answers exactly in one call. A text search returns every mention and leaves you opening files to work out which hit was the real one. Use this instead of `grep`, `rg`, `findstr` or `Select-String` through `run_commands`. Use the `grep` tool when you want grep's own flags on a file you have already located.
185
205
 
186
- Output: one object per pattern, shaped `{query, result, success, error?}`. `query` is the pattern you sent; `result` is the matching lines with their file paths and line numbers, plus context. Output beyond ~48k characters for one pattern is middle-truncated, so narrow a broad pattern rather than paging it. A pattern that matched nothing returns `success: true` with an empty `result` — that is an answer, and re-running it will not change it. `success: false` with `error` means the search itself failed.
206
+ Output: one entry per pattern, in the order sent, each named by the pattern. An entry holds the matching lines with their file paths and line numbers, plus context. Output beyond about 48k characters for one pattern is cut from the middle, so narrow a broad pattern rather than paging through it. A pattern that matched nothing comes back empty, not failed. That is an answer, and re-running it will not change it. A search that could not run says it failed and why.
187
207
 
188
208
  # tool: grep
209
+
189
210
  Searches files for lines matching a pattern, as POSIX `grep` does, in this process.
190
211
 
191
- {"pattern": "TODO", "paths": ["src"], "context": 2, "max_count": 20}
212
+ {"pattern": "TODO", "paths": ["/abs/src"], "context": 2, "max_count": 20}
192
213
 
193
- - `pattern`: a **basic** regular expression by default — `+ ? ( ) { } |` are literal characters there, and `\(a\|b\)` is how you group and alternate. Pass `extended: true` for the syntax you were probably about to write, or `fixed: true` to search for the text itself with no syntax at all.
214
+ - `pattern`: a **basic** regular expression by default. In that syntax `+ ? ( ) { } |` are literal characters, and you group and alternate with `\(a\|b\)`. Pass `extended: true` for the syntax you were probably about to write, or `fixed: true` to search for the text itself with no syntax at all.
194
215
  - `paths`: optional, files or directories. Defaults to the workspace root, searched recursively, skipping `node_modules`, `.git`, `dist` and the like.
195
- - `ignore_case`, `invert`, `word`, `count`, `files_with_matches`: the usual flags, spelled out — case-insensitive, the lines that do *not* match, whole words only, a count per file, names only.
196
- - `context`: lines shown either side of a match. `max_count`: stop after this many per file. Line numbers are included unless you set `line_numbers: false`.
216
+ - `ignore_case`, `invert`, `word`, `count`, `files_with_matches`: the usual flags, spelled out. They give, in order: case-insensitive matching, the lines that do *not* match, whole words only, a count per file, and file names only.
217
+ - `context`: lines shown either side of a match. `max_count`: stop after this many matches per file. Line numbers are included unless you set `line_numbers: false`.
197
218
 
198
- What it is for: grep's own semantics on a known file or directory — every matching line rather than one per file, a count, an inverted match, a window of context, a pattern you already have in POSIX form. What `search_codebase` is for: sweeping the whole repository with several independent patterns at once to find *which* files mention something. Reach for that first when you do not yet know where to look, and for this when you do. Neither is for questions about a symbol — `ask_lsp` answers those exactly.
219
+ What it is for: grep's own semantics on a known file or directory. That means every matching line rather than one per file, a count, an inverted match, a window of context, or a pattern you already have in POSIX form. It is cheaper than reading whole files to find where something is before you read or edit it. `search_codebase` is for sweeping the whole repository with several independent patterns at once to find *which* files mention something. Reach for that when you don't yet know where to look, and for this when you do. Neither is for questions about a symbol; `ask_lsp` answers those exactly.
199
220
 
200
- This runs in-process. It is not the `grep` binary and does not go through `run_commands`, so it needs nothing installed and behaves the same on every platform; running `grep` or `rg` through the shell instead is the thing to avoid.
221
+ This runs in-process. It is not the `grep` binary and does not go through `run_commands`, so it needs nothing installed and behaves the same on every platform. Running `grep` or `rg` through the shell instead is the thing to avoid.
201
222
 
202
- Output: a single `{query, result, success, error?}`. `query` is `grep:<pattern>`; `result` is the matching lines, each prefixed with its path and line number, with context lines separated by `-` and matches by `:`. A pattern that matched nothing returns `success: true` and says so in words — that is an answer, and re-running it will not change it. Reading a file's lines here counts as having read them.
223
+ Output: one result, named `grep:` followed by the pattern. It holds the matching lines, each prefixed with its path and line number. Context lines are marked with `-` and matching lines with `:`. A pattern that matched nothing has not failed, and the result says so in words. That is an answer, and re-running the same search will not change it. A search that could not run says it failed and why. The lines a match shows you count as lines you have read, for `editor` and `sed`.
203
224
 
204
225
  # tool: awk
226
+
205
227
  Runs an `awk` program over one or more files, in this process.
206
228
 
207
- {"program": "NR>1 {sum += $2} END {print sum}", "files": ["data.csv"], "field_separator": ","}
229
+ {"program": "NR>1 {sum += $2} END {print sum}", "files": ["/abs/data/usage.csv"], "field_separator": ","}
208
230
 
209
- - `program`: the awk program. `{print $1}`, `$3 ~ /error/ {print FILENAME, NR, $0}`, a `BEGIN`/`END` pair — all of it.
231
+ - `program`: the awk program, in full. That can be `{print $1}`, `$3 ~ /error/ {print FILENAME, NR, $0}`, or a `BEGIN`/`END` pair.
210
232
  - `files`: optional. A program with only a `BEGIN` block needs none.
211
- - `field_separator`: `-F`. `variables`: `-v name=value`, as an object.
233
+ - `field_separator`: this is `-F`. `variables`: this is `-v name=value`, given as an object such as `{"limit": "10"}`.
234
+
235
+ What it is for: questions about columns and totals, where a search would find the lines but leave the counting to you. Examples are summing a column, pulling fields out of a delimited file, counting occurrences per key, or reducing a report to the two numbers you actually wanted.
212
236
 
213
- What it is for: questions about columns and totals, where a search would only find the lines and leave you counting them yourself — summing a column, pulling fields out of a delimited file, counting occurrences per key, reshaping a report into the two numbers you actually wanted.
237
+ It cannot write, and that is on purpose. Output redirection, pipes, `system()` and `getline` are refused, not quietly ignored. Use `sed` or `editor` to change a file.
214
238
 
215
- It cannot write, and that is deliberate rather than incidental: output redirection, pipes, `system()` and `getline` are refused rather than quietly ignored. Use `sed` or `editor` to change a file.
239
+ It runs in-process, not through the shell. It needs no `awk` binary installed and behaves the same on every platform. Running `awk` through `run_commands` instead is the thing to avoid.
216
240
 
217
- Output: a single `{query, result, success, error?}`. `query` is `awk:<program>`; `result` is everything the program printed. A program that printed nothing still returns `success: true` — that is the program's answer, not a failure.
241
+ Output: one result, named `awk:` followed by the program, holding everything the program printed. A program that could not run says it failed and why. A program that printed nothing has not failed: that is the program's answer.
218
242
 
219
243
  # tool: extract_document
220
244
  {{DEFAULT}}
221
245
 
222
246
  # tool: fetch_web_content
223
- Fetches web pages — documentation, API references, changelogs — and extracts from each what you ask for.
247
+
248
+ Fetches web pages, such as documentation, API references or changelogs, and pulls out of each one what you ask for.
224
249
 
225
250
  {"requests": [{"url": "https://example.com/docs/config", "prompt": "List every option under `server` with its default value"}]}
226
251
 
227
- - `requests`: an array. Each entry pairs a `url` with a `prompt`. A bare `{url, prompt}` outside the array is rejected.
228
- - `prompt`: what to pull out of that page. You get the answer to this prompt back, not the page, so ask for the specific thing you need.
252
+ - `requests`: an array with one entry per page. Each entry pairs a `url` with a `prompt`. A bare `{url, prompt}` outside the array is rejected.
253
+ - `prompt`: what to pull out of that page. You get back the answer to this prompt, not the page, so ask for the specific thing you need.
229
254
 
230
- Fetch independent URLs in one call, next to any other independent calls in the same response.
255
+ Fetch independent URLs in one call, alongside any other independent calls in the same response.
231
256
 
232
- Output: one object per request, shaped `{query, result, success, error?}`. `query` is the URL; `result` is the text extracted for your prompt. A page that could not be fetched has `success: false` with the reason in `error`.
257
+ Output: one entry per request, in the order sent, each named by its URL. An entry holds the text extracted from that page for your prompt. A page that could not be fetched says it failed and why, and the other entries are unaffected.
233
258
 
234
259
  # tool: editor
235
- Changes or creates one text file. Use this, never the shell, for anything that writes a file: `sed -i`, `echo >`, `cat > f <<EOF` and `Set-Content` tell you nothing about what they changed.
236
260
 
237
- Which arguments you send decides what the call does. Use one form per call; don't mix `old_text` with a line range.
261
+ Changes or creates one text file. Use this, never the shell, for anything that writes a file. `sed -i`, `echo >`, `cat > f <<EOF` and `Set-Content` tell you nothing about what they changed.
238
262
 
239
- Write the arguments in this order: `path` and every other short argument first — line and column numbers, `intent`, `task_progress`, `old_text` — and `new_text` last. The text you are writing is the long part of the call, and whatever is written after a long text is the part most easily left out.
263
+ The arguments you send decide what the call does. Use one form per call, and don't mix `old_text` with a line range.
240
264
 
241
- 1. Replace text: `path`, `old_text`, `new_text`. `old_text` must match exactly, whitespace and indentation included. If it occurs more than once, add `occurrence` (one-based, in file order) to pick one, or `replace_all: true` for all of them.
242
- 2. Replace lines: `path`, `start_line`, `new_text`, optional `end_line` (inclusive, defaults to `start_line`). Best where the text is long, minified or repeated, because a line number cannot be ambiguous. An empty `new_text` deletes the range.
243
- 3. Replace characters: `path`, `start_line`, `start_column`, `new_text`, optional `end_line`/`end_column` (inclusive, each defaulting to its start). This is the unit a diagnostic speaks in — `line 108, column 385` — and on a minified line it is the only form that leaves the other 400 characters alone. `start_column` alone replaces exactly one character.
244
- 4. Insert lines: `path`, `insert_line`, `new_text`. The text goes in before that line and nothing is replaced. `insert_line` = line count + 1 appends at end of file.
245
- 5. Insert within a line: `path`, `insert_line`, `insert_column`, `new_text`. The text goes in before the character at that column — this is how you add one missing bracket. `insert_column` = line length + 1 appends at end of line.
246
- 6. Create, or overwrite whole: `path` and `new_text` only. Creates the file if absent; if present, replaces all of it, which is allowed only once you have read it, since reading is what tells you what you are discarding. (`start_line: 1` with `end_line: <last line>` is the same write.) No size limit. Reach for it only after a targeted edit has failed — a whole-file rewrite that is slightly off silently loses the parts you never meant to touch. Never delete a file to get a clean slate: this form already is one, and a deleted file stays gone if the turn ends before you write it back.
265
+ Write the arguments in this order: `file_path` and every other short argument first (line and column numbers, `intent`, `task_progress`, `old_text`), then `new_text` last. The text you are writing is the long part of the call, and whatever comes after a long text is the part most easily left out.
247
266
 
248
- {"path": "/abs/src/app.ts", "old_text": "const retries = 3;", "new_text": "const retries = 5;"}
249
- {"path": "/abs/src/app.ts", "start_line": 40, "end_line": 44, "new_text": " return cached;\n"}
250
- {"path": "/abs/game.js", "insert_line": 108, "insert_column": 385, "new_text": ")"}
267
+ 1. Replace text: `file_path`, `old_text`, `new_text`. `old_text` must match exactly, including whitespace and indentation. If it occurs more than once, add `occurrence` (one-based, in file order) to pick one, or `replace_all: true` to change all of them.
268
+ 2. Replace lines: `file_path`, `start_line`, `new_text`, and optionally `end_line` (inclusive, defaults to `start_line`). This form is best where the text is long, minified or repeated, because a line number cannot be ambiguous. An empty `new_text` deletes the range.
269
+ 3. Replace characters: `file_path`, `start_line`, `start_column`, `new_text`, and optionally `end_line` and `end_column` (inclusive, each defaulting to its start). This is the unit a diagnostic speaks in, as in `line 12, column 640`. On a minified line it is the only form that leaves the other 400 characters alone. `start_column` on its own replaces exactly one character.
270
+ 4. Insert lines: `file_path`, `insert_line`, `new_text`. The text goes in before that line and nothing is replaced. Setting `insert_line` to the line count + 1 appends at the end of the file.
271
+ 5. Insert within a line: `file_path`, `insert_line`, `insert_column`, `new_text`. The text goes in before the character at that column, which is how you add one missing bracket. Setting `insert_column` to the line length + 1 appends at the end of the line.
272
+ 6. Create, or overwrite whole: `file_path` and `new_text` only. This creates the file if it is absent. If it exists, it replaces all of it, which is allowed only once you have read the file, because reading is what tells you what you are discarding. (`start_line: 1` with `end_line` set to the last line is the same write.) There is no size limit. Use this form only after a targeted edit has failed, because a whole-file rewrite that is slightly off silently loses the parts you never meant to touch. Never delete a file to get a clean slate. This form already gives you one, and a deleted file stays gone if the turn ends before you write it back.
273
+
274
+ {"file_path": "/abs/src/app.ts", "old_text": "const retries = 3;", "new_text": "const retries = 5;"}
275
+ {"file_path": "/abs/src/app.ts", "start_line": 40, "end_line": 44, "new_text": " return cached;\n"}
276
+ {"file_path": "/abs/src/app.ts", "insert_line": 12, "insert_column": 640, "new_text": "]"}
251
277
 
252
278
  Rules the tool enforces:
253
- - An edit addressed by line number (forms 2–5) must fall inside lines you have read. An edit that changes the file's line count invalidates those reads, because every line below it moved. For the next edit to that file, either use `old_text` (form 1 only needs the file read at some point) or read the region again. Line numbers from an earlier turn, from a task summary, or from a diagnostic issued before your last edit go stale the same way.
254
- - `new_text` replaces the range, it is not added to it — but repeating the lines already there and then continuing is how you insert after them, and that is allowed: the range names the lines you mean. What is refused is going on to repeat lines from *outside* the range, which would duplicate text already elsewhere in the file; the refusal names the lines it matched.
255
- - Text copied out of `read_files` must not carry the ` 92 | ` gutter. When copying, read with `line_numbers: false`.
279
+ - An edit addressed by line number (forms 2–5) must fall inside lines you have read in their current state. An edit that changes the file's line count invalidates those reads, because every line below it has moved. For the next edit to that file, either use `old_text` (form 1 only needs the file to have been read at some point) or read the region again. Line numbers from an earlier turn, from a task summary, or from a diagnostic issued before your last edit go stale the same way.
280
+ - `new_text` replaces the range; it is not added to it. You may repeat the lines already in the range and then continue, which is how you insert after them, because the range names the lines you mean. What is refused is going on to repeat lines from *outside* the range. That would add a second copy of text already elsewhere in the file, and the refusal names the lines it matched so you can aim the next call at them.
281
+ - Text copied out of `read_files` must not carry the ` 92 | ` line-number gutter. When you read in order to copy, read with `line_numbers: false`.
256
282
 
257
- One edit, then its check, then the next. Where two edits to the same file are genuinely unavoidable in one step, use `old_text` for both, since the first one to change the line count moves the lines the other points at.
283
+ One edit, then its check, then the next. If two edits to the same file in one step are genuinely unavoidable, use `old_text` for both. Otherwise the first one to change the line count moves the lines the other points at.
258
284
 
259
- Output: one `{query, result, success, error?}` object for this edit. `query` is `edit:<path>` or `insert:<path>`; `result` describes what changed, and that is your confirmation — do not read the file back to see it. A failed edit changed nothing: `success` is false, the file is exactly as it was, and `error` names the fix. Don't resend the same call; change what `error` points at.
285
+ Output: one result for this edit, named `edit:` or `insert:` followed by the path, describing what changed. That description is your confirmation, so don't read the file back to see it. A failed edit changes nothing: the result says it failed and why, and the file is exactly as it was. Don't resend the same call. The reason names the fix, so change what it points at.
260
286
 
261
- Once the edit lands, call `check_file` on the file before starting the next change.
287
+ Once the edit lands, call `check_file` on the file before you start the next change.
262
288
 
263
289
  # tool: sed
264
- Applies a `sed` script to one or more files, in this process. The third way to change a file, alongside `editor` and `apply_patch`.
265
290
 
266
- {"script": "s/oldName/newName/g", "files": ["src/a.ts", "src/b.ts"], "in_place": true}
291
+ Applies a `sed` script to one or more files, in this process. It is the third way to change a file, alongside `editor` and `apply_patch`.
292
+
293
+ {"script": "s/oldName/newName/g", "files": ["/abs/src/a.ts", "/abs/src/b.ts"], "in_place": true}
267
294
 
268
- - `script`: the sed program — `s/foo/bar/g`, `/^debug/d`, `2,5s/^/# /`. Several commands go in one script, separated by newlines or `;`. Addresses and `s///` patterns are **basic** regular expressions unless you pass `extended: true`.
269
- - `files`: what to run it over.
270
- - `in_place`: omit it and the call only prints what the script would produce, which is how you check a script before trusting it. Set it to `true` and each file is rewritten.
295
+ - `script`: the sed program, such as `s/foo/bar/g`, `/^debug/d` or `2,5s/^/# /`. Several commands go in one script, separated by newlines or `;`. Addresses and `s///` patterns are **basic** regular expressions unless you pass `extended: true`.
296
+ - `files`: the files to run it over.
297
+ - `in_place`: if you omit it, the call only prints what the script would produce, which is how you check a script before trusting it. Set it to `true` to rewrite each file.
271
298
  - `quiet`: print only what the script itself prints, as `sed -n` does.
272
299
 
273
- What it is for: one mechanical change that applies in many places, or across many files — renaming an identifier everywhere, stripping a prefix from every line of a block. What `editor` is for: a single considered change to one place. It can anchor on text you quote back and it tells you when the file has moved under you; a script cannot, and a script that matches more than you meant changes more than you meant. Preview first.
300
+ What it is for: one mechanical change that applies in many places, or across many files, such as renaming an identifier everywhere or stripping a prefix from every line of a block. `editor` is for a single considered change to one place. It can anchor on text you quote back, and it tells you when the file has moved under you. A script can do neither, and a script that matches more than you meant changes more than you meant. Preview first.
274
301
 
275
- The same rule as `editor` applies, for the same reason: an in-place run is refused on a file you have not read, and a script addressed by line number is refused unless you have read those lines. Read first. In plan mode `in_place` is refused outright, exactly as `sed -i` through the shell is; the preview still works.
302
+ The same rule as `editor` applies, for the same reason. An in-place run is refused on a file you have not read, and a script addressed by line number is refused unless you have read those lines. Read first. In plan mode `in_place` is refused outright, just as `sed -i` through the shell is, but the preview still works.
276
303
 
277
- Output: one object per file, shaped `{query, result, success, error?}`. `query` is `sed:<file>`; `result` is that file's output, or a sentence saying what was written. The files do not share a fate — one can be written while the next is refused — so read every entry. `success: false` means that file was **not** touched and `error` says why. A script that matched nothing is `success: true`: it ran, and that is its answer.
304
+ It runs in-process, not through the shell. It needs no `sed` binary installed and behaves the same on every platform.
305
+
306
+ Output: one entry per file, in the order given, each named `sed:` followed by the file. An entry holds that file's output, or a sentence saying what was written. The files don't share a fate: one can be written while the next is refused, so read every entry. A failed entry says why, and that file was **not** touched. A script that matched nothing has not failed. It ran, that is its answer, and running it again unchanged will not change it.
278
307
 
279
308
  # tool: apply_patch
309
+
280
310
  Applies one patch that adds, updates, moves or deletes files. Use it when a single change spans several files, or when a new file arrives alongside edits to existing ones. For one change to one file, `editor` is simpler.
281
311
 
282
- Call shape: `{"input": "<the whole patch as one string>"}`. Send the patch body itself; legacy wrappers such as `%%bash` or `apply_patch <<"EOF"` are still accepted but not preferred.
312
+ The argument is a single string, `input`, holding the whole patch: `{"input": "*** Begin Patch\n...\n*** End Patch"}`. Send the patch body itself. Legacy shell wrappers such as `%%bash` or `apply_patch <<"EOF"` are still accepted but not preferred.
283
313
 
284
314
  Grammar: the patch opens with `*** Begin Patch` and closes with `*** End Patch`. Between them each file gets one header:
285
- - `*** Add File: <path>` — followed by the new content, every line prefixed `+`.
286
- - `*** Update File: <path>` — followed by hunks: unchanged context lines start with a space, removed lines with `-`, added lines with `+`.
287
- - `*** Move to: <new path>` — only immediately after an `*** Update File:` header, to rename that file.
288
- - `*** Delete File: <path>` — no body.
315
+ - `*** Add File: <path>`, followed by the new content with every line prefixed `+`.
316
+ - `*** Update File: <path>`, followed by hunks: unchanged context lines start with a space, removed lines with `-`, added lines with `+`.
317
+ - `*** Move to: <new path>`, only immediately after an `*** Update File:` header, to rename that file.
318
+ - `*** Delete File: <path>`, with no body.
289
319
 
290
- Hunks are located by context, never by line number. Give enough unchanged lines around each change to pin it down, and where the same block appears more than once put an `@@` marker line before the hunk, optionally carrying nearby context such as the enclosing signature.
320
+ Hunks are located by context, never by line number, so don't write line numbers anywhere in a patch. Give enough unchanged lines around each change to pin it down. Where the same block appears more than once, put an `@@` marker line before the hunk, optionally followed by nearby context such as the enclosing signature.
291
321
 
292
322
  *** Begin Patch
293
323
  *** Update File: src/config.ts
@@ -300,7 +330,7 @@ Hunks are located by context, never by line number. Give enough unchanged lines
300
330
  +export const DEFAULTS = { retries: 3 };
301
331
  *** End Patch
302
332
 
303
- Output: one `{query, result, success, error?}` object for the whole patch. `result` lists the files added, updated, moved or deleted, and that is your confirmation — don't read those files back. A patch that did not apply, usually because its context lines no longer match, sets `success: false` and says so in `error`; read the region as it stands now and rebuild the patch from that, since resending the same text fails the same way. After it lands, call `check_file` on the files it touched before making the next change.
333
+ Output: one result for the whole patch, listing the files it added, updated, moved or deleted. That list is your confirmation, so don't read those files back. If the patch did not apply, usually because its context lines no longer match the file, the result says it failed and why. Read the region as it is now and rebuild the patch from that. Resending the same text fails the same way. After it lands, call `check_file` on the files it touched before you make the next change.
304
334
 
305
335
  # tool: ask_question
306
336
  Ask only when an answer that only the user has would change what you build. Don't use it to confirm a choice you can make yourself, or to report progress. Their reply arrives as text — act on it in the same turn.
@@ -313,24 +343,26 @@ Call this once the assigned work is finished and checked. `verified` states what
313
343
  {{DEFAULT}}
314
344
 
315
345
  # tool: run_commands
316
- Runs shell commands: builds, test suites, running the program you changed, installing dependencies, git. That is what it is for — the work no dedicated tool does.
346
+
347
+ Runs shell commands: builds, test suites, running the program you changed, installing dependencies, git. That is the work no dedicated tool does, and it is what this tool is for.
317
348
 
318
349
  It is not for files. Each of these has a tool that reports whether it worked:
319
350
  - reading a file (`cat`, `head`, `tail`, `type`, `Get-Content`) → `read_files`
320
351
  - searching for text (`grep`, `rg`, `findstr`, `Select-String`) → `search_codebase`, or the `grep` tool
352
+ - totalling or picking out columns (`awk`, `cut`, `wc`) → the `awk` tool
321
353
  - listing what exists (`ls`, `dir`, `find`, `Get-ChildItem`) → `list_files`
322
354
  - writing or changing a file (`sed -i`, `echo >`, `cat > f <<EOF`, `tee`, `Set-Content`, a one-off script that rewrites a file) → `editor`, `apply_patch` for a change across several files, or the `sed` tool
323
355
  - finding where a name is defined, or what uses it → `ask_lsp`
324
356
  - asking whether one file type-checks or lints clean (`tsc`, `eslint`, `biome`, `ruff`, `mypy`, `go build`, `cargo check`) → `check_file`, which answers from the language servers in milliseconds without building the project. Run the checker here only when you need a project-wide answer, or when no language server covers the file.
325
357
 
326
- When to run: when a change needs the code executed to settle whether it was right, and once more after every planned change is in place — not after each edit, which is what `check_file` is for. Put `check_file` on the changed files in the same response as the run. The run says *that* it fails and where; the checker says *which line* to change.
358
+ When to run: when a change needs the code executed to settle whether it was right, and once more after every planned change is in place. Don't run after each edit; that is what `check_file` is for. Put `check_file` on the changed files in the same response as the run. The run says *that* it fails and where, and the checker says *which line* to change.
327
359
 
328
360
  {"commands": ["npm run build", "npm test -- src/parser.test.ts"]}
329
361
 
330
- - `commands`: an array of complete, non-interactive command strings. Independent commands go in one call and may run concurrently; commands that depend on each other belong in a single string joined with the shell's sequencing operator (see below).
331
- - `credentials`: optional, an array of names of QA credentials the user has configured, for a command that needs one but does not name it itself — a test runner reading its environment, say. The values are set for that call only and are never shown to you. If none are configured, leave it out.
362
+ - `commands`: an array of complete, non-interactive command strings. Independent commands go in one call and may run concurrently. Commands that depend on each other belong in a single string, joined with the shell's sequencing operator (see below).
363
+ - `credentials`: optional, an array of names of QA credentials the user has configured. Use it for a command that needs a credential but does not name it itself, such as a test runner that reads its environment. The values are set for that call only and are never shown to you. If none are configured, leave it out.
332
364
 
333
- Output: one object per command, shaped `{query, result, success, error?}`. `query` is the command; `result` is its combined stdout and stderr. A non-zero exit sets `success: false` and describes the exit in `error`, but `result` still holds everything the command printed — the compiler error or the failing test is in there, so read it before doing anything else.
365
+ Output: one entry per command, in the order sent, each named by the command. An entry holds everything the command printed, stdout and stderr together. A command that exits non-zero is reported as failed with its exit described, but the entry still holds all its output. The compiler error or the failing test is in there, so read it before doing anything else.
334
366
 
335
367
  {{DEFAULT}}
336
368
 
@@ -340,25 +372,26 @@ Runs an installed skill: a packaged procedure for a task this machine already kn
340
372
  {{DEFAULT}}
341
373
 
342
374
  # tool: check_file
343
- Returns the language servers' diagnostics for the files you name. This is the linter, the type checker, the syntax check and the Problems panel — whichever word the question uses, this answers it. Results are live and follow your edits: each answer is current as of the moment you ask. If a problem is still listed after an edit, it is still there. There is nothing to restart.
375
+
376
+ Returns the language servers' diagnostics for the files you name. This is the linter, the type checker, the syntax check and the Problems panel. Whichever of those words the question uses, this tool answers it. Results are live and follow your edits, so each answer is current as of the moment you ask. If a problem is still listed after an edit, it is still there. You cannot restart a language server from here, and you don't need to.
344
377
 
345
378
  {"paths": ["/abs/src/parser.ts", "/abs/src/lexer.ts"]}
346
379
 
347
380
  - `paths`: absolute paths. Put every file you want checked into one call.
348
381
 
349
- Where a language server covers the file, this answers what `tsc`, `eslint`, `biome`, `ruff`, `mypy`, `go build` or `cargo check` would answer, for just these files, in milliseconds, without building anything. Ask it before reaching for one of those through `run_commands`.
382
+ Where a language server covers the file, this answers the same question as `tsc`, `eslint`, `biome`, `ruff`, `mypy`, `go build` or `cargo check`. It does so for just these files, in milliseconds, without building anything. Ask it before you reach for one of those through `run_commands`.
350
383
 
351
384
  When to call it:
352
- - After each edit lands, on the file touched, before you begin the next edit. This is the cheap check between one change and the next.
353
- - At the end, in the same response as the run — `run_commands` for the build, the tests or the program, or `browser` for a page. The run tells you *that* something broke; this tells you *which line*. Calling only one leaves the other half to guesswork.
354
- - Whenever you are asked about errors, warnings, lint or problems — "is it clean now?", "what is still broken?". A report from an earlier edit is out of date; ask again.
385
+ - After each edit lands, on the file you touched, before you begin the next edit. This is the cheap check between one change and the next.
386
+ - At the end, on every file you changed, in the same response as the run: `run_commands` for the build, the tests or the program, or `browser` for a page. The run tells you *that* something broke, and this tells you *which line*. If you call only one, the other half is left to guesswork.
387
+ - Whenever you are asked about errors, warnings, lint or problems, as in "is it clean now?" or "what is still broken?". You have no other way to know. A report from before your last edit is out of date, so ask again.
355
388
  - On a file you are about to change, when you want to know what was already wrong with it.
356
389
 
357
- Output: plain text, one section per file you named, each problem on its own line as `file:line:column` with its severity and message. A clean file says so in one line. There is no object to unpack and no `success` field — problems being listed is this tool working, not failing.
390
+ Output: plain text with one section per file you named. Each problem is on its own line as `file:line:column` with its severity and message. A clean file says so in one line. A list of problems means the tool worked, not that it failed.
358
391
 
359
- `Delimiter scan`: where a file's brackets don't balance, this section names the line to edit and how many brackets that line is out by, one line per place the trouble starts, since a file can be broken in several spots at once. A parse error is always reported where the parser gave up, which is a closing bracket; the scan names the line the parse error cannot. Work through every line it lists before re-checking rather than re-checking after each one. Don't recount brackets to check it: the scan skips strings, comments and regex literals and hand-counting does not, so where your count and the scan disagree, your count is wrong. If you doubt it, make the edit and run the code — that settles it faster than any recount. The scan runs even when the editor reported nothing, so it can appear under a file called clean; for script inside an `.html` file it is the only report you get.
392
+ `Delimiter scan`: where a file's brackets don't balance, this section names the line to edit and how many brackets that line is out by. It gives one line per place the trouble starts, because a file can be broken in several spots at once. A parse error is always reported where the parser gave up, which is a closing bracket. The scan names the line that the parse error cannot. Work through every line it lists before you re-check, rather than re-checking after each one. Don't recount brackets to check it. The scan skips strings, comments and regex literals and hand-counting does not, so where your count and the scan disagree, your count is wrong. If you doubt the scan, make the edit and run the code, which settles it faster than any recount. The scan runs even when the language server reported nothing, so it can appear under a file called clean. For script inside an `.html` file it is the only report you get.
360
393
 
361
- A clean result is conclusive only where a language server covers that file, and that is not every language on every machine. If it reports nothing and you have reason to expect a problem, or the project has a checker the language servers don't run, run that checker through `run_commands`. Tests and builds always go through `run_commands`; this tool does not run them.
394
+ A clean result is conclusive only where a language server covers that file, and that is not every language on every machine. Run the project's checker through `run_commands` in two cases: this tool reports nothing but you have reason to expect a problem, or the project has a checker the language servers don't run. Tests and builds always go through `run_commands`, because this tool does not run them.
362
395
 
363
396
  # tool: list_files
364
397
  Use this, not `ls`, `dir`, `find` or `Get-ChildItem` through `run_commands`, whenever you need to know which files exist — it is scoped to the workspace and they are not. `max_results` caps the entries returned: 200 by default, 1000 at most; if a pattern hits the cap, narrow it. A directory listing puts directories first with a trailing `/`, and gives each file's size, which tells you whether reading it whole is reasonable. This says which files exist, not what is in them — to find files by content use `search_codebase`, which reports the line worth reading around.