Minimal code and minimal words, combined — a YAGNI/terse-prose persona plus a deterministic tool-output compressor, for Claude Code and Hermes.
Quick start · What's inside · Tuning · When to skip · Uninstall
Two blades: what you build, how you talk about it.
- Blade 1 — code: an efficiency ladder (YAGNI → reuse → stdlib → native → existing dep → one line → minimum code). Stop at the first rung that holds.
- Blade 2 — prose: facts and code, no preamble, no restating the ask, no trailing summary. Fragments over sentences where meaning survives.
Supports Claude Code and Hermes — the two agents this was built for, both of which support the full feature set (persona skill + tool-output compression hook).
Claude Code:
claude plugin marketplace add maxkilla/comb
claude plugin install comb@combRestart Claude Code (or start a new session) and it's live — no config file to edit, no restart flags.
Hermes:
hermes plugins install maxkilla/comb --enable(Manual install: cp plugin.yaml __init__.py ~/.hermes/plugins/comb/, then add comb under plugins.enabled in your Hermes config — Plugin's kind is omitted in plugin.yaml, so Hermes defaults it to standalone, which is what makes that enabled entry required. Project-local install: ./comb/, requires HERMES_ENABLE_PROJECT_PLUGINS=1. The persona skill is separate from the plugin — copy skills/comb/SKILL.hermes.md to ~/.hermes/skills/software-development/comb/SKILL.md if you want comb mode without the always-on SOUL.md edit described below.)
That's the whole install. Everything below is what it does and how to tune it — skip straight to Uninstall if you just want to try it and back out cleanly.
Default-on, no trigger word needed — see "Always-on persona" below. Off: "stop comb" / "normal mode". One blade only: "comb code" or "comb prose".
Full rules: skills/comb/SKILL.md.
| Piece | Where |
|---|---|
| Claude Code skill (source of truth) | skills/comb/SKILL.md |
| Claude Code plugin manifest | .claude-plugin/ |
| Claude Code compression hook | hooks/hooks.json + scripts/compress-tool-output.js |
| Claude Code always-on persona hook | hooks/hooks.json + scripts/inject-comb-mode.js |
| Hermes skill | skills/comb/SKILL.hermes.md |
| Hermes compression plugin | plugin.yaml + __init__.py (repo root) |
| Benchmark vs rdxmin | benchmarks/vs-rdxmin.js |
| Tests | test/compress.test.js, test/test_compress.py — 48 passing |
The persona rules are the same content in both. The tool-output compressor (elides oversized Bash/Agent/WebFetch/WebSearch/Grep/Glob/MCP output, keeps head/tail/error lines) is ported to both hosts' equivalent hook point — Claude Code's PostToolUse and Hermes' transform_tool_result. Deterministic, zero-dependency, zero-network — no external service required.
If a middle section has more distinct error-looking lines than the compressor can salvage (MAX_ERROR_LINES, 15), it leaves the output whole instead of guessing which errors to drop — a critical-gate pattern from TACO (arXiv:2604.19572), adapted here as a static rule rather than their self-evolving one. That full bypass only applies below GATE_MAX_CHARS (20000 chars) — above it, a dense-error output still needs elision, so it falls back to the normal salvage cap instead of passing an arbitrarily large blob through untouched.
For JSON tool output specifically, the head/tail cut snaps to the nearest complete element boundary (a line that's just a closing brace/bracket) instead of an arbitrary character index — a raw char cut lands mid-object about as often as not on pretty-printed JSON, which produces invalid JSON and context-free error salvage. Not a JSON parser, just a bounded search for the common pretty-printed shape; falls back to a raw cut if no boundary is found nearby.
Comb doesn't wait for the model to notice a trigger word or choose to load a skill:
- Claude Code: the plugin's
UserPromptSubmithook (scripts/inject-comb-mode.js) injects the persona rules asadditionalContexton every turn. - Hermes: installed by appending the same rules to
~/.hermes/SOUL.md, the agent's identity slot — loaded unconditionally every session, no skill load required. (This edits a file outside the repo; if you don't want that, delete the appended block fromSOUL.mdand rely onskills/comb/SKILL.hermes.mdinstead, trigger-word activated.)
Either way, skills/comb/SKILL.md / SKILL.hermes.md stay as the source of truth and remain independently loadable.
Env vars, both ports:
COMB_COMPRESS_HEAD # chars kept from the start (default 1200)
COMB_COMPRESS_TAIL # chars kept from the end (default 800)
COMB_COMPRESS_THRESHOLD # only compress above this size (default 3000)
COMB_COMPRESS_GATE_MAX # size ceiling for the error-count full-bypass gate (default 20000)
COMB_COMPRESS=0 # kill switch (Hermes only; 0/false/no/off) — disables without touching config.yaml
COMB_COMPRESS_SAVE_FULL=0 # Claude Code only: disable saving the full untouched output to disk on elision
Elided output recovery (Claude Code only). Elision is otherwise irreversible, so by default
(COMB_COMPRESS_SAVE_FULL unset or 1) the full original text is saved to
~/.claude/comb/tool-output/ (mode 0600, capped at 1MB per file, head75/tail25 if larger) and
the elided marker includes the recovery path. Files older than 7 days are swept opportunistically
(2% chance per save, no dedicated hot-path scan) rather than requiring a cron job. Since this
persists full tool output — including anything sensitive that appeared in it — to disk, set
COMB_COMPRESS_SAVE_FULL=0 if you'd rather lose the recovery file than keep it around.
scripts/comb-statusline.sh renders a [COMB] badge showing rate-limit usage (5h/weekly bars, same data /usage shows) and cumulative compressor savings (⇣~NNk tok (Nx), read from ~/.claude/comb/stats.json, written by compress-tool-output.js on every elision). The char count is measured exactly; the token figure is the standard ~4-chars-per-token estimate, hence the ~. Bash-only, no jq/node dependency, symlink-refused reads.
Claude Code allows exactly one statusLine command — wire it in ~/.claude/settings.json:
"statusLine": {
"type": "command",
"command": "bash \"/absolute/path/to/comb/scripts/comb-statusline.sh\""
}Use it if you…
- run Claude Code or Hermes and want oversized tool output compressed without giving up recoverability (elided text is saved to disk by default, see Tuning above)
- want a terse-prose/YAGNI persona that's on by default, not opt-in per message
- work with JSON-heavy tool output (MCP calls, API responses) and want elision that respects element boundaries instead of an arbitrary character cut
Skip it if you…
- are on a Claude Code version whose
tool_responseshape comb's field-guessing (output/stdout/content/text/result) doesn't match — it no-ops safely rather than guessing wrong, but you won't get compression either - want ML-based or fully content-type-routed compression (JSON-specific crushing, AST-aware code compression) — comb is a deterministic head/tail/error-line rule with a JSON-boundary heuristic bolted on, not a routed pipeline with a trained model behind it
npm test # Claude Code compressor (scripts/compress-tool-output.js)
python3 test/test_compress.py # Hermes plugin (comb/__init__.py)Claude Code:
claude plugin uninstall comb@comb
claude plugin marketplace remove combNothing else to clean up — the plugin doesn't touch any file outside its own install directory except the optional scratch dirs it created (~/.claude/comb/, holding stats.json and elided-output recovery files under tool-output/; safe to rm -rf if you don't want them kept). If you wired the statusline, remove the statusLine block from ~/.claude/settings.json.
Known Claude Code issue, not comb-specific: marketplace remove doesn't always clear the extraKnownMarketplaces entry from ~/.claude/settings.json (anthropics/claude-code#9537), which can cause the marketplace to silently reappear on next launch. If that happens, check ~/.claude/settings.json for a leftover comb entry under extraKnownMarketplaces and remove it by hand.
Hermes:
hermes plugins uninstall combOr manually: delete ~/.hermes/plugins/comb/ and remove comb from plugins.enabled. If you installed the always-on persona (which edits ~/.hermes/SOUL.md directly), delete the appended comb block from that file — it's a plain text append, easy to spot and remove.
MIT — see LICENSE.
