skills.sh for code mode. Agent write same script every session, throw it away, write it again. Blocks keep it in your repo, check it every PR, hand it back.
| one script, rewritten in a week 32 sessions, one developer, counted by scan |
of task cost spent regenerating scripts Purdue, arXiv, Sep 2026 |
for one Go test run| tail -20 vs test-summary, this repo's 326 tests |
"Once an agent develops working code for a task, it can save that implementation for future use." Anthropic
Code mode by Cloudflare · Script waste measured by Purdue · From the makers of Caveman, #1 on Hacker News
| Normal agent · writes 101 tokens of script | 🪨 Blocks agent · 21 tokens |
|---|---|
python3 - <<'EOF'
import json
ops=json.load(open('cloud/agent-surface/generated/operations.json'))
print(type(ops), (list(ops.keys())[:5] if isinstance(ops,dict) else len(ops)))
items = ops['operations'] if isinstance(ops,dict) and 'operations' in ops else ops
print(json.dumps(items[0] if isinstance(items,list) else list(items.items())[0], indent=1)[:800])
EOF |
caveman-blocks run json-peek --path cloud/agent-surface/generated/operations.json{"kind": "object", "keys": ["schema_version", "contract_sha256",
"operations", "exclusions", "operations[].id", … 15 more],
"rows": 1, "sample": {"schema_version": 1, …}, "truncated": true} |
Same question. 101 token become 21. Every session after, still 21.
A real script from a Claude Code transcript, run again on the same 1.4 MB file (251,893 tokens). Answers trimmed here; in full they are 236 and 227 tokens. The heredoc's [:800] cut its answer off mid-object; the block returned all 20 keys. Token counts: tiktoken o200k. Method
AGENTS.md says how. A block does it. init writes eight rules and a one-line-per-block index into your AGENTS.md:
| Rule | What it means |
|---|---|
| Index first | A block fits: run it. Almost fits: add a param to it |
| Twice means block | A script you would run twice, or one over ~10 lines, becomes a block. Not a heredoc, not a /tmp file |
| Inputs are params | No hardcoded paths, ids, ports or dates |
| Answer, not data | One small JSON object. Filter, count and truncate in code. The runner cuts anything over 2 KB |
| Fails loud | Exit 0 on success. Non-zero with {"error": ...} on failure |
| Safe to re-run | Idempotent, no prompts, cleans up after itself |
| Header first | Name, summary, params, effects, example. caveman-blocks lint checks it |
| Compose | Call other blocks with caveman-blocks run. Never copy their code |
One hook on the shell tool watches for heredocs. One a block covers gets a single line back: Blocks: json-peek covers this. Next time: caveman-blocks run json-peek --path …. A new one becomes a candidate the agent can promote into a block. The hook never denies or rewrites a command. verify runs every block's own example and stamps a hash into the file, and CI re-checks it on every pull request. A broken block drops out of the index. Full format: docs/FORMAT.md.
npx caveman-blocks initRun it in your repo, then commit .blocks/ and AGENTS.md. Everyone who clones it gets the blocks. One rock. That it.
Pre-release: v0.1.0-rc.1 binaries are on Releases. npx, Homebrew and curl | sh go live with v0.1.0.
More: see your waste first, add blocks, hints in your agent, plugins, CI, uninstall
npx caveman-blocks scan # what your agents retyped this month. Script text never leaves your machine
npx caveman-blocks add json-peek # copy a first-party block in. You own it now
npx caveman-blocks hooks install # once per machine: hints in Claude Code, Codex, Cursor and OpenCode
claude plugin marketplace add caveman-ai/blocks && claude plugin install caveman-blocks@caveman-blocks # Claude Code, as a plugin
codex plugin marketplace add caveman-ai/blocks && codex plugin add caveman-blocks@caveman-blocks # Codex, as a pluginAdd the CI step so a pull request can't ship a broken block. Changed your mind: caveman-blocks hooks uninstall removes only the entries it added. Something off: caveman-blocks doctor.
| Who | Found |
|---|---|
| Purdue | Agents regenerating near-duplicate scripts: up to 68.00% of tasks and 9.57% of task cost. Seven behavioral principles cut cost 7.88–41.73% in six settings; synthesized skills helped in three of eight |
| Anthropic | Agents writing code instead of calling tools: 150,000 tokens down to 2,000. Working code can be saved for future use |
| CUNY and Ohio State | 91.8% of 138,133 public SKILL.md files have at least one defect. Prose nobody runs rots |
| Microsoft Research and UIUC | 62.6% of the efficiency regressions skills cause come from too much procedure. So: eight short rules |
In one week, agents on one machine wrote near-duplicates of a single script 394 times, across 32 sessions:
$ npx caveman-blocks scan --since 7d
394x import json;r=json.load(open('tests/flowbook/out/report.jso… ~3 lines 32 sessions covered by: json-peek (add)
225x import sys,json; d=json.load(sys.stdin); [print(r['type'], … ~1 lines 37 sessions covered by: json-peek (add)
… 1853 more shapes
Measured: 94407 shell commands, 11726 inline Python scripts, 1855 shapes. Not grouped: 6331 edits, 3 scripts without a shape.
One heavy user, mostly Caveman repos. Over two months it was 30,221 scripts: half were file edits, which are never captured, and 3% took a parameter. Study · This run
| Input | Raw | What agents type now | Block |
|---|---|---|---|
go test -v ./..., 326 tests |
10,561 | 397 · | tail -20 |
76 · test-summary |
| 1.4 MB JSON file | 251,893 | 236 · their own heredoc | 227 · json-peek |
| 366-line Go file | 3,111 | 250 · grep -n "^func |^type " |
489 · grep-defs |
Tokens, tiktoken o200k. grep-defs loses to a bare grep: it labels every definition with file, kind, name and line. Not measured yet: how often agents follow a hint, and whole sessions. That's the first dogfood gate. Method
| Command | What it does |
|---|---|
scan |
Your agents' repeated scripts, from transcripts already on disk |
init |
Rules and index in AGENTS.md, .blocks/ in the repo |
add <name> |
A first-party block and its test data, copied in. Your code from then on |
run <name> |
Run a block: effects checked, paths kept inside the repo, output capped at 2 KB |
hooks install |
Hints in Claude Code, Codex and Cursor when a block covers what the agent is writing |
promote |
The brief that turns a repeated script into a block |
lint · verify · sync |
Check it, run its example and stamp it, rebuild the index. --check for CI |
stats |
Scripts captured, hints followed, block calls. Counted, local |
telemetry off |
Usage counts off for good. status shows what is on and why |
First-party blocks, Python standard library only: json-peek · jsonl-stats · test-summary · first-error · wait-for · grep-defs · http-json · replace-in-file. What each returns. export wraps them as SKILL.md for agents that read skills.
Not yet: Python only, no sandbox, and the Codex and Cursor hooks haven't run in a live session. Copilot CLI and Gemini CLI are next.
Blocks is free. It stays free because we can show it gets used, so the CLI sends usage counts by default: commands run, hints shown and followed, block runs, a random install ID, OS and IP address. Never your scripts, file paths, repo names or the names of blocks you wrote. Turn it off for good with caveman-blocks telemetry off; DO_NOT_TRACK=1 is honored too. Everything that is sent.
No model calls. Blocks stay in your repo; captured scripts are scrubbed of secrets and kept outside it. Trust boundary.
Apache-2.0. Fork it, ship it, put it in your monorepo. "Caveman" and the rock logo are trademarks; see TRADEMARKS.md.
@software{brussee2026blocks, author = {Brussee, Julius}, year = {2026},
title = {Caveman Blocks: why many script when few do trick}, url = {https://github.com/caveman-ai/blocks}}