You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
v0.52.0 — Tool fallback elimination + edge case test coverage
Eliminates the shell-fallback feedback loop: all 15 perf tool descriptions
now say 'Zero-fork — pure Go' instead of 'Replaces shell: cat, grep, bc...'
which told the LLM exactly what shell command to use when tools failed.
Fixes:
- batch_patch: continue-on-error (was early-stop on first failure)
- math_eval: added modulo (%) operator (most common fallback trigger)
- diff: OOM guard (rejects files >10K lines before LCS allocation)
- browser_tool: honest description (no-JS limitation noted)
- read_file: points to base64/checksum instead of shell for binaries
Tests: 57 new edge-case tests across all 15 perf tools +
isBinary, http_batch. Every tool now has minimal edge coverage:
math_eval(7), diff(3), count_lines(4), multi_grep(2), json_query(5),
checksum(3), sort(2), base64(5), tr(5), word_count(3), tree(2),
batch_patch(3), head_tail(2), glob(1), isBinary(5), http_batch(1)
click — Follow a link or interact with an element by ref ID
82
82
back — Return to the previous page in navigation history
83
83
84
+
Note: Uses regex-based HTML parsing with NO JavaScript execution. Best for server-rendered HTML pages. SPAs and JS-heavy sites may return limited content.
85
+
84
86
Use browser_navigate(url) first, then browser_snapshot() to see interactive
85
87
elements with their ref IDs (e.g. @e1, @e2), then browser_click(ref) to
func (t*diffTool) Description() string { return`Compare two files and return structured hunks. Each hunk has a type (equal/added/removed) and line-by-line content. Use path_a+path_b for file-vs-file, or path+content for file-vs-string. Replaces shell: diff fork.` }
651
+
func (t*diffTool) Description() string { return`Compare two files and return structured hunks. Each hunk has a type (equal/added/removed) and line-by-line content. Use path_a+path_b for file-vs-file, or path+content for file-vs-string. Zero-fork LCS-based diff — no subprocess spawned.` }
func (t*countLinesTool) Description() string { return`Count lines, bytes, and characters in one or more files. Streaming scanner — zero-alloc on content. Replaces shell: wc -l, wc -c, wc -m forks.` }
838
+
func (t*countLinesTool) Description() string { return`Count lines, bytes, and characters in one or more files. Streaming scanner — zero-alloc on content, zero subprocess forks. Per-file and aggregate totals.` }
func (t*jsonQueryTool) Description() string { return`Parse a JSON file and extract a value using a dot-path query. Supports array indexing with [N]. Empty query returns the entire parsed JSON. Replaces shell: jq, python -c "import json" forks.` }
1152
+
func (t*jsonQueryTool) Description() string { return`Parse a JSON file and extract a value using a dot-path query. Supports array indexing with [N]. Empty query returns the entire parsed JSON. Zero-fork — pure Go JSON traversal.` }
1156
1153
1157
1154
typejsonQueryArgsstruct {
1158
1155
Pathstring`json:"path"`
@@ -1293,7 +1290,7 @@ type treeTool struct {
1293
1290
}
1294
1291
1295
1292
func (t*treeTool) Name() string { return"tree" }
1296
-
func (t*treeTool) Description() string { return`List the directory tree with file counts, sizes, and nesting. Returns a structured tree: each entry shows path, is_dir, file_count, total_size, children, depth. Replaces shell: find, tree, ls -R forks.` }
1293
+
func (t*treeTool) Description() string { return`List the directory tree with file counts, sizes, and nesting. Returns a structured tree: each entry shows path, is_dir, file_count, total_size, children, depth. Zero-fork — pure Go directory walk.` }
func (t*checksumTool) Description() string { return`Compute cryptographic hashes of files using SHA-256 (default), SHA-1, or MD5. Uses Go crypto stdlib — zero subprocess fork. Replaces shell: sha256sum, sha1sum, md5sum forks.` }
1424
+
func (t*checksumTool) Description() string { return`Compute cryptographic hashes of files using SHA-256 (default), SHA-1, or MD5. Uses Go crypto stdlib — zero subprocess fork, pure Go implementation.` }
1428
1425
1429
1426
typechecksumFileArgstruct {
1430
1427
Pathstring`json:"path"`
@@ -1555,7 +1552,7 @@ type sortTool struct {
1555
1552
}
1556
1553
1557
1554
func (t*sortTool) Name() string { return"sort" }
1558
-
func (t*sortTool) Description() string { return`Sort lines in one or more files. Supports ascending (default), descending, unique (dedup), numeric, case-insensitive, and reverse. For multiple files, results are merged. Replaces shell: sort, sort -u, sort -n forks.` }
1555
+
func (t*sortTool) Description() string { return`Sort lines in one or more files. Supports ascending (default), descending, unique (dedup), numeric, case-insensitive, and reverse. For multiple files, results are merged. Zero-fork — pure Go sort with no subprocess.` }
func (t*headTailTool) Description() string { return`Read the first or last N lines of one or more files. Streaming — stops after N lines (no full-file read for head). Supports multiple files in parallel. Replaces shell: head -n, tail -n forks.` }
1721
+
func (t*headTailTool) Description() string { return`Read the first or last N lines of one or more files. Streaming — stops after N lines (no full-file read for head). Supports multiple files in parallel. Zero-fork — pure Go scanner.` }
func (t*base64Tool) Description() string { return`Encode or decode base64. Supports file input (path) or inline string (content). Encode: file or string → base64. Decode: base64 string → decoded string. Replaces shell: base64 fork. Use path for file, content for inline string, decode=true to decode.` }
1875
+
func (t*base64Tool) Description() string { return`Encode or decode base64. Supports file input (path) or inline string (content). Encode: file or string → base64. Decode: base64 string → decoded string. Zero-fork — pure Go encoding. Use path for file, content for inline string, decode=true to decode.` }
1879
1876
1880
1877
typebase64Argsstruct {
1881
1878
Pathstring`json:"path,omitempty"`
@@ -1963,7 +1960,7 @@ type trTool struct {
1963
1960
}
1964
1961
1965
1962
func (t*trTool) Name() string { return"tr" }
1966
-
func (t*trTool) Description() string { return`Transform text: case conversion, character replacement, string substitution, character deletion. Operates on a file or inline content. Replaces shell: tr, sed (simple substitutions) forks.` }
1963
+
func (t*trTool) Description() string { return`Transform text: case conversion, character replacement, string substitution, character deletion. Operates on a file or inline content. Zero-fork — pure Go strings transformations.` }
1967
1964
1968
1965
typetrTransformstruct {
1969
1966
Fromstring`json:"from,omitempty"`// for char/string replacement
func (t*wordCountTool) Description() string { return`Count words, lines, and characters in one or more files. Streaming scanner — no full-content load. Returns per-file and aggregate totals. Replaces shell: wc fork.` }
2096
+
func (t*wordCountTool) Description() string { return`Count words, lines, and characters in one or more files. Streaming scanner — no full-content load. Returns per-file and aggregate totals. Zero-fork — pure Go scanner.` }
0 commit comments