Releases: DFKHelper/token-goat
v2.0.0 — TypeScript rewrite
Complete Python→TypeScript migration. All modules ported to TypeScript; Python source removed; package promoted from packages/token-goat-ts/ to project root. Now published to npm instead of PyPI.
Install: npm install -g token-goat
See CHANGELOG.md for the full change history.
v1.9.9
See CHANGELOG.md for details.
v1.9.7
See CHANGELOG.md for details.
v1.9.6
See CHANGELOG.md for details.
v1.9.5
v1.9.4
Added
-
token-goat tokens [patterns]— per-file token footprint table. Scans matched files and prints each file's token estimate alongside its line count, sorted largest-first by default.--treegroups results by directory with per-directory subtotals and percentages of the total.--top Nlimits the view to the N largest files.--ascreverses the sort order.--jsonemits a structured object withtotal_tokens,total_files, and afilesarray.--no-ignorebypasses.tokengoatignore. Omit patterns to scan the entire project. -
token-goat note set/get/unset/list/clear— persistent per-project notes. Stores short key-value facts in a per-project TOML file. Token-goat injects them into the context at session start and after compaction so they survive conversation rollover without being repeated in the chat history. Keys are alphanumeric with hyphens and underscores (max 80 chars).note list --jsonfor machine-readable output;note clearwipes all notes at once. -
token-goat pack --strip-comments— strip comments before packing. Removes language-appropriate comments from source files before bundling. Covers Python#line comments, JS/TS/Go/Rust/Java/C/C++ line and block comments, SQL--comments, Ruby/shell hash comments, and CSS/SCSS block comments. Shebangs (#!) are preserved. Cuts token count on comment-heavy codebases; language detection is extension-based with no extra install. -
token-goat pack --scan-secrets— check for credentials before emit. Scans packed files for patterns matching AWS access and secret keys, GitHub tokens, private key PEM blocks, Stripe and OpenAI keys, Slack webhook URLs, Google API keys, database connection strings, bearer tokens, and password literals. Exits 2 and prints per-file, per-line warnings when any pattern fires; a clean pack exits normally. Binary and image extensions are skipped automatically. -
token-goat call-chain <symbol>— trace the full call path to a symbol. Walks the call graph upward from symbol and prints each transitive caller layer, from immediate callers out to entry points. Pairs withcallers(one hop) andimpact(downstream direction). -
token-goat hot [--limit N] [--project dir]— cross-session file frequency ranking. Tallies read and edit counts from all stored sessions and ranks files by total activity. Useful for identifying which files dominate token spend across your whole history, not just the current conversation.--jsonfor structured output;--projectto filter to a specific project directory. -
token-goat impact <symbol>— downstream blast-radius estimate before a refactor. Walks the reference graph forward from symbol and lists every file and function that directly or transitively depends on it, with the hop depth and dependency type (call, type annotation, or import). Run it before changing a function signature to see what breaks without starting a build. -
token-goat context-for <task>— minimal context bundle for a task. Takes a natural-language task description, runs semantic search across the indexed codebase, and emits a prioritized list oftoken-goat readcommands trimmed to a token budget. Fetches only the slices relevant to the task instead of loading entire files.--budget Nsets the token ceiling;--top Nlimits the file count;--jsonfor structured output. -
token-goat dead— surface symbols with no known callers. Queries the project index for functions, methods, async functions, and classes that have no recorded call-site references. Private symbols (names starting with_) and common entry-point names (main,app,create_app, etc.) are excluded from results by default.--include-privatelifts the underscore filter;--kindnarrows to specific symbol types;--top Ncaps the list;--jsonfor structured output. Results are heuristic leads: dynamic dispatch and external callers are not visible to static indexing. -
token-goat coverage-gaps— find callables not referenced by any test file. Scans indexed functions and methods in non-test source files for names that never appear in a test file's reference records. Dunder and private names are excluded.--top Nlimits the list;--jsonfor structured output. Useful for spotting untested surface area before a refactor or release; results should be read as leads, not verdicts. -
token-goat pack --budget N— fail the pack if it would exceed a token budget. Exits with code 3 when the estimated token count of the collected files exceeds N, so a shell script or CI step can treat an oversized context as an error rather than silently passing it to the model.--budget 0(the default) imposes no limit. -
token-goat skeleton— file line count in the output header. The skeleton header now shows total line count alongside symbol count:# Skeleton: src/token_goat/cli.py (80 symbols, 9,394 lines). Gives an immediate size gauge before deciding whether to read a file in chunks or in full. -
Injection detector — three new patterns.
forget-instructionscatches "forget [all] [your] previous instructions/directives/guidelines" (requires "previous" to avoid false positives on documentation phrases like "forget to include instructions from step 1").pretend-no-restrictionscatches roleplay jailbreak framing ("pretend you have no restrictions/limitations/constraints"; requires "you have no" to skip game-design prose).exfil-conversationcatches attempts to extract the full conversation or chat history ("print the entire chat history", "dump the message history"); requires "the" before the noun so code comments and variable references do not fire. -
Large-file read hints — skeleton suggestion for files with many indexed symbols. When the read hint fires and more than three symbols are indexed for the file, the hint now shows the total symbol count and suggests
token-goat skeleton "file"before opening a specific one. Previously the overflow appeared as...with no count and no browse path. The skeleton command in the hint is quoted to handle paths with spaces.
Performance
pre_readhook now uses a read-only DB connection for symbol lookup._get_indexed_symbols_and_line_countwas opening a write-capable connection (db.open_project()) that loads the sqlite-vec extension, sets WAL mode, and runs schema DDL on every call. Switching todb.open_project_readonly()eliminates those steps, cutting the function from ~9.8 ms to ~1.4 ms. Every Read tool call passes throughpre_read, so the saving applies to every hook invocation. Fail-soft behavior is unchanged.
Fixed
-
Stale
.jsonlsession sidecars now get cleaned up. The cleanup pass only matched files ending in.json, so.jsonlsidecars piled up and were never removed. The suffix filter now covers both extensions. -
Writer lock no longer leaves an empty lock file behind. When the
os.writeafter anO_EXCLcreate failed, the freshly created lock file was orphaned on disk. The failure path now deletes it. -
Skeleton brace-skipper counts braces inside literals correctly. A
}or{inside a string, comment, or backtick template literal was counted as a real brace, which leaked body lines into the skeleton. Those contexts are now skipped, and regex literals are handled, too. -
Embedding dimension validation runs for custom models. The check that the model's vector width matches the stored index was skipped for any non-default model. It now runs regardless of which model is configured.
-
A closing
---in YAML front matter is no longer read as a heading. The front-matter terminator was parsed as a setext H2 heading, which invented a phantom section. Markdown parsing now recognizes the fence. -
MCP server name is read consistently in the transcript tool tally. The tally pulled the server name from two different places, so one server could show up under more than one label. Extraction is now uniform.
-
WSL path normalization drops the doubled slash. Normalizing a Windows drive path produced a redundant slash after the drive letter, such as
/mnt/c//foo. The extra slash is gone. -
Combined
--headand--tailrecall returns both ends. Passing--headand--tailtogether returned only the head slice. Recall now returns the head and the tail. -
compact-hint --diffignores timestamp-only changes. A manifest whose only difference was a refreshed# as-of:timestamp was reported as a real change. The diff now treats a timestamp-only tick as no change.
v1.9.3
What's new
Added
- **** — show which functions call a given symbol, grouped by caller with file, caller name, and every invocation line. Complements
refsby showing the call chain rather than raw usage lines. - **** — per-project exclusion file at project root. Add gitignore-style glob patterns (one per line,
#comments supported) to skip files and directories from indexing on top of built-in skip lists. Runtoken-goat ignoresto see what's active. token-goat semantic --mode keyword|hybrid— two new search modes.--mode keywordruns BM25 keyword search with no embedding model required.--mode hybridcombines BM25 and vector rankings via reciprocal rank fusion, useful when a query has distinctive terms that pure semantic search would drift past. The default (--mode vector) is unchanged.token-goat arch— project-wide import graph summary: hub modules sorted by inbound import count, entry-point files nothing imports, and circular import chains. Derived from the existing index with no extra indexing step.token-goat pack <patterns>— bundle files into a single LLM-ready output in Markdown (default), XML, or plain text, with a manifest table of per-file line and token counts. Supports--line-numbers,--instruction-file,--output, and--no-ignore. Reads file paths from stdin when no patterns are given.token-goat budget <patterns>— token-cost estimate for a file set, sorted by cost descending.--context <N>shows percentage of an N-thousand-token window. Run beforepackto decide what to include.token-goat todo [--kinds K] [--group file|kind]— scan indexed files for TODO-family markers (TODO, FIXME, HACK, XXX, NOTE). Groups by file by default;--group kindto group by marker type; markers in string literals are excluded.token-goat failures [src]— extract failing test blocks from test runner output. Parses pytest, Jest, Go, and Cargo output; passing tests and preamble are dropped. Reads stdin by default; pass a file path for saved output.--jsonfor structured output.token-goat trace [src]— condense Python tracebacks to project-owned frames. Strips library, stdlib, and virtualenv frames. Chained exceptions preserve their cause notes; bare exceptions without a message are handled.--keep N(default 5) caps the frame count.token-goat lockdeps [path]— summarize lock file dependencies as a compact table. Reads poetry.lock, uv.lock, requirements.txt, Pipfile.lock, package-lock.json, Cargo.lock, and yarn.lock. Returns direct dependencies only.token-goat logfold [src]— collapse consecutive duplicate log lines to[Nx]counts. Normalizes ISO timestamps, UUIDs, IPs, and short hex IDs before comparing so the same event logged with different values folds correctly.--tail N,--no-normalize,--json.
Fixed
- Path traversal bypass in
_is_system_path().bash_parser.pyappended..even at root of an absolute path, letting/../../etc/passwdslip past the system-path block. Now discards..at root.
v1.9.2
Changes
Changed
- Hook watchdog default reduced from 5000ms to 700ms; new
HOOKS_WATCHDOG_DEFAULT_MSconstant is the single source of truth across config, hooks_common, and tests.
Performance
- Surgical hint lookup (
_try_surgical_read_hint) is now memoized by path+mtime_ns, eliminating repeated DB queries for unchanged files. Cache key normalizes to lowercase on Windows to handle case-insensitive filesystem paths.
v1.9.0
[1.9.0] - 2026-06-16
Added
-
TerraformFilterextended:terraform showcompression and plan data-source detection.terraform showoutput now strips noise attributes (id, arn, timeouts, tags blocks) per resource block and appends a suppression note; only meaningful fields survive.terraform planunchanged-block detection now covers data-source read-during-apply blocks in addition to managed-resource no-op blocks. -
KubectlFilterextended: event grouping and describe compression.kubectl eventsoutput groups events byREASONwith a per-group count and a field-selector hint.kubectl describecollapses label and annotation blocks to line counts, preserves the Conditions table in full, and retains container resource (requests/limits) fields. -
NpmInstallFilterextended: warn collapsing and verbose line suppression.npm warnlines after the first 3 are collapsed to a suppression note. Verbose timing, sill, http, and verb lines are suppressed entirely. Braille spinner reify progress lines are stripped. -
Three-layer watchdog budget resolution.
_resolved_watchdog_ms()now readsconfig.load().hooks.watchdog_ms(default 5000 ms) when noTOKEN_GOAT_HOOK_WATCHDOG_MSenv var is set. Previously it fell straight through to the 2000 ms compile-time constant, ignoring whatever[hooks].watchdog_mswas set to. Resolution order: (1) env var, (2) project config baseline (process-level mtime-cached, oneos.stat()on the fast path), (3)_HOOK_WATCHDOG_MS = 2000 mscompile-time fallback. Values below the 100 ms floor are clamped regardless of layer. -
Reread-deny hint shows real indexed symbols.
_handle_reread_denynow queries the project DB for up to 8 non-import, non-variable symbols in the denied file and emits exacttoken-goat read "path::Symbol"commands in the hint instead of the static::SymbolNameplaceholder. The lookup usesfind_projectfrom the file path, so nocwdparameter is required. If the file is not indexed or the query fails, the hint falls back to the generic placeholder silently. -
_handle_doc_compactauto-spawnscompact-docin the background. When the section-map path fires for a large markdown file, it now launchescompact-doc <file>as a fire-and-forget subprocess so the compact sidecar is ready on the next read. A per-file session fingerprint (compact_doc_spawned:<path>) prevents re-spawning for the same file within a session. Iftoken-goatis not on PATH or the spawn fails, the hook continues normally.
Fixed
TerraformFilter._compress_terraform_inithead/tail fallback. Whenterraform initprogress lines (e.g.,Installing plugin N) did not match the provider-specific regex, all lines passed through unchanged. The method now applies head=5/tail=5 compression wheneverlen(non_empty) > 12after provider-line collapsing.
v1.8.0
What's New in 1.8.0
Added
- curl -v verbose compression —
post_bashdetectscurl -v/--verbosecommands and strips TLS handshake noise, redundant request/response headers, and progress meters; keeps the request line, status code,content-type, and body - jest/vitest verbose PASS-suite compression — collapses
PASS src/...blocks with all-green test lines into a single summary line - JUnit XML structured summary — parses
<testsuites>XML frompost_bashoutput and emits a compact pass/fail/skip count instead of raw XML - Task-output temp file redirect —
pre_readdetects Claude task-output files in%TEMP%/claude/...and transparently redirects totoken-goat bash-output - Minified JS/CSS grep elision —
post_bashtruncates grep/rg hits on minified files (.min.js,.min.css, bundled output) to avoid multi-MB lines flooding context - Compaction hint suppression — suppresses the redundant re-read hint that fired after every conversation compaction even when files hadn't changed
- go test -v compression — collapses passing
=== RUN/--- PASSblocks in verbose Go test output - make/cmake/ninja build compression — strips redundant compile command echoes while keeping warnings and errors
- Python traceback deduplication — collapses repeated identical tracebacks in test output to a single copy
- tsc output compression — suppresses TypeScript compiler progress lines, keeping only errors and the final summary