sini/nix-config/calldiff

Claude Code and agent skill by sini/nix-config

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Reads and diffs call graphs with `calldiff`, so a change is described by the call paths it moved rather than by prose over a line diff. Use before proposing an approach, when reviewing a diff that reroutes control flow, and when writing the PR body for one. Do not use for Nix, which calldiff cannot parse.

Install

npx vskill@latest install sini/nix-config/calldiff

SKILL.md

calldiff

calldiff parses a repository with tree-sitter and prints who calls whom, as a tree. calldiff diff prints the same tree twice over and marks what one git tree added or dropped against another.

It answers the question a line diff cannot. What call paths did this change create, remove, or reroute? A line diff shows that a function body changed. A call diff shows that the function now reaches the network, or no longer reaches the cache.

Language support: it does not read Nix

22 languages, including TypeScript, JavaScript, Python, Go, Rust, Java, Ruby, C, C++, C#, Swift, Kotlin, Lua, Elixir, Bash, and Zig.

Nix is not one of them. In sysinit, that rules out most of the tree. calldiff answers Entrypoint file not found for a .nix path, which reads exactly like a typo. It is not one: the file is unindexed. Do not conclude that the file is empty, and do not retry with a different path.

What calldiff does reach in this repo: the Lua under modules/darwin/home/hammerspoon/ and sysinit.nvim. It also reaches the Go under pkgs/ and the shell under hack/.

It reaches .zsh too, which upstream does not. overlays/calldiff.nix adds the extension to the bash extractor, and the bash grammar parses this repo's zsh including its dotted function names. Nushell has no extractor at all, so the five .nu files stay unread.

The three commands

bash
# What this working tree changed, against HEAD. No arguments needed.
calldiff diff
# A branch against another. Same argument order as git diff.
calldiff diff main feature
# One entrypoint's call tree, no diff.
calldiff tree -e run pkgs/ask
# Every path from an entrypoint to a symbol. Answers "can this reach that?"
calldiff reach -e M.setup --to compose modules/darwin/home/hammerspoon

--to takes a symbol the repository defines. A call into a library, such as hs.execute or fmt.Println, is a leaf in the tree and not a reachable target. reach --to on one answers Target not found.

Argument order matches git diff. No ref means HEAD against the working tree. One ref means that ref against the working tree. Two refs compare those two trees.

Rules

Give Go and Rust an entrypoint; --file wants an export

--file expands to the exports of that file. A Go package main exports nothing, so --file on it fails with No exported entrypoints even though the file parses. Name the function with -e and scope with a path instead.

bash
# good — the function by name, the package as the search path
calldiff tree -e run pkgs/ask
# bad — main.go exports nothing, so this reports failure on a file it parsed fine
calldiff tree --file pkgs/ask/main.go
Bound the output before piping it into your own context

A tree over a large entrypoint runs to thousands of lines, and the default depth is 12. --max-depth cuts the tree; --token-limit cuts the text. Use one.

bash
# good — two levels is enough to see what moved
calldiff diff main --max-depth 3
# bad — the whole graph, most of which the change did not touch
calldiff diff main
Fence the default output; --format md is broken in 0.5.0

The default tree is colored on a terminal and plain when piped, so it pastes into a fenced block as-is. --format md puts the multi-line tree inside one markdown table cell and prints [object Object] for the tree column. It renders as neither a table nor a tree. --format json and --format yaml are sound; use one of those when a script reads the output.

`markdown
<!-- good — the plain tree inside a fence -->

$ calldiff diff main --max-depth 3

<!-- bad — a table cell holding a 20-line tree, and [object Object] beside it -->
$ calldiff diff main --format md
Never run calldiff skills add or calldiff mcp add

Both write agent config files directly into ~/.claude and ~/.config. Those paths are generated by this repository, so a write there is either overwritten by the next nh darwin switch or lost. The skill you are reading is the nix-managed equivalent, and modules/home/programs/llm/mcp-servers.nix already registers calldiff --mcp for every harness.

bash
# good — the skill ships from modules/home/programs/llm/skills/calldiff/
calldiff diff --format md
# bad — writes a hand-managed file into a Nix-owned directory
calldiff skills add claude

The MCP server hides diff, reach and tree behind search_tools and call_read_tool, so reaching one costs three round trips. Prefer the shell.

It never installs a grammar, so a slow run is a real one

Upstream calldiff runs npm install into ~/.cache/calldiff/grammars the first time it meets a language. The build here bundles bash, go, lua, python, rust and typescript into the package itself, and calldiff prefers its own node_modules over that cache. A run over those languages needs no network and takes about 0.3 seconds.

A language outside that list still falls back to the cache and still installs. overlays/calldiff.nix names the bundled set; add to it rather than letting the fallback fire on a language this machine parses often.

Where this fits the other skills

  • Planning a change: run calldiff tree and calldiff reach before you propose

an approach. The design then rests on the call graph the code has, not the one you assume.

  • Reviewing a diff: calldiff diff alongside the line diff. A call path that

appeared and is not mentioned in the description is the finding.

  • Writing the PR body: calldiff diff in a fenced block when the change moved

control flow, in place of a paragraph describing it.

  • Finding code in the first place: that is search-code-routing. calldiff reads

call edges, not text and not shapes.

Security

  • Security scanPassed, 90 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
0

Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/sini/nix-config/calldiff/badge)](https://verified-skill.com/skills/sini/nix-config/calldiff)

Something wrong with this skill or its page? Tell us.