Releases: DFKHelper/token-goat
Release list
v2.6.1 — replace breaks the Read-deny/Edit deadlock
A new token-goat replace command closes a systemic trap where token-goat's own pre-read denials could permanently block Claude Code's Edit tool on a file for the rest of a session, plus a background-indexer staleness fix and multi-range sed hint support.
Highlights
token-goat replace <file>bypasses the Read/Edit precondition entirely. Several of token-goat's ownpre_readdenials (re-reads of markdown/source files, large-file caps, truncated-file re-reads) leave no way to ever successfully Read a file again this session — permanently blocking Edit on it too, reproduced live across multiple projects. The new command edits a file directly via Node fs (--old-from/--new-fromor--old-b64/--new-b64, plus--all), and all six of the deny messages that actually cause this now point at it.- Fixed a silent index-staleness bug shared by
write-fileandreplace. Neither ever told the background worker a file had changed, so edits through either command left the symbol index stale until a manualtoken-goat index. A new fail-softenqueueDirtyPathSafehelper now wires all four write paths into the dirty-reindex queue. sed -nhints now cover every range in a multi-range command (sed -n '24,28p;65,84p' file), not just the first.
Full details: CHANGELOG.md.
v2.6.0 — Correctness and security pass
A correctness-and-security pass across nearly the whole codebase: the indexer's crash-safety, three SSRF gaps, two TOCTOU races, and a session-cache format bug that was quietly corrupting compact-hint/context-stats output all get fixed, alongside dozens of smaller fixes to the CLI, hooks, and language parsers.
Highlights
- Indexer crash-safety. The dirty-queue drain, parser SHA/scoping, and embeddings upsert all had silent-data-loss paths on a crash or transient error mid-batch — the core symbol pipeline is now durable under interruption.
- Session-cache format bug fixed.
compact-hint/context-stats/cache sessionwere reading the old Python-era dict shape against the realFileEntry[]array format, rendering garbage (- 0,- 1) instead of actual file paths for any real session. compact-docfully wired end to end. The extractive-sidecar pipeline the README already documented had no callers;--force/--sentences/--show,pre_readsidecar serving, andpost_editstaleness marking are now all live.- Three SSRF gaps closed, two TOCTOU races closed. IPv6 private-range matching, DNS-rebinding via the unresolved-fallback path, and a redirect-depth cap in
config_commands.ts; plus lock-free read-modify-write races inpack.ts's symlink validation andskill_cache.ts's hit counter. - Several CLI commands were unreachable or silently degraded.
context-statswas never registered,statsbypassed most of its own options,section --listwas rejected outright, and a dozen numeric flags (--limit,--depth,--budget, ...) silently producedNaNon bad input instead of erroring. - Cross-agent read deduplication. Opt-in: a sibling Claude Code session gets a hint when another session already read the same file, instead of everyone independently paying full price.
- Broad language-parser correctness fixes across PowerShell, Kotlin, C#, PHP, and the shared string/comment scanner — mostly brace-depth and scope-tracking edge cases that could desync symbol extraction for the rest of a file.
- Windows drive-letter paths resolved incorrectly on non-Windows hosts. Two path-resolution helpers gated their Windows-specific handling on
process.platformbut still called the ambient, host-nativepath.resolve()— invisible on a real Windows machine, where that resolver already behaves win32-style, but wrong on Linux (CI), where aC:/...path got treated as relative and corrupted. Fixed to usepath.win32.resolve()explicitly, and guarded with tests that assert on which resolver is called so a regression is caught locally on Windows too, not just in CI.
Full details: CHANGELOG.md.
v2.5.0 — every documented command, now real
A documentation-driven release: every command the README promised now actually exists, with a guard that fails CI the moment docs and code drift again.
Highlights
- 44 documented-but-missing commands wired and tested. A doc audit found the README documenting commands the CLI never registered (skill lifecycle, code-graph analysis, text/file utilities, cache/session/config ops). All are now implemented with coverage, and a README-table-driven registration guard plus a built-bundle command matrix keep the doc/code contract from silently breaking again.
- Skill compact lifecycle is observable end to end.
skill-compact --all,skill-history,skill-diff,skill-section, andskill-listgainscompact_stale/hit_count/age.installpre-generates compacts; a read hook flags a stale compact at read time. - Windows/PowerShell read surface.
Get-Contentwrapped inpowershell -Command/pwsh -cnow gets the same surgical-read hint as a bare read, size-gated on temp paths. - Cross-process MCP caching. Read-only
mcp__*results persist across hook processes and recall instead of re-fetching. - Fewer round-trips. A one-time
gh pr/issue viewfield-batching advisory,git push/ghread-view output caching, andrefs "a,b,c"merged multi-symbol references. - Subagent transcripts.
bash-output --file --transcriptreads a subagent.outputJSONL as assistant text; same-session skill re-loads are denied with a compact-recall pointer.
Full details: CHANGELOG.md.
v2.4.0 — line-range reads (file@N-M)
Added
- Line-range reads in
token-goat read(file@N-M).read "file.ts@10-40"returns lines 10 to 40 inclusive, andread "file.ts@42"returns a single line. Ranges read straight from disk with no index lookup, so they work on any file, including paths outside every indexed project, restoring parity with the Python build (whose@N-Msyntax the TS port had not carried over). An end past EOF clamps to the last line; an inverted range or a start below 1 is a clear error; a trailing newline is not counted as an extra line.
See src/read_commands.ts; regression-tested in tests/read_commands.test.ts.
Full changelog: https://github.com/DFKHelper/token-goat/blob/v2.4.0/CHANGELOG.md
v2.3.0 — PowerShell support, semantic search fix, compression port complete
Highlights
PowerShell & Windows read support. Symbol indexing now covers PowerShell .ps1/.psm1 — top-level functions, filters, classes, enums, and class methods — so symbol, read, skeleton, and outline work on PowerShell scripts. The whole-file-read hints now match bat, type, and PowerShell Get-Content/gc (previously documented but wired only for cat), and Get-Content <path> -Tail N and Get-Content <path> | Select-Object -First N get the same surgical-read nudges as tail and head.
Semantic search fixed. token-goat semantic now actually returns results: the missing sqlite-vec dependency is declared and the vec0 rowid bind is corrected. Pruning, reindexing, and surgical reads no longer break on platforms without the sqlite-vec binary, and path lookups match case-insensitively on Windows/macOS.
Bash-output compression port completed. Batches B through K land the full 158-filter set — package managers, linters / type-checkers / formatters, git, build tools, containers / Kubernetes, cloud / IaC, CI / security scanners, AI-CLI streaming assistants, shell / file utilities, language runtimes / compilers, and DB / runner utilities.
Language adapter fixes. C# (namespace indexed as a namespace, modifier-less methods), PHP (code sharing a line with a block comment, top-level declarations after a class), Kotlin (top-level const val / val), Rust and Go (function-local declarations no longer leak as top-level symbols), TS/JS (destructuring binds each identifier individually), Makefile (::= / :::= no longer mis-indexed as targets), and .env (export -prefixed keys).
WebFetch recall. Repeated fetches of the same URL are recalled from cache instead of re-fetched.
Full details, including every fix and the per-batch compression list: CHANGELOG.md at v2.3.0
v2.2.4
Correctness and compression release.
Session recall now survives the hook process boundary
token-goat's hooks run as a fresh process per tool call, but the entire session-recall layer lived in process-local memory that died with each process, so re-read dedup and bash-output / web-output recall never fired across calls in the shipped binary. Three on-disk layers under ~/.token-goat (per-session state plus content-addressed bash/web blobs) restore the behavior, with merge-on-save, atomic writes, and age/count pruning. WebFetch responses are now actually cached for cross-process recall.
Bash-output compression, wired and filling in
The pre-bash command-rewrite mechanism is reconnected end to end, so build and test commands are compressed automatically (opt out with TOKEN_GOAT_BASH_COMPRESS=0). The first structured per-tool filters land: Jest/Vitest (a shared Node test-runner family) and pytest / go test (bespoke runners). The remaining per-tool filters port in follow-up batches.
Other fixes
token-goat config-getreturns the value from the requested section, not the first matchtruncateLineno longer overshootsmaxLineLength- the reindex queue deduplicates paths case-insensitively on Windows/macOS
- flat section ranges never end before they start
index --walkindexes a non-git folder- task-output recall hints name a working
--filecommand trimToBudgetno longer slices mid-ANSI-escape- skill compact cache filenames are colon-free and consistent across store/get/list
Full details: CHANGELOG.md
v2.2.3
2.2.3 — the surgical-read pipeline, reconnected
This is a significant correctness release. The migration off the original Python implementation to TypeScript left several core components unwired in the shipped binary while the unit test suite stayed green:
- The background indexer wrote nothing. The worker drained its dirty queue into a stub, so the
symbolstable was never populated and the real parser was tree-shaken out of the bundle — every surgical read (symbol,read,skeleton,outline,semantic) returned an empty index. refsreturned[]and its command was never registered on the CLI.semanticalways reported "no matches" because its FTS query aliased the virtual table (no such column: f, silently swallowed by acatch).token-goat index .produced an unqueryable index — it stored relative path keys no reader could match.exports,imports,find,grep, andweb-outputwere implemented but never wired into the CLI (exports/importswere also non-functional as written).config-getignored its file argument and read token-goat's own config instead.
All of these are fixed, and every surgical-read and index-backed command is now reconnected end to end.
To stop this class of failure from recurring, two structural guards were added, both driven off a single command registry so new commands are covered automatically:
- a data-driven CLI registration guard that runs in a fast (~2s, no-I/O) pre-commit tier, so an implemented-but-unregistered or unfunctional command fails before the commit lands; and
- a built-bundle command matrix that indexes a fixture and runs every registered command against the shipped
dist/token-goat.mjsat pre-push and in CI — a command broken or unreachable in the shipped artifact now fails the build.
Also in this release: serve_diff_on_reread now covers source, style, and data files (not just docs); YAML/TOML kebab-case keys are indexed; read resolves 3+ part dotted symbols to the leaf; and the architecture reference was rewritten for the TypeScript codebase.
Full details: CHANGELOG.md
v2.2.2
[2.2.2] - 2026-06-27
Added
- PowerShell system-query recall.
Get-CimInstance,Get-Process,Get-Counter,Get-Service,Get-PSDrive, andGet-WmiObjectcommands run viapowershell.exe/pwshare now registered as monitoring commands. Output is cached after the first run and atoken-goat bash-output <id> --tail 50recall hint is emitted on repeats. token-goat section/outline/symbolrepeat recall. Running the sametoken-goat section "FILE::Heading",outline FILE, orsymbol NAMEcommand a second time in a session now emits a bash-output recall hint instead of re-executing.
v2.2.1
v2.2.0
See CHANGELOG.md for full details.
Highlights
- Count-based hard-deny for repeated source file reads — 3rd+ read of the same source file is hard-blocked; use
token-goat read,skeleton, oroutlineinstead - Identifier grep on a single file →
token-goat symbolhint viaextractRgSymbolSearch - Section heading normalization — em/en-dashes, trailing parens, numeric prefixes all handled; full heading list shown on miss
- Markdown heading grep →
token-goat outlinehint viaextractMarkdownHeadingGrep - Session artifact re-read dedup —
tasks/*.outputandtool-results/*.txtdiff-or-deny - Python heredoc reads now caught by
extractPythonFileRead - SQL cat hooks, curl GET cache, curl -o dedup, cat JSON|jq, node require(), CSS/SCSS/LESS cat, find → fd, eza --tree/tree/ls -R → map, grep|grep chain, doc-file diff-on-reread, .md re-read denial, git diff compression
- Security hardening, Windows mkdirSync race fix, multiple CLI and embedding fixes
- 180+ filter & interception rules (was 160+)