Skip to content

Releases: nRafinia/CsMesh

v0.11.0

Choose a tag to compare

@github-actions github-actions released this 05 Oct 11:08
0dc214d

csmesh 0.11.0

Upgrade note

The graph format moves to v15. An index built by 0.10.x is rejected on load (exit 4):
run csmesh index --full once. review baselines are invalidated the same way; run
csmesh review --accept after the first review on 0.11.0.

Freshness

  • A file edited without changing its size, within two seconds of being indexed, was
    treated as fresh. Under default heal, that meant a stale answer with no [STALE]
    marker. Each stamp now carries a SHA-256 of the bytes that were parsed. Inside the
    mtime tolerance, the hash decides. An exact mtime match still costs no file read.
  • Files are stamped before they are read, so a write that lands mid-index can no longer
    hide behind a fresh-looking stamp.

Answers that say what they left out

  • INCOMPLETE now states rows shown out of the total, e.g. 12 of 95 reached member(s) shown, and suggests a budget that fits the whole answer. The old line
    could say "nearly complete" with most rows missing, and suggest a budget that
    overflowed again.
  • context reports members past the 20-row cap (… 14 more member(s)), with a
    matching withheld_members field in --json.
  • where labels a member that matches only through its type's name [container], and
    ranks it below the type itself.

MCP

  • initialize instructions now carry the prefer-csmesh-over-grep directive and the
    "you are about to → run instead" table, from the same source as the installed skill.
    This matters in repositories with no AGENTS.md: there, the server's instructions are
    the only rules an agent sees.
  • Shared parameters (project, heal, repo, budget, under, depth) are
    described once. tools/list drops from 5,059 to 2,899 tokens. Instructions plus
    catalogue together go from 5,368 to 3,865 tokens resident per session.

Exit codes are unchanged.


📦 Installation & Upgrades

Global .NET Tool

dotnet tool update --global CsMesh

Automatic One-Line Install Script

Linux & macOS:

curl -fsSL https://raw.githubusercontent.com/nRafinia/CsMesh/main/install.sh | sh

Windows (PowerShell):

irm https://raw.githubusercontent.com/nRafinia/CsMesh/main/install.ps1 | iex
winget install nRafinia.CsMesh

Quick Setup for AI Assistants

# Install skills and register MCP server in one command:
csmesh install -g --all
csmesh index --full

v0.10.1

Choose a tag to compare

@github-actions github-actions released this 02 Oct 08:49
a79dc47

0.10.1

Fixes for csmesh run outside a git repository.

  • Root detection no longer stops at a .csmesh folder that holds no index. Before,
    a stray .csmesh in a parent directory (for example the user home) became the root
    for every unmarked folder beneath it, and index there could fail with exit 70.
  • Telemetry no longer creates a .csmesh folder. A failed command in a plain folder
    used to leave one behind, which then triggered the problem above.
  • Indexing skips a directory it cannot read instead of failing the whole run.
  • The MCP server picks a workspace root that holds an index or a C# project, not one
    that only holds a stray .csmesh.

If you have a .csmesh folder in your home directory with no graph.json in it,
you can delete it.


📦 Installation & Upgrades

Global .NET Tool

dotnet tool update --global CsMesh

Automatic One-Line Install Script

Linux & macOS:

curl -fsSL https://raw.githubusercontent.com/nRafinia/CsMesh/main/install.sh | sh

Windows (PowerShell):

irm https://raw.githubusercontent.com/nRafinia/CsMesh/main/install.ps1 | iex

Quick Setup for AI Assistants

# Install skills and register MCP server in one command:
csmesh install -g --all
csmesh index --full

v0.10.0

Choose a tag to compare

@github-actions github-actions released this 26 Sep 13:52
52a4c7a

0.10.0

Stale rows now heal by default. A query that finds edited files rebinds them before
answering; --no-heal or CSMESH_AUTO_INDEX=0 opts out. The MCP query tools take a
heal argument (default true).

  • A default heal never waits for the index lock. If another process holds it, the query
    answers from the current graph with a heal skipped: index busy note, exit 0.
  • An explicit --heal waits for the lock and exits 75 if it cannot take it.
  • index exits 75 when the lock stays held, instead of writing the graph unlocked after
    the wait. Before this release two concurrent writers could both write.

📦 Installation & Upgrades

Global .NET Tool

dotnet tool update --global CsMesh

Automatic One-Line Install Script

Linux & macOS:

curl -fsSL https://raw.githubusercontent.com/nRafinia/CsMesh/main/install.sh | sh

Windows (PowerShell):

irm https://raw.githubusercontent.com/nRafinia/CsMesh/main/install.ps1 | iex

Quick Setup for AI Assistants

# Install skills and register MCP server in one command:
csmesh install -g --all
csmesh index --full

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 26 Sep 11:24
672a2f9

Changed

  • Declarations print their full span. Every row that points at a declaration now reads
    path:start-end instead of path:line, so the next read can be exactly that range
    instead of the whole file. A single-line declaration stays path:line. Wiring sites
    (@ Api/Registrations.cs:22) are still one line: they point at a call or a
    registration, not a declaration. The cost is small: on a 29-project solution the
    where, context and blast-radius answers grew by 2, 13 and 25 tokens.
  • The skill text tells agents to read that range. Run csmesh install after upgrading
    so the instruction blocks in your agent files pick it up.

Added

  • --json rows carry end_line next to line. No field was renamed or removed, and exit
    codes are unchanged.

Upgrade

dotnet tool update -g CsMesh
npm i -g @nrafinia/csmesh
csmesh install

The graph format is unchanged (v14); existing indexes load as they are.


📦 Installation & Upgrades

Global .NET Tool

dotnet tool update --global CsMesh

Automatic One-Line Install Script

Linux & macOS:

curl -fsSL https://raw.githubusercontent.com/nRafinia/CsMesh/main/install.sh | sh

Windows (PowerShell):

irm https://raw.githubusercontent.com/nRafinia/CsMesh/main/install.ps1 | iex

Quick Setup for AI Assistants

# Install skills and register MCP server in one command:
csmesh install -g --all
csmesh index --full

v0.8.2

Choose a tag to compare

@github-actions github-actions released this 26 Sep 09:56
7601230

Added

  • Solution scope warning. csmesh doctor and csmesh index now say when a solution
    file was found but did not fully decide which projects are indexed: some listed project
    paths match nothing on disk, none do, the solution lists no project, or it cannot be read.
    The line names the solution, how many of its paths matched, and the first one that did
    not, as written in the file:

    solution        App.slnx: 2 of 3 project path(s) matched on disk (first unmatched: src/Old/Old.csproj)
    

    When the result was a fallback to the ProjectReference closure, the line says so. Before
    this, the fallback was silent. --json carries the same data as solution_findings on
    both reports; the field is new, no existing field changed, and exit codes are unchanged.

Fixed

  • Spurious incremental run after the first index. In a repository where the solution
    leaves some projects out of scope, the run after a first full index could come back
    incremental instead of current. Two causes, both fixed: the index created its own
    .csmesh/ directory after stamping the repository root, so it moved the stamp it checks
    next time; and the new-file check walked out-of-scope projects and reported their files as
    new. Nothing out of scope ever entered the graph; the cost was one needless rebind.

Upgrade

dotnet tool update -g CsMesh
npm i -g @nrafinia/csmesh

The graph format is unchanged (v14); existing indexes load as they are.


📦 Installation & Upgrades

Global .NET Tool

dotnet tool update --global CsMesh

Automatic One-Line Install Script

Linux & macOS:

curl -fsSL https://raw.githubusercontent.com/nRafinia/CsMesh/main/install.sh | sh

Windows (PowerShell):

irm https://raw.githubusercontent.com/nRafinia/CsMesh/main/install.ps1 | iex

Quick Setup for AI Assistants

# Install skills and register MCP server in one command:
csmesh install -g --all
csmesh index --full

v0.8.1

Choose a tag to compare

@github-actions github-actions released this 25 Sep 13:50
dd2886a

Fixed

  • Solution scope on Linux and macOS. Project paths inside a .sln use backslashes
    (Visual Studio and dotnet sln add write them that way on every OS). On Linux and macOS
    they were combined with the solution directory unconverted, matched no project on disk,
    and scope silently fell back to the ProjectReference closure. A project listed in the
    solution but not reachable by ProjectReference from an executable or test project was
    left out of the index. A .slnx with backslash paths had the same problem. Windows was
    not affected.

Check whether you were affected

Run csmesh doctor on the affected machine. Before this fix the scope line read
ProjectReference closure from N root(s) where it should name your solution file.

Upgrade

dotnet tool update -g CsMesh
npm i -g @nrafinia/csmesh

The graph format is unchanged (v14), so existing indexes still load. On Linux or macOS,
run csmesh index --full once after upgrading so the scope is decided again from the
solution file.

📦 Installation & Upgrades

Global .NET Tool

dotnet tool update --global CsMesh

Automatic One-Line Install Script

Linux & macOS:

curl -fsSL https://raw.githubusercontent.com/nRafinia/CsMesh/main/install.sh | sh

Windows (PowerShell):

irm https://raw.githubusercontent.com/nRafinia/CsMesh/main/install.ps1 | iex

Quick Setup for AI Assistants

# Install skills and register MCP server in one command:
csmesh install -g --all
csmesh index --full

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 25 Sep 12:56
604422d

CsMesh 0.8.0

Graph format is still v14. Existing indexes keep working; no reindex is required, with one
exception noted under doctor.

Upgrade

dotnet tool update -g CsMesh
npm install -g @nrafinia/csmesh
csmesh install      # refreshes the generated agent instruction blocks

New: csmesh export

Renders the graph as Mermaid or DOT at three levels:

csmesh export --level project   --format mermaid
csmesh export --level namespace --format dot --out docs/namespaces.dot
csmesh export --level neighbourhood "OrderService.Submit" --depth 1 --direction out
  • Without --out, the diagram goes to stdout under the budget (default 1500). If it does
    not fit, the command exits 2 and names the remedy: --out, a coarser --level, or a
    smaller --depth.
  • With --out, the full diagram is written atomically and stdout carries only a short
    summary: node and edge counts plus what was withheld. The path must be inside the
    repository (exit 64 otherwise).
  • Node ids are derived from the symbol's identity, so a committed diagram changes only
    where the code changed.
  • Call edges are plain arrows. Other kinds are labelled (di, iface, override,
    mediatr, construct, route, typeuse); write access is dashed.
  • By default, test code, TypeUse edges, compiler-synthesized tuple and anonymous types,
    and edges inside a single project or namespace are withheld and counted in the summary.
    --include-tests and --all-edges bring the first two back.
  • Namespace buckets use the namespace of the outermost containing type; nested types never
    appear as namespaces.
  • Available over MCP as the export tool, which returns the summary.

Design and trade-offs: docs/adr/0004-csmesh-export.md.

Selecting one overload

When two overloads of a member live in the same project, --project cannot tell them
apart. Exit 3 now prints a selector for each candidate. Pass it back quoted:

csmesh trace "CheckoutService.Apply(int,string)"

The parameter list must match exactly: same arity, same ref/out/in. Short type
names, Int32/int style aliases and nullable value types are accepted. A selector
works wherever a symbol does (trace, impl, blast-radius, context, path,
silence). If no overload matches, silence with the same selector lists the ones that
exist. An unclosed ( is exit 64 with a reminder to quote.

doctor

Two new warnings, each naming the project and the fix:

  • Source-generator output not on disk (CS8795). Members a generator would supply stay
    unbound. Set EmitCompilerGeneratedFiles=true and build.
  • PackageReference to a project in the same solution. That project's types are not
    bound through the package. Use a ProjectReference.

The generator warning reads diagnostics captured at index time. On a project with many
compiler errors, run csmesh index --full once so the index records it.

Smaller changes

  • csmesh where <term> --unranked lists every match in stable order, without entrypoint
    ranking.
  • usage.jsonl records carry schema_version: 2. Lines without it read as version 1, and
    lines written by 0.0.1 in PascalCase are read again instead of being dropped.
  • review keeps its five most recent base caches and drops caches for the same revision
    built against an older reference set.
  • The release workflow passes dispatch inputs through environment variables instead of
    interpolating them into scripts.

📦 Installation & Upgrades

Global .NET Tool

dotnet tool update --global CsMesh

Automatic One-Line Install Script

Linux & macOS:

curl -fsSL https://raw.githubusercontent.com/nRafinia/CsMesh/main/install.sh | sh

Windows (PowerShell):

irm https://raw.githubusercontent.com/nRafinia/CsMesh/main/install.ps1 | iex

Quick Setup for AI Assistants

# Install skills and register MCP server in one command:
csmesh install -g --all
csmesh index --full

v0.7.1

Choose a tag to compare

@github-actions github-actions released this 24 Sep 10:47
f387a38

0.7.1

Package types resolve from restore, not from whatever landed in bin/

Until now csmesh took package assemblies only from bin/. A class library does not copy its
PackageReference closure there, so on library-heavy solutions whether Refit.RestService or a
Hangfire type bound depended on which app project happened to copy it.

0.7.1 reads each in-scope project's obj/project.assets.json, the same resolved graph the compiler
uses, and gives every project its own reference list. On that solution, with bin/ still empty,
unbound call sites drop to 250. A restore is enough; a build is needed only for source-generator
output.

  • Per-project references: a package referenced by one project no longer binds in another, and two
    projects on different versions of a package each compile against their own. Previously every
    compilation saw every assembly under every bin/.
  • Projects without an assets file (never restored) keep the old bin/ behaviour.
  • A restore now marks the index dirty: the next csmesh index runs a full pass instead of
    reporting the tree current, and the review base cache is keyed on the assets files too.
  • Design: docs/adr/0003-package-assemblies-from-assets.md.

doctor

  • The references line reports three sources: runtime, assets, bin/.
  • Unrestored projects are counted and the advice is dotnet restore. The "nothing from bin/, run
    dotnet build" message fires only when neither source supplied packages.
  • The instruction-drift line prints ASCII; the previous arrow rendered as a control picture on the
    Windows console.

skill --install

  • Rewriting an existing file keeps its line endings. A CRLF AGENTS.md used to come back with LF
    lines inside it.
  • The rules block renders as LF regardless of the checkout the binary was built from, so every
    release binary writes the same bytes.
  • Each target path is written once per install. AGENTS.md, shared by several agents, was written
    three times.

📦 Installation & Upgrades

Global .NET Tool

dotnet tool update --global CsMesh

Automatic One-Line Install Script

Linux & macOS:

curl -fsSL https://raw.githubusercontent.com/nRafinia/CsMesh/main/install.sh | sh

Windows (PowerShell):

irm https://raw.githubusercontent.com/nRafinia/CsMesh/main/install.ps1 | iex

Quick Setup for AI Assistants

# Install skills and register MCP server in one command:
csmesh install -g --all
csmesh index --full

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 23 Sep 11:17
53f5207

CsMesh 0.7.0

Breaking: graph format v14

Existing indexes are rejected with exit 4 until you rebuild them:

csmesh index --full

csmesh review baselines built by 0.6.x need one csmesh review --accept after the
upgrade.

Where is this written?

blast-radius --writes answers "who writes this property or field" instead of "who
touches it":

csmesh blast-radius Order.Status --writes --budget 800

Member-access edges now carry a role: Read, Write, Read|Write (compound
assignment, ++/--, ref arguments) or Subscribe (event +=/-=). Writes are
recorded for simple and compound assignment, object initializers, with expressions,
out and ref arguments, deconstruction targets, constructor writes to readonly
fields and init-only properties, and indexer setters. Bare field writes such as
_total = x, which produced no edge at all before, are now recorded.

  • A write through an interface-typed receiver shows up on the implementation with
    [via-interface]. It is one reverse hop, so it can include writers bound to another
    implementation of the same interface member.
  • Events and indexers are graph nodes now. --writes on an event returns no rows and
    points you to blast-radius <event> for its subscribers.
  • Not recorded: writes to members declared only in referenced assemblies, and attribute
    named arguments.

Roles live on the existing call edge, so default changes and review output does not
fill up with write findings after the upgrade. --calls does show a method that moved
from reading a member to writing it.

review: no more false exit 5 on a clean tree

The base revision used to be indexed in a checkout with no bin/. Package types went
unbound, edges dropped out, and review reported structural changes that did not
exist. The base is now compiled against the working tree's reference set.

  • The base-graph cache is keyed on that reference set, so a stale thin base is rebuilt
    instead of reused.
  • When a .csproj, .props, .targets, Directory.Packages.props,
    packages.lock.json, global.json or solution file changed in the reviewed range,
    review prints a warning (reference_inputs_changed in JSON). The exit code does not
    change.

Agent skill

The skill text teaches --writes, drops a repeated paragraph and uses a generic
nested-type example. Refresh installed copies with:

csmesh skill --install

Upgrade

dotnet tool update -g CsMesh
npm install -g @nrafinia/csmesh

then csmesh index --full in each indexed repository.

v0.6.1

Choose a tag to compare

@github-actions github-actions released this 22 Sep 11:46
9faeb57

CsMesh 0.6.1

No graph format change. A 0.6.0 index keeps working, so no re-index is needed.

dotnet tool install now delivers the native binary

Until now the NuGet tool was a framework-dependent build: every run compiled Roslyn through the JIT
from scratch. npx and the install scripts already shipped the Native AOT binary, so only NuGet
users paid for it. CsMesh is now a pointer package, and the .NET 10 SDK picks the native package
for your platform when you install or update.

Measured on the same 29-project solution and machine, in one session, with phase timing on:

0.6.0 dotnet tool 0.6.1 dotnet tool
impl, warm median 185.6 ms 54.1 ms
trace --depth 2, warm median 204.8 ms 47.8 ms
index --full, warm 12.8–15.3 s 1.8–2.1 s
first launch before Main 1.6 s about 0.05 s

Native packages: win-x64, win-arm64, linux-x64, linux-arm64, osx-x64, osx-arm64. Any other
platform gets CsMesh.any, the framework-dependent build, so install and update keep working
there. Each native package is about 13 MB, against 4 MB for the old one.

dotnet tool update -g CsMesh

Updating from 0.6.0 was verified on win-x64.

More platforms

Release archives and the npm package now cover win-arm64, linux-arm64 and osx-x64 as well. Before,
npm exited on those platforms.

Phase timing

CSMESH_TIMINGS=1 writes one line per indexing phase to stderr, with the time from process start to
Main. Nothing reaches stdout, so JSON and MCP output are unaffected. Include it when you report a
slow run.

Docs

Every latency and startup figure now names the channel it was measured on.

📦 Installation & Upgrades

Global .NET Tool

dotnet tool update --global CsMesh

Automatic One-Line Install Script

Linux & macOS:

curl -fsSL https://raw.githubusercontent.com/nRafinia/CsMesh/main/install.sh | sh

Windows (PowerShell):

irm https://raw.githubusercontent.com/nRafinia/CsMesh/main/install.ps1 | iex

Quick Setup for AI Assistants

# Install skills and register MCP server in one command:
csmesh install --all
csmesh index