<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <title>callgraph releases</title>
  <subtitle>What was added, changed and fixed in each callgraph release.</subtitle>
  <link rel="self" type="application/atom+xml" href="https://callgraph.eu/changelog/feed.xml"/>
  <link rel="alternate" type="text/html" href="https://callgraph.eu/changelog/"/>
  <id>https://callgraph.eu/changelog/</id>
  <updated>2026-11-06T00:00:00Z</updated>
  <author><name>Gergő Makra</name></author>
  <icon>https://callgraph.eu/assets/favicon.svg</icon>
  <entry>
    <title>callgraph v0.5.0</title>
    <link rel="alternate" type="text/html" href="https://callgraph.eu/changelog/#v0.5.0"/>
    <link rel="related" type="text/html" href="https://github.com/GeRiY/callgraph/releases/tag/v0.5.0"/>
    <id>https://github.com/GeRiY/callgraph/releases/tag/v0.5.0</id>
    <updated>2026-11-06T00:00:00Z</updated>
    <published>2026-11-06T00:00:00Z</published>
    <content type="html">&lt;h3&gt;Added&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Where to start with a task — &lt;code&gt;locate&lt;/code&gt;:&lt;/b&gt; give it the names and terms from a task in one go (&lt;code&gt;callgraph.sh locate RefundController processRefund refund payment_status checkout.vue&lt;/code&gt;, or the new &lt;code&gt;locate&lt;/code&gt; tool over MCP) and it lists the few files worth opening first, best first, each with the reason: the class or method of that name, the file of that name, a name that contains the word (&lt;code&gt;refund&lt;/code&gt; → &lt;code&gt;RefundJob&lt;/code&gt;, &lt;code&gt;refunds_table&lt;/code&gt;), a text such as a column name or route, or a call to it. It answers from the project map without reading the code again, so it is quick. A file that matches several of your terms comes before one that matches a single term many times. It shows 5 files (&lt;code&gt;--all&lt;/code&gt; for every match) and says which terms found nothing and which are too general. The skill and MCP instructions now also tell agents when to use it, and when plain text search (grep) is the better tool.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Project profile:&lt;/b&gt; &lt;code&gt;callgraph.sh profile&lt;/code&gt; tells you in about 15 lines how an unfamiliar project is built: the architecture (Laravel / Yii layered MVC, DDD / hexagonal, Vue / React frontend, SwiftUI MVVM, Rust web), which folder holds which layer (controllers, services, repositories, models, components, stores…) with file counts, the design patterns it uses (Repository, Factory, Strategy, Observer…), the folders with no clear role, and whether the layers call each other in the expected direction. It reads folder and file names and checks them against the code graph (&lt;code&gt;extends Controller&lt;/code&gt;, &lt;code&gt;implements *RepositoryInterface&lt;/code&gt;, &lt;code&gt;defineStore&lt;/code&gt;); what it cannot tell stays &quot;unknown&quot;. &lt;code&gt;--full&lt;/code&gt; shows every folder. For AI clients: the &lt;code&gt;project_profile&lt;/code&gt; MCP tool, and a short profile is sent when a client connects.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Layers in queries (opt-in, nothing changes by default):&lt;/b&gt; &lt;code&gt;--layer service&lt;/code&gt; searches only the files of that layer (no need to know the folder names), &lt;code&gt;--layers&lt;/code&gt; groups the summary by layer and marks each file with its role, &lt;code&gt;--by-layer&lt;/code&gt; orders &quot;who calls it?&quot; results by layer, closest to the called code first (also for &lt;code&gt;callers&lt;/code&gt;, and as &lt;code&gt;layer&lt;/code&gt; / &lt;code&gt;by_layer&lt;/code&gt; on the MCP tools). Folder names that say nothing, or are not English, can be mapped in a commit-able &lt;code&gt;.callgraph-layers&lt;/code&gt; file (&lt;code&gt;service = app/Logic&lt;/code&gt;, &lt;code&gt;ignore-role = app/Legacy&lt;/code&gt;).&lt;/li&gt;&lt;li&gt;&lt;b&gt;Exclude extensions per project:&lt;/b&gt; a &lt;code&gt;.callgraphignore&lt;/code&gt; file in the project root (or in any subfolder; the nearest one applies) lists extensions callgraph should skip there, one per line (&lt;code&gt;md&lt;/code&gt;, &lt;code&gt;.json&lt;/code&gt; or &lt;code&gt;*.vue&lt;/code&gt;; &lt;code&gt;#&lt;/code&gt; starts a comment). Commit it, and everyone on the team gets the same results. A file you name directly with an excluded extension is refused with a clear message.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Changed&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Only supported files are processed, more strictly:&lt;/b&gt; callgraph already ignored files with other extensions; now it also skips generated files (&lt;code&gt;package-lock.json&lt;/code&gt;, &lt;code&gt;*.min.js&lt;/code&gt;, &lt;code&gt;*.min.css&lt;/code&gt;) and files with binary content, even when their extension is supported. Naming one of them directly gives a clear reason instead of a result.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Upper-case extensions count:&lt;/b&gt; &lt;code&gt;B.PHP&lt;/code&gt;, &lt;code&gt;App.TS&lt;/code&gt; or &lt;code&gt;Main.Vue&lt;/code&gt; are now processed like their lower-case versions (before, they were silently skipped).&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Fixed&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;A file reached through a symlink is no longer listed twice:&lt;/b&gt; if a symlink pointed to a file inside the project, that file appeared (and was analysed) twice in folder results.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Windows: the short summary shows file names again:&lt;/b&gt; when a folder&#x27;s output was too long and callgraph showed the one-line-per-file summary instead, Windows listed each file with its full path instead of just its name.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>callgraph v0.4.0</title>
    <link rel="alternate" type="text/html" href="https://callgraph.eu/changelog/#v0.4.0"/>
    <link rel="related" type="text/html" href="https://github.com/GeRiY/callgraph/releases/tag/v0.4.0"/>
    <id>https://github.com/GeRiY/callgraph/releases/tag/v0.4.0</id>
    <updated>2026-11-06T00:00:00Z</updated>
    <published>2026-11-06T00:00:00Z</published>
    <content type="html">&lt;h3&gt;Added&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Refresh the project map ahead of time:&lt;/b&gt; &lt;code&gt;callgraph.sh refresh&lt;/code&gt; brings the project map in &lt;code&gt;.callgraph/&lt;/code&gt; up to date right away — every changed, new or deleted file, or only the files / folders you name — and prints a one-line summary. Handy after a &lt;code&gt;git pull&lt;/code&gt; or after an agent wrote many files: the next query no longer has to re-analyse them. &lt;code&gt;--background&lt;/code&gt; returns at once and does the work in a separate process. Two refreshes never work on the same project at the same time; if one is already running, the other simply skips.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Optional Claude Code hook:&lt;/b&gt; after Claude edits or writes a file, callgraph refreshes that file in the background, so the next question about it is answered instantly. The installer asks whether to add it (&lt;code&gt;install.sh --hooks&lt;/code&gt; adds it without asking); it only adds one entry to &lt;code&gt;~/.claude/settings.json&lt;/code&gt;, keeps all other settings and hooks, and saves a &lt;code&gt;settings.json.bak&lt;/code&gt; backup first. Check or remove it any time: &lt;code&gt;callgraph.sh hook status&lt;/code&gt; / &lt;code&gt;callgraph.sh hook uninstall&lt;/code&gt;. It does nothing outside registered projects (or ones that already have a &lt;code&gt;.callgraph/&lt;/code&gt; folder).&lt;/li&gt;&lt;li&gt;&lt;b&gt;The MCP server keeps itself up to date:&lt;/b&gt; while &lt;code&gt;callgraph mcp&lt;/code&gt; runs, it watches the projects it has opened and refreshes changed files a moment after they are saved, so queries stay fast. The answers are exactly the same as before. If watching is not possible on a system, it says so once and works as before. To switch it off, set &lt;code&gt;CALLGRAPH_WATCH=0&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;b&gt;The MCP server explains itself:&lt;/b&gt; AI tools that use callgraph through MCP (Claude Code, Claude Desktop, Cursor, VS Code) now get a short usage guide when they connect, in your language: which tool to use when, how to find every caller of a function, and how to read the answers. A new &lt;code&gt;guide&lt;/code&gt; tool gives them the full manual on request. The tool descriptions now each carry an example and the most common mistake to avoid. The guide is made from the same text as the skill&#x27;s &lt;code&gt;SKILL.md&lt;/code&gt;, so the two always say the same thing.&lt;/li&gt;&lt;li&gt;&lt;b&gt;The installer can set up the MCP server for Claude Code:&lt;/b&gt; if the &lt;code&gt;claude&lt;/code&gt; command is available, &lt;code&gt;install.sh&lt;/code&gt; asks whether to register callgraph as an MCP server (&lt;code&gt;install.sh --mcp&lt;/code&gt; does it without asking, &lt;code&gt;--no-mcp&lt;/code&gt; skips it). Running it again does not create duplicates. It prints how to remove it (&lt;code&gt;claude mcp remove -s user callgraph&lt;/code&gt;) and where to find the setup for Claude Desktop, Cursor and VS Code. If this step fails, the rest of the install still completes. The installer now ends with a reminder to restart Claude Code.&lt;/li&gt;&lt;li&gt;&lt;b&gt;The MCP server can update itself:&lt;/b&gt; add &lt;code&gt;--auto-update&lt;/code&gt; to the server&#x27;s arguments in your AI tool&#x27;s MCP settings (&lt;code&gt;&quot;args&quot;: [&quot;mcp&quot;, &quot;--auto-update&quot;]&lt;/code&gt;, recommended). When the tool starts the server — at most once a day — it checks for a newer callgraph release, downloads it, checks that the file is exactly the published one (it never installs a file whose checksum does not match), installs it just like &lt;code&gt;callgraph.sh update&lt;/code&gt; (your projects and settings are kept) and restarts itself, so the tool works with the new version right away. If anything goes wrong (no internet, GitHub limit, a bad download, no write permission) it simply starts the version you have and writes one line to the tool&#x27;s log. It only writes into callgraph&#x27;s own folder, never into your projects.&lt;/li&gt;&lt;li&gt;&lt;b&gt;The MCP server tells you about updates:&lt;/b&gt; without &lt;code&gt;--auto-update&lt;/code&gt;, the server checks for a newer release at most once a day in the background (it never makes a request wait) and adds one line to the first answer of the session: &lt;code&gt;ℹ callgraph X is available (installed: Y) — update: …/callgraph.sh update, or add --auto-update to the MCP config&lt;/code&gt;. &lt;code&gt;CALLGRAPH_UPDATE_CHECK=0&lt;/code&gt; turns off all update checks (no network at all); they are also off in CI.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Changed&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Comments inside a method stay in &lt;code&gt;--body&lt;/code&gt;:&lt;/b&gt; the short method view used to hide comment lines inside the method too, so an agent could think a line was missing and read the file again. Now only the docblock above the method and blank lines are left out; comments inside the method (they often explain the intent) are shown. When a docblock was left out, the header line says so, e.g. &lt;code&gt;(docblock L112-119 omitted: --doc)&lt;/code&gt;. &lt;code&gt;--doc&lt;/code&gt; still adds the docblock, &lt;code&gt;--raw&lt;/code&gt; still prints the exact source. The MCP &lt;code&gt;method_body&lt;/code&gt; tool works the same way.&lt;/li&gt;&lt;li&gt;The project website has its own domain: &lt;a href=&quot;https://callgraph.eu&quot;&gt;https://callgraph.eu&lt;/a&gt; (the old &lt;code&gt;geriy.github.io/callgraph&lt;/code&gt; address redirects).&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Fixed&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;&quot;Who calls it&quot; now finds calls from child classes:&lt;/b&gt; searching for a method with its class name (&lt;code&gt;--grep FrontendController::redirectToNewDashboard&lt;/code&gt;, or the MCP &lt;code&gt;find_callers&lt;/code&gt; tool) missed the places where a child class calls the inherited method as &lt;code&gt;$this-&amp;gt;redirectToNewDashboard()&lt;/code&gt; — only the bare method name found them. Now these calls are found too, marked with the child class (&lt;code&gt;L139 via EventeditController │ …&lt;/code&gt;). A child class that has its own version of the method is not counted, because its call runs its own version.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>callgraph v0.3.0</title>
    <link rel="alternate" type="text/html" href="https://callgraph.eu/changelog/#v0.3.0"/>
    <link rel="related" type="text/html" href="https://github.com/GeRiY/callgraph/releases/tag/v0.3.0"/>
    <id>https://github.com/GeRiY/callgraph/releases/tag/v0.3.0</id>
    <updated>2026-11-06T00:00:00Z</updated>
    <published>2026-11-06T00:00:00Z</published>
    <content type="html">&lt;h3&gt;Changed&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Faster queries on big projects:&lt;/b&gt; callgraph now keeps a compact project map in &lt;code&gt;.callgraph/&lt;/code&gt; in just three files, however big the project is: a short list of all files, one file with every file&#x27;s full analysis, and one with the summary that searches need. It is updated file by file, only for files that changed since the last query (deleted or renamed files drop out). &quot;Where is it called&quot; (&lt;code&gt;--grep&lt;/code&gt;, every &lt;code&gt;--depth&lt;/code&gt; level), &lt;code&gt;callers&lt;/code&gt;, &lt;code&gt;--strings&lt;/code&gt; and &lt;code&gt;--const&lt;/code&gt; are answered from the summary file in one read; a single-file view (outline, &lt;code&gt;--body&lt;/code&gt; …) reads just that file&#x27;s part of the full-analysis file. The output is exactly the same as before. An edited file shows up in the very next query; anything damaged or written by another callgraph version is rebuilt quietly. The map replaces the old analysis cache (&lt;code&gt;cache.jsonl&lt;/code&gt;), which is removed automatically, so the folder takes less space than before. The MCP server (&lt;code&gt;callgraph mcp&lt;/code&gt;) keeps the map in memory between requests. To switch it off (e.g. to compare), set &lt;code&gt;CALLGRAPH_NO_GRAPH=1&lt;/code&gt;. Details: &lt;code&gt;docs/PROJECT-GRAPH.md&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Shorter call lists in &quot;where is it called&quot; results:&lt;/b&gt; when one caller method makes the same call on several lines with the very same source text, it is now shown once with all its line numbers, e.g. &lt;code&gt;L12, L40 │ $this-&amp;gt;repo-&amp;gt;find($id)&lt;/code&gt;. Each caller shows at most 3 such rows; the rest are listed by line number only: &lt;code&gt;… +2 more: L55, L61&lt;/code&gt;. This applies to &lt;code&gt;--grep&lt;/code&gt;, the first &lt;code&gt;--depth&lt;/code&gt; level and the one-line-per-call view used when the result would be too long. Calls through an interface stay on their own row (&lt;code&gt;via …&lt;/code&gt;).&lt;/li&gt;&lt;li&gt;&lt;b&gt;Shorter method bodies:&lt;/b&gt; &lt;code&gt;--body&lt;/code&gt; now leaves out what an agent rarely needs: the docblock / doc comments above the method, blank lines and lines that are only a comment. Code lines are printed exactly as written (a comment at the end of a code line stays), and nothing inside a string, heredoc or template literal is ever removed. The line numbers are still the real ones, so a gap shows where lines were skipped and you can still read an exact range. Attributes such as &lt;code&gt;#[test]&lt;/code&gt; / &lt;code&gt;#[Route(...)]&lt;/code&gt; are kept. Works for PHP, JS / TS / Vue, Rust and Swift, for several methods at once and for &lt;code&gt;--grep … --body&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;New &lt;code&gt;--doc&lt;/code&gt; adds the docblock back; new &lt;code&gt;--raw&lt;/code&gt; prints the exact, unfiltered source (as before, plus Rust / Swift doc comments and attributes). The MCP &lt;code&gt;method_body&lt;/code&gt; tool follows the same default and has &lt;code&gt;doc&lt;/code&gt; / &lt;code&gt;raw&lt;/code&gt; options.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Added&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Notes on files and methods (pilot):&lt;/b&gt; &lt;code&gt;callgraph note add &amp;lt;file&amp;gt;[::&amp;lt;method&amp;gt;] &quot;&amp;lt;text&amp;gt;&quot;&lt;/code&gt; (also &lt;code&gt;callgraph.sh note …&lt;/code&gt;) attaches a short note, stored outside the source in &lt;code&gt;&amp;lt;project&amp;gt;/.callgraph/notes.jsonl&lt;/code&gt; (git-ignored) with the date and time (UTC). The outline shows it under the file header or the method (&lt;code&gt;📝 2026-11-05 20:27 · text&lt;/code&gt;, newest first, at most 3), &lt;code&gt;--body&lt;/code&gt; above the method source. &lt;code&gt;note list [&amp;lt;path&amp;gt;]&lt;/code&gt; lists them (with &lt;code&gt;[orphaned]&lt;/code&gt; when the method is gone), &lt;code&gt;note rm &amp;lt;id&amp;gt;&lt;/code&gt; deletes one, and &lt;code&gt;show &amp;lt;dir&amp;gt; --notes &amp;lt;pattern&amp;gt;&lt;/code&gt; searches them. The anchor is the method name, not a line number. MCP: a new read-only &lt;code&gt;notes&lt;/code&gt; tool (there is no write tool). Without notes the output is unchanged. Details: &lt;code&gt;docs/NOTES.md&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;b&gt;TypeScript: calls through typed objects and interfaces.&lt;/b&gt; callgraph now works out which class a TS method call goes to when the type is written down: a typed parameter (&lt;code&gt;repo: Repo&lt;/code&gt;), a typed class property (&lt;code&gt;private repo: Repo&lt;/code&gt;, also &lt;code&gt;constructor(private repo: Repo)&lt;/code&gt;), &lt;code&gt;this.repo = new Repo()&lt;/code&gt; or &lt;code&gt;const x = new Repo()&lt;/code&gt;. So &lt;code&gt;this.repo.find()&lt;/code&gt; shows up as &lt;code&gt;Repo::find&lt;/code&gt;, and &lt;code&gt;--grep &#x27;Repo::find&#x27;&lt;/code&gt; finds it. Classes record their &lt;code&gt;implements&lt;/code&gt;, and TS interfaces (&lt;code&gt;interface X extends Y&lt;/code&gt;) appear in the map, so searching &lt;code&gt;PlaylistResolver::getPlayables&lt;/code&gt; also finds calls made through its &lt;code&gt;Resolver&lt;/code&gt; interface, marked &lt;code&gt;via Resolver&lt;/code&gt; (in &lt;code&gt;--depth&lt;/code&gt; and &lt;code&gt;callers&lt;/code&gt; too). When the type is unclear (no type, &lt;code&gt;any&lt;/code&gt;, a union like &lt;code&gt;Repo | null&lt;/code&gt;, a generic &lt;code&gt;T&lt;/code&gt;, or different values in the same function) the call stays as before.&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;code&gt;--const&lt;/code&gt; lists re-exports:&lt;/b&gt; besides references and definitions, &lt;code&gt;--const NAME&lt;/code&gt; now shows where a name is passed on, marked &lt;code&gt;[re-export]&lt;/code&gt;: Rust &lt;code&gt;pub use state::{CheckState, STATE_FILE};&lt;/code&gt; / &lt;code&gt;pub(crate) use …&lt;/code&gt;, JS / TS &lt;code&gt;export { NAME } from &#x27;./x&#x27;&lt;/code&gt; / &lt;code&gt;export { NAME }&lt;/code&gt;, PHP &lt;code&gt;use const App\NAME;&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Fixed&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;--grep &amp;lt;pattern&amp;gt; --body&lt;/code&gt; prints the source of the caller methods again (the option was ignored).&lt;/li&gt;&lt;li&gt;MCP &lt;code&gt;method_body&lt;/code&gt;: &lt;code&gt;method&lt;/code&gt; may be a single name as a plain string as well as a list (some clients send &lt;code&gt;&quot;method&quot;: &quot;parse&quot;&lt;/code&gt;, which used to fail with an &quot;expected a sequence&quot; error).&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Fixed&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;JS/TS: no more doubled methods when a class is named like its file&lt;/b&gt; (&lt;code&gt;PlaylistResolver.ts&lt;/code&gt; with &lt;code&gt;class PlaylistResolver&lt;/code&gt;): the class&#x27;s methods were listed twice, once under the file&#x27;s &lt;code&gt;module&lt;/code&gt; entry and once under the class. Now class members appear only under the class and top-level functions only under the module.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>callgraph v0.2.0</title>
    <link rel="alternate" type="text/html" href="https://callgraph.eu/changelog/#v0.2.0"/>
    <link rel="related" type="text/html" href="https://github.com/GeRiY/callgraph/releases/tag/v0.2.0"/>
    <id>https://github.com/GeRiY/callgraph/releases/tag/v0.2.0</id>
    <updated>2026-11-05T00:00:00Z</updated>
    <published>2026-11-05T00:00:00Z</published>
    <content type="html">&lt;h3&gt;Added&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Background update check:&lt;/b&gt; at most once a day &lt;code&gt;callgraph.sh&lt;/code&gt; checks GitHub in a detached background process (never slows a query down). If a newer release exists, the output ends with one line, once a day: &lt;code&gt;ℹ callgraph X is available (installed: Y) — update: bash …/callgraph.sh update&lt;/code&gt;. Claude Code tells the user and offers the update; it never updates on its own. Opt out with &lt;code&gt;CALLGRAPH_UPDATE_CHECK=0&lt;/code&gt;; off in CI.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Bug reporting via GitHub:&lt;/b&gt; bilingual issue forms (bug report, idea / feedback), a private security report link and &lt;code&gt;SECURITY.md&lt;/code&gt;. Error messages now point to the bug form; &lt;code&gt;feedback.sh show &amp;lt;error-id&amp;gt;&lt;/code&gt; prints the details to paste.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Release checksums:&lt;/b&gt; every release has a &lt;code&gt;SHA256SUMS&lt;/code&gt; asset (&lt;code&gt;sha256sum&lt;/code&gt; format, all assets). &lt;code&gt;update&lt;/code&gt; verifies the downloaded zip&#x27;s SHA-256 before installing and installs nothing on a mismatch; a release without &lt;code&gt;SHA256SUMS&lt;/code&gt; (v0.1.0) is refused unless &lt;code&gt;--insecure-skip-checksum&lt;/code&gt; is given. &lt;code&gt;update --from &amp;lt;zip&amp;gt;&lt;/code&gt; checks &lt;code&gt;--sha256 &amp;lt;hex&amp;gt;&lt;/code&gt; or a &lt;code&gt;SHA256SUMS&lt;/code&gt; next to the zip, otherwise it warns in one line and installs.&lt;/li&gt;&lt;li&gt;&lt;b&gt;MCP server mode:&lt;/b&gt; &lt;code&gt;callgraph mcp&lt;/code&gt; runs a Model Context Protocol server on stdio (official Rust SDK &lt;code&gt;rmcp&lt;/code&gt;), so Claude Desktop, Cursor, VS Code or any MCP client can use callgraph. Tools: &lt;code&gt;outline&lt;/code&gt;, &lt;code&gt;method_body&lt;/code&gt;, &lt;code&gt;find_callers&lt;/code&gt;, &lt;code&gt;search&lt;/code&gt;, &lt;code&gt;framework_view&lt;/code&gt;, &lt;code&gt;projects&lt;/code&gt; — the same compact text and output cap as the CLI. Read-only, no network, paths confined to the project root. The skill / CLI usage is unchanged. Setup recipes: &lt;code&gt;docs/MCP.md&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;b&gt;See how something is called:&lt;/b&gt; &quot;where is it called&quot; results (&lt;code&gt;--grep&lt;/code&gt;, and every level of &lt;code&gt;--depth&lt;/code&gt;) now show the call&#x27;s own source line next to its line number, e.g. &lt;code&gt;L25 │ $this-&amp;gt;repo-&amp;gt;find($id)&lt;/code&gt; — no extra &lt;code&gt;--body&lt;/code&gt; call needed just to see the arguments.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Calls through interfaces and traits:&lt;/b&gt; searching a class method (&lt;code&gt;--grep &#x27;PlaylistResolver::getPlayables&#x27;&lt;/code&gt;) also finds the calls made through its interface, abstract parent or trait (and, the other way round, through subclasses that don&#x27;t override it). These are marked, e.g. &lt;code&gt;L14 via Resolver │ …&lt;/code&gt;; &lt;code&gt;--depth&lt;/code&gt; follows them to the next level, and &lt;code&gt;callers&lt;/code&gt; adds a &lt;code&gt;&quot;via&quot;&lt;/code&gt; field. Works where the call&#x27;s receiver type is known (PHP: typed properties and other resolved receivers; Rust: &lt;code&gt;Type::method&lt;/code&gt; calls); JS/TS interfaces and Swift protocols are not tracked yet.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Rust: smarter method calls.&lt;/b&gt; For &lt;code&gt;x.load()&lt;/code&gt; callgraph now works out the type of &lt;code&gt;x&lt;/code&gt; in the simple cases (parameter type, &lt;code&gt;let x = Repo::new()&lt;/code&gt;, &lt;code&gt;Repo { … }&lt;/code&gt;, &lt;code&gt;self&lt;/code&gt;, a field of your own struct like &lt;code&gt;self.repo&lt;/code&gt;), so the call shows up as &lt;code&gt;Repo::load&lt;/code&gt; and &quot;who calls &lt;code&gt;Repo::load&lt;/code&gt;?&quot; finds it. When the type can&#x27;t be worked out, the call is kept as &lt;code&gt;?::load&lt;/code&gt; and a &lt;code&gt;Repo::load&lt;/code&gt; search still lists it, marked as uncertain — instead of silently missing it.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Rust constants:&lt;/b&gt; &lt;code&gt;--const&lt;/code&gt; now finds Rust &lt;code&gt;const&lt;/code&gt; / &lt;code&gt;static&lt;/code&gt; items — where they are defined and where they are used (also &lt;code&gt;Type::CONST&lt;/code&gt;).&lt;/li&gt;&lt;li&gt;&lt;b&gt;JS / TS object methods:&lt;/b&gt; functions inside an object literal (&lt;code&gt;const api = { fetch() {}, save: () =&amp;gt; {} }&lt;/code&gt;, or a plain &lt;code&gt;export default { … }&lt;/code&gt;) are listed as separate methods (&lt;code&gt;api.fetch&lt;/code&gt;) with their line ranges, and calls to them are found.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Changed&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Shorter result lists:&lt;/b&gt; when the project root would repeat on many lines (&lt;code&gt;--grep&lt;/code&gt;, &lt;code&gt;--depth&lt;/code&gt;, &lt;code&gt;--strings&lt;/code&gt;, &lt;code&gt;--const&lt;/code&gt;, folder outlines, framework views…), the first line is now &lt;code&gt;root: /abs/path/to/project&lt;/code&gt; and every path after it is relative to that root. Outputs with a single path, and the machine formats (&lt;code&gt;json&lt;/code&gt;, &lt;code&gt;mermaid&lt;/code&gt;, &lt;code&gt;dot&lt;/code&gt;, &lt;code&gt;callers&lt;/code&gt;), are unchanged.&lt;/li&gt;&lt;li&gt;&lt;code&gt;SKILL.md&lt;/code&gt; now recommends finding callers by name (&lt;code&gt;--grep &#x27;(^|::|\.|-&amp;gt;)name$&#x27;&lt;/code&gt;), which also catches inherited, trait and unknown-receiver calls; &lt;code&gt;Type::method&lt;/code&gt; is for narrowing a common name. It also explains the new search output (&lt;code&gt;root:&lt;/code&gt; line, &lt;code&gt;L&amp;lt;n&amp;gt; │ code&lt;/code&gt;, &lt;code&gt;via&lt;/code&gt;, &lt;code&gt;?::&lt;/code&gt;) and the new Rust / JS options.&lt;/li&gt;&lt;li&gt;&lt;code&gt;--const&lt;/code&gt; also lists the matching constant definitions (marked &lt;code&gt;[definition]&lt;/code&gt;), not only the references.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Fixed&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Windows: the project root is printed as &lt;code&gt;C:\…&lt;/code&gt; instead of &lt;code&gt;\\?\C:\…&lt;/code&gt; in search output.&lt;/li&gt;&lt;li&gt;A bare method selector also finds an object-literal method: &lt;code&gt;store.ts::updateSongs&lt;/code&gt; selects &lt;code&gt;playableStore.updateSongs&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code&gt;--grep … --depth&lt;/code&gt;: from level 2 on, callers are searched in the whole project (from the project root), not only in the folders of the level-1 matches — callers in other folders were missed.&lt;/li&gt;&lt;li&gt;Rust &lt;code&gt;--format api&lt;/code&gt; now lists the &lt;code&gt;pub fn&lt;/code&gt; methods of &lt;code&gt;impl&lt;/code&gt; blocks (and trait implementations), the &lt;code&gt;pub&lt;/code&gt; constants and fields — before, it showed no public methods for Rust types.&lt;/li&gt;&lt;li&gt;&lt;code&gt;--strings&lt;/code&gt; now finds texts inside Vue template expressions (&lt;code&gt;{{ … }}&lt;/code&gt;, &lt;code&gt;:title=&quot;…&quot;&lt;/code&gt;, &lt;code&gt;@click=&quot;…&quot;&lt;/code&gt;) and in Rust &lt;code&gt;const&lt;/code&gt; / &lt;code&gt;static&lt;/code&gt; values, including byte strings (&lt;code&gt;b&quot;…&quot;&lt;/code&gt;).&lt;/li&gt;&lt;li&gt;SCSS: &lt;code&gt;@mixin&lt;/code&gt; / &lt;code&gt;@function&lt;/code&gt; parameters (&lt;code&gt;$color: t.$brand, …&lt;/code&gt;) and &lt;code&gt;@include&lt;/code&gt; keyword arguments were listed as constants; now only &lt;code&gt;$var: value;&lt;/code&gt; declarations are (the parameters stay the mixin&#x27;s params).&lt;/li&gt;&lt;li&gt;&lt;code&gt;update --check&lt;/code&gt; now also records its result in &lt;code&gt;update-check.json&lt;/code&gt;, so the daily background check does not repeat it and a newer version found manually shows up in the notice.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>callgraph v0.1.0</title>
    <link rel="alternate" type="text/html" href="https://callgraph.eu/changelog/#v0.1.0"/>
    <link rel="related" type="text/html" href="https://github.com/GeRiY/callgraph/releases/tag/v0.1.0"/>
    <id>https://github.com/GeRiY/callgraph/releases/tag/v0.1.0</id>
    <updated>2026-11-05T00:00:00Z</updated>
    <published>2026-11-05T00:00:00Z</published>
    <content type="html">&lt;p&gt;First release.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Languages: PHP, JavaScript / TypeScript, Vue, &lt;b&gt;Rust&lt;/b&gt;, &lt;b&gt;Swift / SwiftUI&lt;/b&gt;, CSS / SCSS, JSON, Markdown.&lt;/li&gt;&lt;li&gt;Structure, categorized call graph, method bodies, &quot;who calls this?&quot; and impact analysis (&lt;code&gt;--grep --depth&lt;/code&gt;), framework views (Laravel / Yii), many output formats.&lt;/li&gt;&lt;li&gt;English or Hungarian output (&lt;code&gt;callgraph.sh set-lang en|hu&lt;/code&gt;).&lt;/li&gt;&lt;li&gt;Built-in update: &lt;code&gt;callgraph --version&lt;/code&gt;, &lt;code&gt;callgraph.sh update [--check|--force]&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Prebuilt packages for macOS (arm64, x86_64), Linux (x86_64, ARM64, static musl) and Windows.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
</feed>
