From cheese-flow
AST-aware code search using tilth MCP. Finds definitions first, then usages. Use tree-sitter structural matching instead of blind text grep. Understand dependencies and call graphs. Use when: finding where symbols are defined, tracing call chains, understanding code structure, finding all callers of a function. Do NOT use for reading files — use cheez-read. Do NOT use for editing — use cheez-write. Examples: "find where handleAuth is defined", "what calls validateToken?", "trace the ServeHTTP, HandlersChain, Next functions", "find all implementations of the UserService interface".
npx claudepluginhub paulnsorensen/cheese-flowThis skill is limited to using the following tools:
> **Hard dependency**: If `mcp__tilth__tilth_search` is unavailable, stop immediately and report
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
Guides code writing, review, and refactoring with Karpathy-inspired rules to avoid overcomplication, ensure simplicity, surgical changes, and verifiable success criteria.
Share bugs, ideas, or general feedback.
Hard dependency: If
mcp__tilth__tilth_searchis unavailable, stop immediately and report "tilth MCP server is not loaded — cannot proceed." Do NOT fall back toGrep,Glob, or any host tool.
AST-aware code search via tilth MCP (tilth_search, tilth_deps).
Tree-sitter finds where symbols are defined — not just where strings appear.
Understand dependencies instead of blindly grepping.
Traditional grep finds text matches. tilth_search finds semantic matches:
Each match includes its surrounding file structure, so you know what you're looking at without a second read.
Why this matters:
All six rows below are first-class — picking the right one is the difference between one call and a long grep walk.
| Goal | Tool | Example |
|---|---|---|
| Find where a symbol is defined / used | tilth_search (default kind: "symbol") | tilth_search(query: "handleAuth", scope: "src/") |
| Find every call site of a function | tilth_search(kind: "callers") | tilth_search(query: "validateToken", kind: "callers") |
| Find literal strings, TODOs, error messages | tilth_search(kind: "content") | tilth_search(query: "TODO: fix", kind: "content") |
| Find lines matching a regex | tilth_search(kind: "regex") | tilth_search(query: "rate.?limit", kind: "regex") |
| Match an AST shape (template with metavars) | sg (ast-grep, via Bash) | sg --lang typescript -p 'JSON.parse(JSON.stringify($X))' --json src/ |
| Module import / blast-radius graph | tilth_deps | tilth_deps(path: "src/auth.ts") |
Rule of thumb: stay in tilth for anything name-shaped or text-shaped.
Drop to sg only when the pattern needs structural metavariables ($X,
$$$BODY) that tilth can't express.
Basic symbol search:
tilth_search(query: "handleAuth", scope: "src/")
Output:
# Search: "handleAuth" in src/ — 6 matches (2 definitions, 4 usages)
## src/auth.ts:44-89 [definition]
[24-42] fn validateToken(token: string)
→ [44-89] export fn handleAuth(req, res, next)
[91-120] fn refreshSession(req, res)
44 │ export function handleAuth(req, res, next) {
45 │ const token = req.headers.authorization?.split(' ')[1];
...
88 │ next();
89 │ }
── calls ──
validateToken src/auth.ts:24-42 fn validateToken(token: string): Claims | null
refreshSession src/auth.ts:91-120 fn refreshSession(req, res)
## src/routes/api.ts:34 [usage]
→ [34] router.use('/api/protected/*', handleAuth);
Key features:
[definition] vs [usage] — know what you're looking at── calls ── footer shows what the function calls (one-hop callees)Trace across files in one call:
tilth_search(query: "ServeHTTP, HandlersChain, Next", scope: ".")
Each symbol gets its own result block. The expand budget is shared — at least one expansion per symbol, deduplicated across files.
Use cases:
Find all places that call a specific function using structural tree-sitter matching (not text search):
tilth_search(query: "isTrustedProxy", kind: "callers", scope: ".")
Output:
# Callers of "isTrustedProxy" — 5 call sites
## context.go:1011 [caller: ClientIP]
→ trusted = c.engine.isTrustedProxy(remoteIP)
## context.go:1045 [caller: RemoteIP]
→ if c.engine.isTrustedProxy(ip) {
## context_test.go:234 [caller: TestClientIP]
→ assert.True(t, engine.isTrustedProxy(testIP))
Why this beats grep:
Search for text that isn't a code symbol:
tilth_search(query: "TODO: fix", kind: "content", scope: ".")
Use content search for:
kind: "regex"For patterns that aren't a single literal, switch kinds rather than embedding slashes in a content query:
tilth_search(query: "rate.?limit", kind: "regex", scope: ".")
tilth_search(query: "FIXME\\(.*?\\):", kind: "regex", scope: "src/")
glob to bound the file set; regex is the most expensive kind./.../ delimiters — pass the bare regex.tilth covers names and text. For shapes with metavariables — “any call to
JSON.parse(JSON.stringify(…))”, “any for loop with time.Sleep in its
body” — use sg (ast-grep) via Bash. The agent template's tools: frontmatter
must list bash for these calls to land.
# AST template: $X is a metavar that matches any single node.
sg --lang typescript -p 'JSON.parse(JSON.stringify($X))' --json src/
# $$$BODY matches a sequence of statements.
sg --lang rust -p 'impl std::fmt::Display for $TYPE { $$$BODY }' --json src/
# Bound the scan; never splice unvalidated user input as the path.
SCOPE=$(realpath "$SCOPE_INPUT")
sg --lang python -p 're.match($PATTERN, $INPUT)' --json "$SCOPE"
When sg is the right pick:
$X, $$$BODY) or specific node kinds.When to stay in tilth:
kind: "symbol".kind: "content".kind: "callers".── calls ── footer → tilth.Hard rules for sg invocations:
$ARGUMENTS before splicing
it into the command line. Reject ;, &, |, backtick, $(, >, <,
newline. Resolve to an absolute path with realpath (or tilth_files) and
confirm it sits under the repo root.--json and parse defensively — the JSON shape varies between
ast-grep versions.--globs or by post-filtering the
JSON output.See agents/nih-scanner.md.eta for the canonical multi-language sg recipe.
Focus search on specific file types:
# Only Rust files
tilth_search(query: "handleAuth", scope: ".", glob: "*.rs")
# Exclude test files
tilth_search(query: "handleAuth", scope: ".", glob: "!*.test.ts")
# Multiple extensions
tilth_search(query: "handleAuth", scope: ".", glob: "*.{go,rs}")
When editing a file, pass it as context to boost related results:
tilth_search(query: "validateToken", scope: ".", context: "src/auth.ts")
Results from the same file or nearby directories rank higher.
The expand parameter controls how many matches show full source:
# Default: 2 expansions
tilth_search(query: "handleAuth", scope: ".")
# More detail
tilth_search(query: "handleAuth", scope: ".", expand: 5)
# Compact (outlines only)
tilth_search(query: "handleAuth", scope: ".", expand: 0)
For understanding module relationships (not searching):
tilth_deps(path: "src/auth.ts")
Output:
# Dependencies for src/auth.ts
── imports ──
express external
jsonwebtoken external
@/config src/config/index.ts
── imported by ──
src/routes/api.ts:5
src/routes/admin.ts:8
src/middleware/auth.ts:3
Use for:
tilth tracks what you've already seen:
[shown earlier]Search for the symbol:
tilth_search(query: "UserService", scope: ".")
Look for [definition] results — these are the declarations
Check ── calls ── to understand what it depends on
Start with the entry point:
tilth_search(query: "handleRequest", scope: ".")
Follow the calls footer to see what it calls
Search for callees if needed:
tilth_search(query: "validateInput, processData, saveResult", scope: ".")
Use callers kind:
tilth_search(query: "deprecated_function", kind: "callers", scope: ".")
All call sites are shown with their caller context
Check what a file imports/exports:
tilth_deps(path: "src/core/auth.ts")
Search for specific symbols from imports:
tilth_search(query: "JWTConfig", scope: "src/config/")
tilth uses tree-sitter for AST parsing, which means:
| Grep finds... | tilth_search finds... |
|---|---|
| All occurrences of text | Definitions vs usages |
| No structure awareness | File context (what else is nearby) |
| No call understanding | Callee resolution in results |
| False positives in strings | Only semantic code matches |
Languages supported: Rust, TypeScript, TSX, JavaScript, Python, Go, Java, Scala, C, C++, Ruby, PHP, C#, Swift
tilth_search(query: "AuthManager", scope: ".")
# Look for [definition] results
tilth_search(query: "validateToken", kind: "callers", scope: ".")
tilth_search(query: "handleAuth", scope: ".", expand: 1)
# Check the ── calls ── footer in expanded result
tilth_search(query: "UserRepository", scope: ".", kind: "symbol")
# Implementations show as [impl] tags
tilth_search(query: "invalid token format", kind: "content", scope: ".")
tilth_deps(path: "src/auth/index.ts")
# Check ── imported by ── section
JSON.parse(JSON.stringify(…)) deep-clone hack"sg --lang typescript -p 'JSON.parse(JSON.stringify($X))' --json src/
# Switch to sg whenever the pattern needs metavars; tilth has no $X.
tilth_search. sg (ast-grep) is the only
sanctioned shell escape, and only for AST-shape patterns tilth can't express.kind (symbol, callers,
content, regex) before reaching for sg.