tok

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 12, 2026 License: MIT Imports: 11 Imported by: 0

README

tok

Go License CI Go Report Card

Cut LLM token costs by 60–90%. Compress prompts. Filter noisy output. Auto-rewrite commands. One binary, zero dependencies.


What tok Does

1. Compress Prompts (Saves Input Tokens)

You write verbose → tok compresses → AI receives less → fewer input tokens charged.

Before: "Hey, could you please help me figure out why this React
         component keeps re-rendering every time the props change?"
After:  "React component re-renders on prop change. Why?"

38 tokens → 9 tokens (76% saved)
2. Filter Output (Readability + Context Savings)

tok intercepts command output and removes noise. Filtered output is readable and saves tokens when piped back into AI.

$ tok npm test
# 200 lines → 3 lines: pass/fail + failures
3. Transparent Command Rewriting

Install the hook once. Every bash command from your AI agent is automatically rewritten:

Claude types:  git status
tok rewrites:  tok git status
Claude sees:   420 tokens → 84 tokens (80% saved)

Claude never knows. You don't type tok prefix. It just works.

4. Make Agents Talk Tersely

Install agent rules that make AI respond with ~75% fewer output tokens:

Normal:  "The reason your component re-renders is likely because..."
tok:     "New object ref each render. Wrap in useMemo."

Same fix. 75% less word.

Install

tok is distributed exclusively through Hawk. It is not available as a standalone package.

# Via Hawk CLI (the only supported distribution)
hawk tok --help

# Or install Hawk first
npm install -g hawk
hawk tok compress -mode full -input "your text here"

Quick Start

Step 1: Install for your AI agent
tok init -g                     # Claude Code, Copilot (default)
tok init -g --gemini            # Gemini CLI
tok init -g --codex             # Codex (OpenAI)
tok init --agent cursor         # Cursor
tok init --agent windsurf       # Windsurf
tok init --agent cline          # Cline / Roo Code
Step 2: Restart your AI tool
# Now every command is automatically filtered
git status    # → tok intercepts, Claude sees 80% less
npm test      # → tok intercepts, Claude sees 90% less
Step 3: Compress your prompts
tok compress -mode ultra -input "Please implement authentication"
# → "Implement auth."
Step 4: Check your savings
tok gain                        # Summary stats
tok gain --graph                # ASCII chart (30 days)
tok gain --history              # Recent commands
tok gain --daily                # Day-by-day
tok gain --format json          # JSON export
tok discover                    # Find missed savings
tok session                     # Adoption across sessions

Benchmarks

Measured on this repo via evals/bench.sh (raw vs tok compress --mode aggressive):

fixture raw bytes raw tokens tok bytes tok tokens saved
git log 2,873 718 298 74 89 %
git diff 385,051 96,262 1,117 279 99 %
ls -la 66,341 16,585 148 37 99 %
find .go 19,145 4,786 147 36 99 %

Reproduce: go build -o tok ./cmd/tok && TOK=./tok evals/bench.sh --no-rtk

Recent additions

Session 2026-04-20 closed the last gaps vs rtk 0.37.1 and caveman:

  • tok commit-msg — read staged diff, emit Conventional Commits subject. Rule-based, no LLM.
  • tok review-diff — scan diff, emit one-line review comments (🔴 bug / 🟡 risk / 🔵 nit). Rule-based, no LLM.
  • tok pr-review [--base|--pr] — batch review-diff across a whole PR, grouped by file.
  • tok md <file> — compress markdown/memory file in place with .original.md backup. New wenyan modes.
  • tok cheatsheet — one-shot reference card for shell users (modes and quickref are aliases).
  • tok hook mode {activate|track|status|set} — Go-native SessionStart + UserPromptSubmit hook bodies. Drop-in replacement for the Node.js scripts, same flag-file format.
  • Wenyan filter layer (internal/filter/wenyan.go) — classical-Chinese-inspired rule-based compression, callable from the main pipeline.
  • Release automationrelease-please workflow + Formula/tok.rb in-repo.
  • Skill bundlerscripts/build-skill.sh produces tok.skill zip for single-file distribution.
  • End-to-end harnesstests/e2e/ Docker-based scenario runner.

Features

Input Compression (6 Modes)
Mode Style Savings
lite Drop filler, keep grammar ~20%
full Drop articles, fragments OK ~40% (default)
ultra Telegraphic, abbreviations ~60%
wenyan-lite Classical Chinese light ~30%
wenyan Classical Chinese standard ~50%
wenyan-ultra Classical Chinese max ~70%
Output Filtering (31-Layer Pipeline)

Research-backed algorithms: entropy pruning, perplexity filtering, AST-aware compression, H2O heavy-hitter, attention sink preservation, semantic chunking, and 25+ more.

Transparent Command Rewriting

Install the hook → every bash command from your AI agent is auto-rewritten to use tok. Zero effort, 100% coverage.

# Hook intercepts and rewrites automatically:
git status  → tok git status    (2,000 → 400 tokens)
git diff    → tok git diff      (10,000 → 2,500 tokens)
npm test    → tok npm test      (25,000 → 2,500 tokens)
cargo test  → tok cargo test    (200+ lines → 20 lines)
Interactive TUI
tok tui                      # 12-section dashboard: Home, Sessions, Trends, Logs, ...
tok tui --theme colorblind   # Okabe-Ito palette for accessible color vision

Live refresh · command palette (:) · search (/) · drill-down · clipboard yank (y) · export (e). Full keybinding reference and architecture in docs/TUI.md.

Token Analytics
tok gain --graph

Token Savings (Last 30 Days)
┌────────────────────────────────────────────────────┐
│ Mon 12 ████████████████████████████ 82%            │
│ Tue 13 ██████████████████████████ 78%              │
│ Wed 14 ██████████████████████████████ 85%          │
└────────────────────────────────────────────────────┘
Total: 267K → 53K tokens (80.1% saved)
Memory File Compression
tok compress-memory CLAUDE.md
# CLAUDE.md          → compressed (AI reads this — fewer tokens)
# CLAUDE.original.md → human-readable (you edit this)
# Average: 46% fewer tokens per session
AI Agent Integration

One command installs terse mode for 12+ agents:

tok install-agents    # Install to all agent directories

Supports: Claude Code, Cursor, Windsurf, Cline, Copilot, Codex, Gemini CLI, Roo Code, Kilo Code, Antigravity, Continue, Cody, CodeWhisperer, Tabnine, Codeium.

100+ Built-in Commands

tok wraps common CLI tools with intelligent filtering:

Files:    ls  read  smart  find  grep  diff  tree  wc  du  df
Git:      git status  git log  git diff  git add  git commit  git push
GitHub:   gh pr list  gh issue list  gh run list
Tests:    jest  vitest  playwright  pytest  go test  cargo test  rspec
Build:    cargo build  go build  gradle  maven  next build  tsc
Lint:     eslint  ruff  golangci-lint  mypy  prettier  rubocop
Package:  npm  yarn  pnpm  pip  cargo  bundle  prisma
Cloud:    aws  docker  kubectl  helm  terraform
Data:     json  jq  curl  wget  deps  env  log

How It Works

Without tok:                              With tok + hook:

Claude  --git status-->  shell  -->  git   Claude  --git status-->  tok hook  -->  git
  ^                            |             ^          | filter         |
  |     ~2,000 tokens         |             |  ~400 tokens (auto)       |
  +---------------------------+             +---------------------------+

Four strategies per command type:

  1. Smart Filtering — removes noise (comments, whitespace, boilerplate)
  2. Grouping — aggregates similar items (files by dir, errors by type)
  3. Truncation — keeps relevant context, cuts redundancy
  4. Deduplication — collapses repeated lines with counts

Architecture

tok
├── cmd/tok/              CLI entry point (cobra)
├── internal/
│   ├── commands/         100+ command wrappers (20 categories)
│   ├── compressor/       Input compression engine (6 modes)
│   ├── filter/           Output pipeline (31 layers)
│   ├── output/           Centralized output abstraction
│   ├── tracking/         SQLite token usage database
│   └── hooks/            Transparent command rewriting
├── agents/               AI agent rules + auto-activation hooks
├── hooks/                Shell integration scripts
├── benchmarks/           Token savings benchmarks
└── evals/                Three-arm eval harness

Single binary, no runtime dependencies.


Configuration

# ~/.config/tok/config.toml
[core]
mode = "full"
auto_activate = true

[tracking]
database_path = "~/.local/share/tok/tracking.db"
Variable Default Purpose
TOK_CONFIG_DIR ~/.config/tok Config location
TOK_AUTO_ACTIVATE (empty) Auto-start on shell init
TOK_DEFAULT_MODE full Default compression
TOK_NO_REWRITE (empty) Disable command rewriting
TOK_NO_COLOR (empty) Disable colors

Shell Integration

# Install transparent command rewriting
tok init -g

# Add [TOK] badge to your prompt
tok hooks-install

# Generate completions
tok completion bash   > /etc/bash_completion.d/tok
tok completion zsh    > "${fpath[1]}/_tok"
tok completion fish   > ~/.config/fish/completions/tok.fish

# Generate man pages
tok man /usr/local/share/man/man1

Commands

Core:       doctor  status  gain  on  off  mode  layers  suggest
Input:      compress  terse  restore  compress-memory
Output:     git  npm  cargo  go  docker  kubectl  pytest  jest  ... (100+)
Analytics:  gain --graph  gain --history  gain --daily  discover  session
Agents:     install-agents  uninstall-agents  init  compress-memory
Hooks:      hooks-install  hooks-uninstall  tok-rewrite-hook
System:     completion  man  self-update  config  telemetry
Tools:      diff  explain  summary  json  merge  export
Tracking:   recall  undo  audit  trust  untrust

Benchmarks

Real token counts from the Claude API:

Task Normal tok Saved
Explain React re-render bug 1,180 159 87%
Fix auth middleware token expiry 704 121 83%
Set up PostgreSQL connection pool 2,347 380 84%
Debug PostgreSQL race condition 1,200 232 81%
Implement React error boundary 3,454 456 87%
Average 1,214 294 65%

Run benchmarks/run.sh to reproduce.


Contributing

git clone https://github.com/GrayCodeAI/tok.git && cd tok
make test && make build && make lint

See CONTRIBUTING.md.


License

MIT

Documentation

Overview

Package tok provides high-performance text compression for LLM context windows.

Usage:

compressed, stats := tok.Compress(text, tok.Aggressive)
compressed, stats := tok.Compress(text, tok.WithBudget(4000))

c := tok.NewCompressor(tok.Adaptive)
compressed, stats := c.Compress(text)

Index

Constants

View Source
const DefaultMinChunkSize = 250

DefaultMinChunkSize is the default minimum chunk size in tokens.

Variables

This section is empty.

Functions

func CompressJSON

func CompressJSON(text string, maxItems int) string

CompressJSON samples large JSON arrays, keeping error/failure items, first 2, last 2, and a random sample of the middle. If maxItems <= 0, defaults to 20. Non-array input is returned unchanged.

func CompressLog

func CompressLog(text string) string

CompressLog preserves ERROR/WARN/FATAL lines and stack traces, collapsing runs of 3+ similar INFO/DEBUG lines into a summary.

func DetectLanguageByExtension

func DetectLanguageByExtension(path string) string

DetectLanguageByExtension returns the programming language name for a file path based on its extension. Returns "" for unknown extensions.

func EstimateTokens

func EstimateTokens(text string) int

EstimateTokens returns the estimated token count for the given text.

func EstimateTokensPrecise

func EstimateTokensPrecise(text string) int

EstimateTokensPrecise uses BPE tokenization (slower, more accurate).

func GetLanguagePatterns

func GetLanguagePatterns(lang string) []string

GetLanguagePatterns returns custom patterns if registered, else built-in pattern strings.

func RegisterChunker

func RegisterChunker(ext string, fn ChunkerFunc)

RegisterChunker registers a custom chunker for a file extension (e.g. ".go").

func RegisterLanguagePatterns

func RegisterLanguagePatterns(lang string, patterns []string)

RegisterLanguagePatterns registers custom boundary patterns for a language. These override the built-in patterns when looking up boundaries.

func WarmupTokenizer

func WarmupTokenizer()

WarmupTokenizer pre-initializes the BPE tokenizer in the background. Call at application startup to avoid latency on the first Compress call.

Types

type ChunkOptions

type ChunkOptions struct {
	MaxTokens     int
	MinTokens     int
	MinChunkSize  int // hard minimum; chunks below this get heavy DP penalty (default: DefaultMinChunkSize)
	Language      string
	Overlap       int           // number of tokens worth of content to repeat from previous chunk
	KeepSeparator SeparatorKeep // controls boundary line placement (default: SepLeft)
}

ChunkOptions configures the code chunking behavior.

func DefaultChunkOptions

func DefaultChunkOptions() ChunkOptions

DefaultChunkOptions returns sensible defaults for code chunking.

type ChunkerFunc

type ChunkerFunc func(path, content string) (language string, chunks []CodeChunk)

ChunkerFunc is a custom chunker that takes a file path and content, returning the detected language and code chunks.

type CodeChunk

type CodeChunk struct {
	Content   string `json:"content"`
	StartLine int    `json:"start_line"`
	EndLine   int    `json:"end_line"`
	Symbol    string `json:"symbol,omitempty"`
	Tokens    int    `json:"tokens"`
}

CodeChunk represents a semantically meaningful chunk of source code.

func ChunkCode

func ChunkCode(source string, opts ChunkOptions) []CodeChunk

ChunkCode splits source code into semantically meaningful chunks based on language-aware boundary detection (function/class/method definitions). If a custom chunker is registered for the file extension in opts.Language, it is used instead of the default pipeline.

func ChunkCodePath

func ChunkCodePath(path, source string, opts ChunkOptions) []CodeChunk

ChunkCodePath is like ChunkCode but accepts a file path for registry lookup.

type Compressor

type Compressor struct {
	// contains filtered or unexported fields
}

Compressor is a reusable compression instance. Reuses internal caches across calls for better performance.

func NewCompressor

func NewCompressor(opts ...Option) *Compressor

NewCompressor creates a reusable compressor.

func (*Compressor) Compress

func (c *Compressor) Compress(text string) (string, Stats)

Compress applies the compression pipeline to the input text.

type LayerStat

type LayerStat struct {
	TokensSaved int
	DurationMs  int64
}

LayerStat contains per-layer statistics.

type Mode

type Mode string

Mode controls compression aggressiveness.

const (
	ModeMinimal    Mode = "minimal"
	ModeAggressive Mode = "aggressive"
)

type Option

type Option interface {
	// contains filtered or unexported methods
}

Option configures compression behavior.

Pre-built option presets (use directly as options).

func WithBudget

func WithBudget(tokens int) Option

WithBudget sets a hard token limit for the output.

func WithMode

func WithMode(m Mode) Option

WithMode sets the compression mode.

func WithQuery

func WithQuery(intent string) Option

WithQuery provides intent context for goal-driven filtering.

func WithTier

func WithTier(t Tier) Option

WithTier selects a pipeline profile.

type SeparatorKeep

type SeparatorKeep int

SeparatorKeep controls what happens to boundary separators during splitting.

const (
	SepLeft    SeparatorKeep = iota // separator stays with preceding chunk (default)
	SepRight                        // separator stays with following chunk
	SepDiscard                      // separator is removed from output
)

type Stats

type Stats struct {
	OriginalTokens   int
	FinalTokens      int
	TokensSaved      int
	ReductionPercent float64
	Layers           map[string]LayerStat
}

Stats contains compression statistics.

func Compress

func Compress(text string, opts ...Option) (string, Stats)

Compress applies tok's compression pipeline to the input text.

type StreamCompressor

type StreamCompressor struct {
	// contains filtered or unexported fields
}

StreamCompressor maintains a background-compressed version of accumulating content. As new content is appended, it re-compresses in the background so a compressed snapshot is always available without blocking.

func NewStreamCompressor

func NewStreamCompressor(threshold int, opts ...Option) *StreamCompressor

NewStreamCompressor creates a background compressor that keeps compressed output ready at all times. Threshold is the token count that triggers background re-compression. If threshold <= 0, it defaults to 2000 tokens.

func (*StreamCompressor) Append

func (sc *StreamCompressor) Append(content string)

Append adds new content. If accumulated tokens exceed the threshold, triggers background re-compression.

func (*StreamCompressor) Close

func (sc *StreamCompressor) Close()

Close shuts down the background compressor and waits for any in-progress compression to finish.

func (*StreamCompressor) Raw

func (sc *StreamCompressor) Raw() string

Raw returns all accumulated raw content.

func (*StreamCompressor) Snapshot

func (sc *StreamCompressor) Snapshot() (string, Stats)

Snapshot returns the current compressed output without blocking. If compression hasn't run yet, returns the raw content joined.

func (*StreamCompressor) TokenCount

func (sc *StreamCompressor) TokenCount() int

TokenCount returns estimated token count of raw content.

type Tier

type Tier string

Tier selects a pre-built pipeline profile.

const (
	TierSurface  Tier = "surface"  // 4 layers, fast
	TierTrim     Tier = "trim"     // 8 layers, balanced
	TierExtract  Tier = "extract"  // 20 layers, max compression
	TierCore     Tier = "core"     // 20 layers, quality-first
	TierCode     Tier = "code"     // code-aware
	TierLog      Tier = "log"      // log-aware
	TierThread   Tier = "thread"   // conversation-aware
	TierAdaptive Tier = "adaptive" // auto-detect content type
)

Directories

Path Synopsis
internal
cache
Package cache provides persistent query caching for tok.
Package cache provides persistent query caching for tok.
config
Package config provides configuration management for tok.
Package config provides configuration management for tok.
core
Package core provides core interfaces and utilities for tok.
Package core provides core interfaces and utilities for tok.
filter
Package filter provides LRU caching using the unified cache package.
Package filter provides LRU caching using the unified cache package.
simd
Package simd provides performance-optimized string operations using manual loop unrolling (processing 16 bytes per iteration).
Package simd provides performance-optimized string operations using manual loop unrolling (processing 16 bytes per iteration).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL