Closes the snapshot/restore loop opened in 0.7/0.8 — you could save and restore but had no way to see what changed.
Added
n8n_diff_workflow— read-only semantic diff between a workflow's current state and a snapshot. Inputs:idplus exactly one ofsnapshotPath(absolute file path;~resolved) orsnapshot(inline object). Snapshot accepts both shapes: flat (n8n_save_workflow/n8n_delete_workflowbackup) and nested (n8n_get_workflow(includeDefinition=true)). Returns counters insummary(added/removed/modified, plus nameChanged/connectionsChanged/settingsChanged) and adiffpayload with per-nodefieldsChangedpaths walking one level intoparameters(e.g.parameters.command,parameters.url).
Notes
- Two-pass node matching: id-first, name-fallback for any unmatched nodes. Handles legacy/hand-edited snapshots without forcing a "1 added + 1 removed" false signal when one side is missing ids.
- Cosmetic noise suppression:
positionandwebhookIdchanges are suppressed by default; toggle withignoreCosmetic: false. - Bounded output: per-node detail capped at
maxModifiedDetails(default 50, max 500) with explicitnodesModifiedTruncatedflag;summarycounters are uncapped. - Pairs with
n8n_save_workflow(which writes the snapshot) andn8n_audit_browser_bridge_usage(which surfaces calls — diff tells you whether they've drifted).
15 new tests, full suite 145/145 green.