Diff Two Diagrams
diagrams_diffCompare two diagram sources — two stored files, or a stored file against inline text — and report the added, removed, and renamed entity names in structured form.
Instructions
Compare two diagram sources — two stored files, or a stored file against inline text — and report the added, removed, and renamed entity names in structured form.
This is the review-time companion to diagrams_check_consistency: that tool asks whether a diagram still matches the code, this one asks what changed between two versions of the diagram itself. Give it the previous version as a_relative_path or a_content and the new version as the b side, and it lists what a reviewer needs to confirm. It is pure comparison over sources the store already knows how to read: no writes, no network, no filesystem changes.
Each side supplies exactly one of a path or inline content, so unstaged edits can be diffed without a round trip. Rename detection pairs a removed name with an added one only when they are identical once lowercased and stripped of separators, and every rename carries confidence: "heuristic" — similarity is not semantic identity.
With include_rename_evidence=true the existing rename pairs gain exact case-sensitive recognized diagram message-call counts for each old and new name on both sides. Repeated calls count separately. This scans diagram labels only and does not inspect source code or establish semantic identity. Evidence reports the first 100 pairs in rename order with pairs_available and pairs_capped. Either side above 10000 recognized calls refuses the entire enabled comparison. The evidence does not change rename pairing or is_same or enable call-order output.
Args:
include_rename_evidence (boolean, default false): Add bounded diagram call-label counts for paired rename names without changing matching or equality
compare_call_order (boolean, default false): Also compare recognized message-call names in order, preserving repetitions. Each side is capped at 10000 calls; over-limit comparison is refused. Plain labels, endpoints, arguments and control flow are excluded.
a_relative_path (string, optional): Side a as a path relative to the diagrams root
a_content (string, optional): Side a as inline source text (dialect detected from the source)
b_relative_path (string, optional): Side b as a path relative to the diagrams root
b_content (string, optional): Side b as inline source text (dialect detected from the source)
Exactly one path or content per side; both or neither is an error naming the side
Returns: JSON with schema: { "a": { "source": string, "type": "plantuml" | "mermaid" }, // path, or "" "b": { "source": string, "type": "plantuml" | "mermaid" }, "added": [{ "name": string }], // declared on b only "removed": [{ "name": string }], // declared on a only "renamed": [ // paired by the shared name normalizer { "from": string, "to": string, "confidence": "heuristic" } ], "unchanged": string[], // declared on both, in a's order "unchanged_count": number, "participants_added": string[], // sequence diagrams only; [] otherwise "participants_removed": string[], "calls_added": string[], "calls_removed": string[], "is_same": boolean, // entity names unchanged, and call order unchanged when comparison is enabled "call_order": { "a": string[], "b": string[], "changed": boolean }, // present only when compare_call_order=true "rename_evidence": { // present only when include_rename_evidence=true "pairs": [{ "from": string, "to": string, "a_from_calls": number, "a_to_calls": number, "b_from_calls": number, "b_to_calls": number, "confidence": "heuristic" }], "pairs_available": number, "pairs_capped": boolean, "pair_limit": 100, "call_limit": 10000, "basis": "diagram-message-call-labels" }, "confidence": "heuristic", "heuristic_warning": string }
A paired rename leaves the added/removed lists, so no change is reported twice. The two sides may use different dialects; each is read with its own syntax.
Examples:
Use when: "Did the order or repetition of message calls change?" -> compare_call_order=true with the two diagram sources
Use when: "What changed in this diagram since my last edit?" -> a_relative_path="models/order.puml", b_content=""
Use when: "Compare the stored diagram against the version in my buffer" -> a_relative_path="system/flow.mmd", b_content=""
Don't use when: You want to know whether the diagram still matches the code (use diagrams_check_consistency)
Don't use when: You want member-level, layout, or style differences (out of scope; this tool compares declared names only)
Error Handling:
CallOrderLimitError rejects enabled comparisons exceeding 10000 recognized calls on either side, without returning partial arrays or source text
Returns "Error: Invalid side 'a'|'b': supply exactly one of ..." when a side supplies both or neither of its path and content
Returns "Error: Invalid side 'a'|'b' content: not a recognizable ..." when inline content is neither PlantUML nor Mermaid
Returns "Error: No diagram found at ''" when a stored side does not exist
Returns "Error: Refused to access path outside the diagrams root" when a stored side attempts to escape the diagrams directory
Returns "Error: ... does not have a recognized diagram extension" when a stored path's extension is not .puml/.plantuml/.mmd/.mermaid
Unexpected internal failures return a generic "Error: Unexpected internal error ..." with isError:true and are logged to stderr without source, paths, or secrets
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| a_content | No | Side a as inline source text (no file read). Exactly one of a_relative_path or a_content must be given; the dialect is detected from the source itself. | |
| b_content | No | Side b as inline source text. Exactly one of b_relative_path or b_content must be given; the dialect is detected from the source itself. | |
| a_relative_path | No | Side a as a stored diagram: path relative to the diagrams root (e.g. 'system/order-flow.puml'). Exactly one of a_relative_path or a_content must be given. | |
| b_relative_path | No | Side b as a stored diagram: path relative to the diagrams root. Exactly one of b_relative_path or b_content must be given. | |
| compare_call_order | No | Compare recognized message-call names in order, including repetitions (default: false). Plain labels, arguments, endpoints and control flow are not compared. | |
| include_rename_evidence | No | Include exact recognized diagram message-call counts for paired rename names (default: false). Limited to 100 pairs and 10000 calls per side. This is label evidence only and does not scan code or prove identity. |