Credit: This approach was designed and spec'd by @vadash in #173.
Requires: tweakcc — a tool that patches Claude Code's system prompts directly.
Important
This doc no longer pins specific tweakcc filenames. Earlier revisions mapped each routing snippet to a fixed fragment name (system-prompt-tool-usage-read-files.md, etc.). Claude Code has since reorganized its system prompt, and tweakcc regenerates the fragment set from whatever Claude Code version you have installed — so any hardcoded filename goes stale on the next CC release (#326). Instead, the routing snippets below are keyed to behavior, and you merge each into whichever current section governs that behavior. Find your version's sections by browsing ~/.tweakcc/system-prompts/ after running tweakcc once, or the full mirror at Piebald-AI/claude-code-system-prompts.
The common failure mode with jCodemunch isn't forgetting — it's skipping. Claude sees the CLAUDE.md policy and reaches for Read or Grep anyway because native tools feel faster under pressure or in long sessions.
jCodemunch offers three enforcement layers:
| Layer | Mechanism | Strength |
|---|---|---|
| CLAUDE.md policy | Soft rules in project instructions | Weakest — ignored under cognitive load |
| PreToolUse hooks | Intercept tool calls at runtime | Medium — stderr warnings, allows Read for edits |
| System prompt rewrites (this doc) | Patch Claude's core instructions | Strongest — model internalizes the preference |
System prompt routing embeds jCodemunch preferences directly into the tool descriptions and usage instructions that Claude reads at the start of every conversation. The model never sees "use Grep for code search" — it sees "use search_symbols for code search" from the start.
tweakcc patches Claude Code's minified cli.js from customizations it stores in ~/.tweakcc/config.json. For system prompts specifically:
- Run tweakcc once (
npx tweakcc). It detects your installed Claude Code version and writes one markdown file per system-prompt part into~/.tweakcc/system-prompts/(or$XDG_CONFIG_HOME/tweakcc/system-prompts), pre-populated with that version's default text. - Edit the relevant markdown files to inject the jCodemunch routing snippets below.
- Run
npx tweakcc --applyto patchcli.js.
Updating Claude Code overwrites the patch, but your edits are remembered — just re-run npx tweakcc --apply. After a CC upgrade, re-check ~/.tweakcc/system-prompts/: section names and boundaries can shift between versions, so confirm your snippets still landed in a section that's actually in the prompt.
tweakcc maintains the canonical, per-version prompt set (and a browsable mirror of every section) at Piebald-AI/claude-code-system-prompts. Use it to see how the current release structures tool-usage and task guidance before deciding where each snippet goes.
CLAUDE.md (soft) --> PreToolUse hooks (hard) --> PostToolUse hook (auto)
routing policy read guard, edit guard index_file after edit
System prompts (deep) --> PostToolUse hook (auto)
routing built into index_file after edit
core instructions (unchanged)
| Component | Reason |
|---|---|
| CLAUDE.md jCodemunch policy block | Replaced by system prompt rewrites |
| PreToolUse read guard | Replaced by prompt routing |
| PreToolUse edit guard | Replaced by prompt routing |
| Component | Reason |
|---|---|
| PostToolUse index hook | Auto re-index is free — no model load, no tool call overhead |
- Code files (
.ts.js.py.go.rs.java.rb.php.cs.cpp.c.h.swift.kt.scala.sqletc.) route to jCodemunch - Non-code files (
.md.json.yaml.toml.env.txt.html.xml.csv, images, PDFs) use native tools (Read,Grep,Glob) - Read is not blocked —
Edit/Writeneed file content in context - Read is deprioritized for code exploration — model reaches for
get_file_outline/get_symbol_sourcefirst - Post-edit indexing handled by hook, not prompt instruction — zero model overhead
Each snippet is jCodemunch routing language to merge into whichever current Claude Code prompt section governs that behavior. Append it to the relevant section's markdown file under ~/.tweakcc/system-prompts/ (preserve the default text already there — add to it, don't wipe it), then npx tweakcc --apply.
How to find the right section: open ~/.tweakcc/system-prompts/ and read the part that talks about reading files / searching / tool selection / starting a task. In recent releases this guidance is more consolidated than it used to be (fewer, broader sections), so several snippets may land in the same file. When in doubt, the system-prompts mirror shows the full current text of every section.
Target the section that tells Claude how/when to read files.
Before reading any source code file, call jCodeMunch get_file_outline to see its
structure first. To read specific symbols, use get_symbol_source (single symbol_id
or batch symbol_ids[]) or get_context_bundle (symbol + its imports) instead of
reading the whole file. Use Read for non-code files (.md, .json, .yaml, .toml,
.env, .txt, .html, images, PDFs) and when you need complete file content before
editing. Never use cat, head, tail, or sed to read any file.
Target the section covering content/grep-style search.
To search code by symbol name (function, class, method, variable), use jCodeMunch
search_symbols -- narrow with kind=, language=, file_pattern=. To search for
strings, comments, TODOs, or patterns in source code, use jCodeMunch search_text
(supports regex via is_regex, context_lines for surrounding code). For database
columns in dbt/SQLMesh projects, use search_columns. Use Grep only for searching
non-code file content (.md, .json, .yaml, .txt, .env, config files). Never invoke
grep or rg via Bash.
Target the section covering file discovery (glob/find-style).
To browse code project structure, use jCodeMunch get_file_tree (filter with
path_prefix) or get_repo_outline for a high-level overview of directories,
languages, and symbol counts. Use Glob when finding files by name pattern. Never
use find or ls via Bash for file discovery.
Target the section describing when to use Bash / the terminal.
Reserve Bash exclusively for system commands and terminal operations: builds,
tests, git, package managers, docker, kubectl, and similar. Never use Bash for
code exploration -- do not run grep, rg, find, cat, head, or tail on source code
files through it. Use jCodeMunch MCP tools for all code reading and searching. If
unsure whether a dedicated tool exists, default to the dedicated tool.
Target the section on searching for a specific function/class/symbol.
For directed codebase searches (finding a specific function, class, or method),
use jCodeMunch search_symbols directly -- it is faster and more precise than text
search. For text pattern searches in code, use jCodeMunch search_text. Use native
search tools only when searching non-code file content.
Target the section on exploring/orienting in an unfamiliar codebase.
For broader codebase exploration, start with jCodeMunch: get_repo_outline for
project overview, get_file_tree to browse structure, suggest_queries when the repo
is unfamiliar. For deep research requiring multiple rounds, use subagents --
instruct them to prefer jCodeMunch over native search tools for source code
exploration.
Target the section on when and how to use subagents.
Use subagents when the task matches the agent's description. Subagents are
valuable for parallelizing independent queries or protecting the main context
window from excessive results. When delegating code exploration to subagents,
instruct them to use jCodeMunch MCP tools (search_symbols, get_symbol_source,
get_file_outline) rather than Read, Grep, or Glob for source code. Avoid
duplicating work that subagents are already doing.
Target the section on doing tasks / making code changes.
Do not propose changes to code you haven't understood. Before modifying code, use
jCodeMunch to build context: get_file_outline to see the file's structure,
get_symbol_source or get_context_bundle to read the relevant symbols, and
get_blast_radius or find_references to understand the impact of your changes.
When working with source code, call resolve_repo with the current directory to
confirm the project is indexed. If not indexed, call index_folder. When a repo is
unfamiliar, call suggest_queries for orientation.
For non-code files (.md, .json, .yaml, .toml, .env, .txt, .html), use Read
directly.
With system prompt routing active, only the PostToolUse hook is needed:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [{
"type": "command",
"command": "jcodemunch-mcp hook-posttooluse"
}]
}
]
}
}All PreToolUse entries can be removed.
| Test | Expected behavior |
|---|---|
| "Find the main function in this project" | Uses search_symbols, not Grep |
| "What does UserService do?" | Uses get_file_outline + get_symbol_source, not Read |
| "Show me the project structure" | Uses get_file_tree, not Glob or ls |
| "Search for TODO comments" | Uses search_text, not Grep |
| "Read the README" | Uses Read (non-code file) |
| "Search package.json for the version" | Uses Grep or Read (non-code file) |
Edit a .ts file |
PostToolUse hook fires, re-indexes automatically |
System prompt routing and hooks are complementary, not exclusive. You can run both:
- Prompts handle the 95% case — Claude reaches for jCodemunch by default
- PreToolUse hook (stderr warning) catches the remaining 5% under cognitive load
- PostToolUse hook keeps the index fresh regardless
This layered approach gives the strongest enforcement with the least friction.
To revert: run npx tweakcc --restore to drop tweakcc's patches (or remove your snippets from the files under ~/.tweakcc/system-prompts/ and re-run npx tweakcc --apply), then re-enable the CLAUDE.md policy block and PreToolUse hooks per AGENT_HOOKS.md.