Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ __pycache__/
*.pyc
.venv/
.env.local
caveman-compress.md
**/.DS_Store
.claude/worktrees/
evals/snapshots/*.html
Expand Down
31 changes: 29 additions & 2 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ Useful flags:
| `--only <id>` | One agent only. Repeatable: `--only claude --only cursor`. |
| `--dry-run` | Print every command. Write nothing. |
| `--with-init` | Drop always-on rule files into the current repo (`.cursor/`, `.windsurf/`, `.clinerules/`, `.github/copilot-instructions.md`, `.opencode/AGENTS.md`, `AGENTS.md`) and, if OpenClaw is on the box, append the bootstrap block to `~/.openclaw/workspace/SOUL.md`. |
| `--with-mcp-shrink` | Register `caveman-shrink` MCP proxy. **On by default.** |
| `--with-mcp-shrink` | Register `caveman-shrink` MCP proxy for Claude Code. **On by default.** OpenCode must wrap MCP servers manually. |
| `--no-mcp-shrink` | Skip MCP-shrink registration. |
| `--with-hooks` / `--no-hooks` | Force-on or force-off the Claude Code hook installer. (Default: on.) |
| `--skip-skills` | Don't run the npx-skills auto-detect fallback when nothing else matched. |
Expand Down Expand Up @@ -170,7 +170,7 @@ What it removes:
- Caveman hook entries from `$CLAUDE_CONFIG_DIR/settings.json` (default `~/.claude/`; matched by the substring `caveman`).
- Hook files in `$CLAUDE_CONFIG_DIR/hooks/` (`caveman-activate.js`, `caveman-mode-tracker.js`, `caveman-stats.js`, `caveman-config.js`, `caveman-statusline.{sh,ps1}`, plus the dir's `package.json` marker).
- The Claude Code plugin and the Gemini CLI extension (if installed).
- The opencode native plugin (`~/.config/opencode/plugins/caveman/`, the `plugin` and `mcp.caveman-shrink` entries from `opencode.json`, our skill/agent/command files, the caveman block from `AGENTS.md`, and the opencode flag file).
- The opencode native plugin (`~/.config/opencode/plugins/caveman/`, the `plugin` entry from `opencode.json`, our skill/agent/command files, the caveman block from `AGENTS.md`, and the opencode flag file). Old `mcp.caveman-shrink` entries are pruned if present.
- The OpenClaw workspace skill folder and the marker-fenced block from `~/.openclaw/workspace/SOUL.md` (when present).
- The `.caveman-active` flag file.

Expand All @@ -191,6 +191,33 @@ Agent read repo. Agent run install. Caveman make agent talk less — agent first

Still broken? [Open an issue](https://github.com/JuliusBrussee/caveman/issues).

**"I want `caveman-shrink` in OpenCode."**

OpenCode install no longer auto-registers `caveman-shrink`. Add a manual MCP
entry that wraps specific upstream servers:

```json
{
"mcp": {
"filesystem-shrink": {
"type": "local",
"command": [
"npx",
"-y",
"caveman-shrink",
"npx",
"-y",
"@modelcontextprotocol/server-filesystem",
"/absolute/path/to/project"
],
"enabled": true
}
}
}
```

Pattern: `caveman-shrink <upstream-command> [...args]`.

**"I ran the installer but Claude Code isn't talking caveman."**

1. Run `node bin/install.js --list` — confirm `claude` is on the detected list. If not, `claude` isn't on `PATH`. Fix that first.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ Install break? Open agent, say *"Read CLAUDE.md and INSTALL.md, install caveman
| `/caveman-review` | One-line PR comments: `L42: 🔴 bug: user null. Add guard.` |
| `/caveman-stats` | Real session token usage + lifetime savings + USD. Tweetable line via `--share`. |
| `/caveman-compress <file>` | Rewrite memory file (e.g. `CLAUDE.md`) into caveman-speak. Cuts ~46% input tokens every session. Code/URLs/paths byte-preserved. |
| `caveman-shrink` | MCP middleware. Wraps any MCP server, compresses tool descriptions. [npm](https://www.npmjs.com/package/caveman-shrink). |
| `caveman-shrink` | MCP middleware. Wraps any MCP server, compresses tool descriptions. Auto-wired for Claude Code; OpenCode wraps manually. [npm](https://www.npmjs.com/package/caveman-shrink). |
| `cavecrew-*` | Caveman subagents (investigator/builder/reviewer). ~60% fewer tokens than vanilla, main context lasts longer. |

**Statusline badge** — Claude Code shows `[CAVEMAN] ⛏ 12.4k` (lifetime tokens saved). Updates every `/caveman-stats` run. Set `CAVEMAN_STATUSLINE_SAVINGS=0` to silence.
Expand Down
9 changes: 8 additions & 1 deletion agents/cavecrew-builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@ description: >
scope. Returns caveman diff receipt. Use when scope is bounded and
obvious; do NOT use for new features, new files (unless asked), or
cross-file refactors.
tools: [Read, Edit, Write, Grep, Glob]
mode: subagent
tools:
read: true
edit: true
write: true
glob: true
grep: true
bash: false
---

Caveman-ultra. Drop articles/filler. Code/paths exact, backticked. No narration.
Expand Down
10 changes: 8 additions & 2 deletions agents/cavecrew-investigator.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@ description: >
"what calls Y", "list all uses of Z", "map this directory". Output is
caveman-compressed so the main thread eats ~60% fewer tokens than
vanilla Explore. Refuses to suggest fixes.
tools: [Read, Grep, Glob, Bash]
model: haiku
mode: subagent
tools:
read: true
edit: false
write: false
glob: true
grep: true
bash: true
---

Caveman-ultra. Drop articles/filler/hedging. Code/symbols/paths exact, backticked. Lead with answer.
Expand Down
9 changes: 7 additions & 2 deletions agents/cavecrew-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@ description: >
no scope creep. Output format `path:line: <emoji> <severity>: <problem>. <fix>.`
Use for "review this PR", "review my diff", "audit this file". Skips
formatting nits unless they change meaning.
tools: [Read, Grep, Bash]
model: haiku
mode: subagent
tools:
read: true
edit: false
write: false
grep: true
bash: true
---

Caveman-ultra. Findings only. No "looks good", no "I'd suggest", no preamble.
Expand Down
23 changes: 9 additions & 14 deletions bin/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,6 @@ const OPENCODE_AGENTS_MD_END = '<!-- caveman-end -->';

function opencodeConfigDir() {
if (process.env.XDG_CONFIG_HOME) return path.join(process.env.XDG_CONFIG_HOME, 'opencode');
if (IS_WIN) return path.join(process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming'), 'opencode');
return path.join(os.homedir(), '.config', 'opencode');
}

Expand Down Expand Up @@ -516,7 +515,10 @@ function installOpencode(ctx) {
note(` would copy ${OPENCODE_COMMAND_FILES.length} command files into ${commandsDir}/`);
note(` would copy ${OPENCODE_AGENT_FILES.length} cavecrew agents into ${agentsDir}/`);
note(` would copy ${OPENCODE_SKILL_DIRS.length} skill dirs into ${skillsDir}/`);
note(` would patch ${opencodeJson} with "plugin" entry${opts.withMcpShrink ? ' + caveman-shrink MCP' : ''}`);
note(` would patch ${opencodeJson} with "plugin" entry`);
if (opts.withMcpShrink) {
note(' would not auto-register caveman-shrink for opencode; wrap specific MCP servers manually');
}
note(` would write Tier-3 ruleset to ${agentsMd}`);
results.installed.push('opencode');
process.stdout.write('\n');
Expand Down Expand Up @@ -614,7 +616,8 @@ function installOpencode(ctx) {
process.stdout.write(` installed: ${agentsMd}\n`);
}

// 6. opencode.json — add plugin entry; optional caveman-shrink MCP.
// 6. opencode.json — add plugin entry only. caveman-shrink stays manual for
// opencode because the standalone MCP registration has broken startup.
let cfg = SETTINGS.readSettings(opencodeJson);
if (cfg === null) {
warn(` ${opencodeJson} unparseable; will not touch it. Edit manually then re-run.`);
Expand All @@ -632,19 +635,11 @@ function installOpencode(ctx) {
if (!cfg.plugin.includes(OPENCODE_PLUGIN_REL)) {
cfg.plugin.push(OPENCODE_PLUGIN_REL);
}
if (opts.withMcpShrink) {
if (!cfg.mcp || typeof cfg.mcp !== 'object') cfg.mcp = {};
if (!cfg.mcp['caveman-shrink']) {
cfg.mcp['caveman-shrink'] = {
type: 'local',
command: ['npx', '-y', MCP_SHRINK_PKG],
enabled: true,
};
process.stdout.write(' registered caveman-shrink MCP server\n');
}
}
SETTINGS.writeSettings(opencodeJson, cfg);
process.stdout.write(` patched: ${opencodeJson}\n`);
if (opts.withMcpShrink) {
note(' caveman-shrink not auto-registered for opencode; wrap MCP servers manually if wanted');
}

results.installed.push('opencode');
} catch (e) {
Expand Down
9 changes: 8 additions & 1 deletion plugins/caveman/agents/cavecrew-builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@ description: >
scope. Returns caveman diff receipt. Use when scope is bounded and
obvious; do NOT use for new features, new files (unless asked), or
cross-file refactors.
tools: [Read, Edit, Write, Grep, Glob]
mode: subagent
tools:
read: true
edit: true
write: true
glob: true
grep: true
bash: false
---

Caveman-ultra. Drop articles/filler. Code/paths exact, backticked. No narration.
Expand Down
10 changes: 8 additions & 2 deletions plugins/caveman/agents/cavecrew-investigator.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@ description: >
"what calls Y", "list all uses of Z", "map this directory". Output is
caveman-compressed so the main thread eats ~60% fewer tokens than
vanilla Explore. Refuses to suggest fixes.
tools: [Read, Grep, Glob, Bash]
model: haiku
mode: subagent
tools:
read: true
edit: false
write: false
glob: true
grep: true
bash: true
---

Caveman-ultra. Drop articles/filler/hedging. Code/symbols/paths exact, backticked. Lead with answer.
Expand Down
9 changes: 7 additions & 2 deletions plugins/caveman/agents/cavecrew-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@ description: >
no scope creep. Output format `path:line: <emoji> <severity>: <problem>. <fix>.`
Use for "review this PR", "review my diff", "audit this file". Skips
formatting nits unless they change meaning.
tools: [Read, Grep, Bash]
model: haiku
mode: subagent
tools:
read: true
edit: false
write: false
grep: true
bash: true
---

Caveman-ultra. Findings only. No "looks good", no "I'd suggest", no preamble.
Expand Down
28 changes: 28 additions & 0 deletions src/plugins/opencode/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,34 @@ to `caveman-config.cjs` because this directory is `"type": "module"`) into
`~/.config/opencode/plugins/caveman/` and patches `opencode.json` with a
`"plugin"` array entry.

It does **not** auto-register `caveman-shrink` as an OpenCode MCP server.
That startup path is currently broken upstream in caveman, so wrap specific MCP
servers manually if you want shrink behavior in OpenCode.

Example `opencode.json` entry:

```json
{
"mcp": {
"filesystem-shrink": {
"type": "local",
"command": [
"npx",
"-y",
"caveman-shrink",
"npx",
"-y",
"@modelcontextprotocol/server-filesystem",
"/absolute/path/to/project"
],
"enabled": true
}
}
}
```

Pattern: `caveman-shrink <upstream-command> [...args]`.

## What it does

- `session.created` → writes the configured default mode to
Expand Down
10 changes: 10 additions & 0 deletions src/plugins/opencode/commands/caveman-compress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
description: Compress a Markdown file into caveman format to save tokens
---
Compress the file at: $ARGUMENTS

Load the `caveman-compress` skill, then run:

`python3 -m scripts <absolute_filepath>`

The compressed version overwrites the original. A human-readable backup is saved as `FILE.original.md`.
6 changes: 0 additions & 6 deletions src/plugins/opencode/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,6 @@ function opencodeConfigDir() {
if (process.env.XDG_CONFIG_HOME) {
return path.join(process.env.XDG_CONFIG_HOME, 'opencode');
}
if (process.platform === 'win32') {
return path.join(
process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming'),
'opencode'
);
}
return path.join(os.homedir(), '.config', 'opencode');
}

Expand Down
3 changes: 2 additions & 1 deletion tests/installer/opencode.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function shimOpencode() {
}

function runInstaller(args, env) {
return spawnSync('node', [INSTALLER, ...args, '--non-interactive', '--no-mcp-shrink'], {
return spawnSync('node', [INSTALLER, ...args, '--non-interactive'], {
env, encoding: 'utf8',
});
}
Expand Down Expand Up @@ -91,6 +91,7 @@ test('opencode fresh install drops plugin, commands, agents, skills, AGENTS.md,
const cfg = JSON.parse(fs.readFileSync(cfgPath, 'utf8'));
assert.ok(Array.isArray(cfg.plugin), 'opencode.json missing plugin array');
assert.ok(cfg.plugin.includes('./plugins/caveman/plugin.js'), 'plugin entry missing');
assert.equal(cfg.mcp?.['caveman-shrink'], undefined, 'opencode install should not auto-register caveman-shrink');
} finally {
fs.rmSync(xdg, { recursive: true, force: true });
fs.rmSync(shimDir, { recursive: true, force: true });
Expand Down