Skip to content

Releases: DFKHelper/token-goat

v0.7.0

21 May 01:47

Choose a tag to compare

Minor release: new context-saving features (Grep output compression, a session orientation brief, bash loop detection) plus a round of worker, database, and compaction fixes.

Added

  • Grep output compression. Large grep/rg/ag/ack results (>30 lines) are compressed to a file-level summary: top 20 files by match count, totals included, full output cached for token-goat bash-output recall. Typical savings: ~80%.

  • Bash loop-detection escalation. The same command run twice triggers a "ran 2×" escalation; three or more repeats produce a "WARNING: ran N×" advisory. Stops runaway loops from burning context unnoticed.

  • Session-wide hint deduplication. Identical hints are suppressed after their first injection within a session. SHA-256 fingerprinting with a JSON-persisted hints_seen set means the agent never gets nagged twice for the same file.

  • Session orientation brief. At session start in a dirty git repository, a compact block (~50 tokens) is injected: current branch, modified/staged/untracked counts, and the five most-recent commits. Disable via TOKEN_GOAT_SESSION_BRIEF=0 or [session_brief] enabled = false in config.toml.

  • Adaptive PreCompact manifest budget. The manifest budget scales from 200 to 600 tokens based on edit count, symbol accesses, and bash activity. Sessions with little activity get a lean manifest; complex ones get the full picture.

  • Git diff --stat in PreCompact manifest. A git diff --stat HEAD summary (capped at 8 lines / 200 chars) is now included in the compaction manifest. The compaction LLM always sees which files drifted from the last commit, even when the session cache doesn't list them as edited.

  • Symbol names in re-read hints. Re-read hints now include up to three symbol names previously accessed in the flagged file (e.g., [symbols: login, get_user, Session]), so the agent can decide whether token-goat read file::symbol is sufficient.

  • Error-preserving smart truncation. When bash output exceeds the size cap, the trimmed view keeps: first 10 lines + up to 10 error-signal lines with 2-line context + last 10 lines, separated by --- N lines omitted ---. Errors are never lost to truncation.

  • Loaded version in token-goat stats. The stats report now shows the running token-goat package version: a header line in the ANSI renderer (token-goat v0.6.1), the version in the rich fallback renderer's panel title, and a top-level version field in --json output. Confirms at a glance which build produced the numbers.

Fixed

  • Git-history indexing batches its writes in one transaction. _index_history_inner inserted up to 200 commit rows on an autocommit connection (isolation_level=None), so every INSERT committed on its own and the trailing conn.commit() was a no-op: 200 separate fsyncs and 200 writer-lock acquisitions per reindex sweep. The batch now runs inside a single BEGIN/COMMIT, acquiring the lock and committing once. The last_indexed_at staleness marker is also written only when at least one commit stored, so a batch that wholly failed (for example, a database that stayed locked throughout) no longer stamps itself "indexed" and suppresses the retry for an hour.

  • project_writer_lock acquisition is now atomic. _try_acquire checked lock_path.exists() and then write_text — a check-then-write with a TOCTOU window: two callers that both observed the file absent each wrote the lock and each believed it held it, so two index_project runs could write the same per-project database concurrently. Acquisition is now a single os.open(O_CREAT | O_EXCL) create — the atomic-mutex pattern the worker slot claim already uses — and _stale falls back to the lock file's mtime so the brief create-then-write window can't be misread as a dead lock.

  • Git-history indexing moved to the background worker. The SessionStart hook spawned git_history.index_project_history on a daemon=True thread inside the hook process, which exits within milliseconds — killing the thread before the indexing finished. Git-history hints are now refreshed by the worker's periodic reindex sweep, which runs in a durable process; index_project_history is idempotent and staleness-gated (1 h), so the move adds no measurable cost.

  • Worker claim-slot no longer wedges on a write failure. If os.write failed after _try_claim_worker_slot created the claim file, the file descriptor leaked and an empty claim file was left on disk. _worker_claim_is_stale treats an empty claim as not-stale (to protect the create-then-write window), so that orphan could never be reclaimed and the single-worker slot stayed blocked. The fd is now closed and the empty file removed on a write failure. Separately, run_daemon wrapped its claim-file cleanup in a finally whose try began only after _write_pid / _register_autostart / cleanup_on_startup, so an exception in any of those skipped the cleanup — the try now covers all startup work.

  • Session-start git brief is capped by one shared deadline. _build_session_brief ran three git subprocesses (rev-parse, status, log) sequentially, each with a fixed 2 s timeout, so a slow or pathological repository could stack a ~6 s pause onto session start. The three calls now share a single ~2.5 s wall-clock budget, and a call is skipped once the budget is spent.

  • A deferred dirty-queue drain no longer slows re-indexing. On Windows a concurrent enqueue_dirty can hold dirty.txt open, making os.replace fail with a sharing violation; drain_dirty_queue retries and then defers. It returned [] for that case — indistinguishable from a genuinely empty queue — so the worker counted a deferred drain as an idle cycle and let adaptive back-off drift re-indexing toward its 10 s maximum while edits piled up. drain_dirty_queue now returns None on a deferral, and the worker resets the idle counter instead of incrementing it.

  • token-goat doctor no longer integrity-checks the production database. The stats summary opened global.db through the read-write path, which runs PRAGMA integrity_check on connect — multi-second on a large global.db, and it created the database file as a side effect when one did not exist yet. The summary now reads through open_global_readonly(), so doctor stays fast regardless of database size and never mutates the database it is diagnosing.

  • token-goat stats breakdown rows now rank by share. The "By kind", "By day", and "By project" tables emitted rows in byte-sorted order while the share column they display is token-derived, so the share percentage zig-zagged whenever bytes and tokens ranked rows differently (an image-heavy day saves bytes but ~0 tokens). Each section renderer now orders its rows by the same share metric it displays — "By source" already did this.

  • Unbounded global.db WAL growth. Every hook writes stat rows to global.db, and under a heavy multi-agent burst its passive autocheckpoints were perpetually blocked by overlapping readers, so the write-ahead-log file only ever grew — one session reached an 11 GB global.db-wal, after which every hook (including the SessionStart hook that runs on /compact) stalled for minutes scanning it. Connections now set PRAGMA journal_size_limit so the WAL file is truncated after each checkpoint, and the worker force-runs a wal_checkpoint(TRUNCATE) on global.db every maintenance cycle. A tests/test_wal_growth_guard.py regression suite, wired into the pre-commit hook, locks both halves of the fix in place.

  • Temp files and automation artifacts excluded from PreCompact manifest. Paths under /tmp/, Windows %APPDATA%, .improve-state-*.json, and improve_commit_msg_* are filtered before the manifest renders. Previously they leaked into "Files Edited" and wasted manifest budget on entries the compaction LLM couldn't use.

v0.6.1

20 May 01:51

Choose a tag to compare

Patch release: token-savings tuning, output-cache DRY refactor, and stat-accounting fixes.

Changed

  • Token-savings tuning across the hint, compaction, and output surfaces. Three internal improvement sweeps tightened the text Token-Goat injects into the conversation: shorter session read-hints and bash / grep / web dedup hints, leaner PreCompact manifest framing, a more compact post-compaction recovery hint, terser token-goat map output framing, and budgeted git-history and project-memory injections. The CLAUDE.md / SKILL.md / AGENTS.md directive blocks written by token-goat install were condensed without dropping any guidance. The result is the same hints for fewer tokens.
  • Command --json output is now compact single-line JSON. stats, map, config, bash-output, web-output, bash-history, web-history, compact-hint, and the surgical-read commands emit --json with no indentation whitespace. JSON written to disk (settings.json and config files) stays pretty-printed for human editing.
  • bash-output and web-output recall now default to a smart head-and-tail view for large cached outputs, with --full to retrieve the whole thing.
  • DRY pass on the output-cache layer. bash_cache and web_cache were near-parallel implementations; their shared pieces (the cache-filename pattern, session-id sanitization, JSON-sidecar loading, and LRU disk-cap eviction) now live in one cache_common module. No user-visible behavior change. Regression tests were added across the token-savings, stat-accounting, and cache surfaces.

Fixed

  • compact_recovery stat accounting. The post-compaction recovery hint recorded no injection overhead and was bucketed under the other source instead of compact. It now records a compact_recovery_overhead row consistent with the session_hint, diff_hint, and bash_dedup_hint siblings, and both compact_recovery kinds map to the compact source bucket.
  • bash-output and web-output recalls were credited no savings. Retrieving a cached output instead of re-running a command, or a cached response instead of re-fetching a URL, now records a bash_output_recall or web_output_recall stat. This closes a measurement gap where thousands of cache hits showed zero tokens saved.

v0.6.0

19 May 16:59

Choose a tag to compare

See CHANGELOG.md for the full release notes.

Highlights

Added: Bash output compression with 12 per-tool filters, WebFetch result cache, Bash output interception with bash-output/bash-history CLI, diff-aware re-read after Write/Edit/MultiEdit, structured section extraction for TOML/YAML/JSON/INI/CFG/dotenv/Dockerfile, post-compaction recovery hint, Grep dedup hint, doctor cache visibility panel, symbol close-match auto-redirect (--strict opt-out), bash and web stats buckets, hardened PostToolUse Bash payload extraction.

Changed: Internal DRY pass across install, languages, bridges, hooks, and CLI surfaces (routing-table SSOT, languages/common config-file helpers, openclaw/opencode bridge unification, Typer option constants). README 'Updating' subsection consolidating upgrade paths.

Fixed: paths.open_log_file now returns a real FileHandler subclass on POSIX; drive-letter canonicalisation tests skip on non-Windows; latent winreg handle leak when SetValueEx/DeleteValue raised.

v0.5.2

17 May 22:45

Choose a tag to compare

Fixed

token-goat read no longer crashes on unindexed projects. The "Did you mean?" suggestion paths shipped in 0.5.0 caught sqlite3.OperationalError and sqlite3.DatabaseError but not FileNotFoundError. db.open_project_readonly raises FileNotFoundError when the per-project DB has not been created yet — typical right after a fresh install or when find_in_all_projects resolves a cross-project file in an unindexed sibling. The miss message now always emits; the suggestion list is best-effort polish and degrades silently.

Changed

  • Top-level CLI description and PyPI long-description now list all four supported harnesses (Claude Code, Codex CLI, opencode, openclaw) and drop the implementation-detail hook-based phrasing.

See CHANGELOG.md.

v0.5.1

17 May 22:34

Choose a tag to compare

Highlights

Docs audit follow-up to v0.5.0. Six fixes, two of them real bugs:

  • token-goat --version / -V now works. SECURITY.md instructed reporters to include the output of this command, but the flag did not exist and the command errored out. The security reporting flow was effectively broken.
  • map --compact help string now says 300 tokens, matching the code constant. Iteration 17 raised the threshold from 200 to 300 but missed the help text.

Plus four doc-only consistency fixes: the shipped routing tables in ~/.claude/CLAUDE.md, the token-goat skill, and ~/.codex/AGENTS.md now mention every 0.5.0 surface (qualified Class.method, Heading#N, map --compact, gdrive-sections, --max-distance, --no-rerank, "Did you mean?"); gdrive-sections is no longer hidden in --help; read / section argument help documents the qualified-lookup and ordinal syntax inline; and the config sub-Typer panel now has a description.

See CHANGELOG.md for the full entry.

v0.5.0

17 May 21:30

Choose a tag to compare

Highlights

WebP image-shrink default — ~39% smaller than the previous JPEG output on screenshots, ~97% smaller than raw PNG. Anthropic's Vision API natively supports image/webp.

Install-time image-codec probe. token-goat install now records image codecs: ok|FAIL as a normal install step and, when WebP/JPEG/PNG support is incomplete, prints a banner-delimited warning with platform-specific install hints (apt-get / dnf / pacman / apk / brew). AI agents driving the install can resolve the gap as part of the same task instead of discovering it months later.

30 token-savings iterations. DB reindex ~80x faster (84 s -> ~1 s for 100 files), hook dispatch ~65% faster (~86 ms -> ~30 ms), repomap output ~30-40% denser, real-LRU image cache, lockfile-guarded eviction, cross-shell project-hash unification (WSL/Cygwin/Git Bash now share the index with Windows), lockfile/minified-bundle/sourcemap exclude defaults, parser SHA-keyed result LRU, per-session result cache, webfetch content-hash dedup, smarter hint suppression.

New CLI surface. install --dry-run, install --verify, map --compact, semantic --max-distance, semantic --no-rerank, gdrive-sections, qualified Class.method reads, Heading#N section ordinals, "Did you mean?" miss suggestions.

Regression benchmark suite locks in the measured wins so future refactors cannot silently regress them.

See the full 0.5.0 entry in CHANGELOG.md for the complete list.

v0.4.0

17 May 19:13

Choose a tag to compare

Full Changelog: v0.3.2...v0.4.0

v0.3.2

16 May 19:52

Choose a tag to compare

What's new

  • opencode supporttoken-goat install --opencode drops a TypeScript bridge plugin into opencode's plugins directory. Image shrinking, post-edit indexing, and compact assist work.
  • openclaw supporttoken-goat install --openclaw drops a TypeScript bridge plugin into ~/.openclaw/plugins/ and registers it in openclaw.json. Image shrinking, post-edit indexing, and pre-fetch denial work.
  • Security hardening: settings.json type validation, project marker resolution, stdin/file payload caps, session symbol coercion, Drive download limit.
  • Performance: hot-path improvements in embeddings, parser, session, image_shrink, hooks, and db.
  • Observability: session timing, embed search metrics, install step logging, db slow-open warning, compact and gdrive metrics.
  • Type safety: replaced broad Any annotations with concrete types across repomap, worker, stats, and stats_renderer.
  • 150+ new tests covering repomap, compact, hints, bridges, session, webfetch, gdrive OAuth, and language adapters.

v0.3.1

16 May 06:12
ef9ebd6

Choose a tag to compare

What's new

Added

  • Linux and WSL support. Worker registers as a systemd --user service when available, with an XDG autostart .desktop fallback. On WSL without systemd the SessionStart hook starts the worker per session. Data directory: ~/.local/share/token-goat/.
  • macOS support (untested). Worker registers as a LaunchAgent at ~/Library/LaunchAgents/com.dfkhelper.token-goat-worker.plist. Data directory: ~/Library/Application Support/dfk-helper/token-goat/.
  • PyPI Trusted Publishing. Publish workflow uses OIDC — no long-lived API tokens stored as repo secrets.
  • README What gets installed? and Security, privacy, and uninstall sections — every file, hook, autostart entry, scheduled task, and data path the installer writes, and how each is reversed.
  • README badges for PyPI version and CI status.
  • Lefthook git hooks for local lint and test parity with CI.

Changed

  • Data directory namespace renamed from DFK Helper LLC to dfk-helper for cross-platform path hygiene. A reinstall recreates the index at the new path; the old directory can be removed by hand.
  • CI slimmed to Python 3.13 on Windows. The package still declares support for 3.11–3.13.
  • README rewritten with a before/after comparison table and stat callouts.

Fixed

  • Python 3.13 null-byte path handling updated in paths.py and tests.
  • Three Windows-runner CI test failures resolved (temp-dir project detection, CRLF in markdown parser, null-byte guard).
  • token-goat stats bar-scale and share-% now use separate denominators so a single dominant kind no longer flattens the rest of the chart.

Security

  • Input validation hardened in paths.py — no rel-path can escape the data directory under any caller.

Removed

  • Legacy tokenwise launcher binaries removed during install/uninstall.