ChangeSnap (v1.2)
Tracks org metadata changes during a feature/bugfix session and generates a
DevOps-tool-agnostic markdown handoff file (.changesnap/<story>-handoff.md).
No dependency on git, Copado, Gearset, or any specific pipeline — it only
reads org state via the Salesforce CLI.
Prerequisites
- Salesforce CLI (
sf) installed
- An authenticated org set as your default:
sf org login web --set-default
- Node.js 18+, VS Code 1.85+
Setup
npm install
npm run compile
Then press F5 in VS Code to launch an Extension Development Host with
the extension loaded, or package it with vsce package to install as a
.vsix.
Commands
| Command |
What it does |
ChangeSnap: Start Session |
Prompts for story number (optional), snapshots the org's metadata state as baseline |
ChangeSnap: End Session (Generate Handoff) |
Re-snapshots, diffs against baseline, runs dependency scan, prompts for manual steps, writes the markdown handoff |
ChangeSnap: Show Active Session Status |
Shows org + start time of the current session |
ChangeSnap: Cancel Active Session |
Discards the baseline without generating a handoff |
How it works
- Baseline — calls the Metadata API's
listMetadata() (via sf org list metadata) once per configured metadata type, and records each
component's lastModifiedDate. This works on any org — sandbox,
scratch, or production — regardless of whether source tracking is
enabled. (An earlier version of this extension used SourceMember
via Tooling API, which is more precise but only works when source
tracking is turned on; many sandboxes don't have it.)
- Diff — compares
lastModifiedDate per component between
baseline and current snapshot to classify added / modified / deleted.
- Dependency scan — for each changed component, queries
MetadataComponentDependency (Tooling API — a separate feature from
SourceMember, not gated by source tracking) and flags any
referenced component that isn't itself part of the change set (the
"forgot to include the PermissionSet" problem). Coverage is not
100% for every metadata type — treat warnings as a strong hint, not
a guarantee.
- Handoff file — self-contained markdown, safe to paste into a
ticket or hand to any DevOps tool.
Configuration
changeSnap.metadataTypes (workspace setting) — the list of metadata
types checked at session start/end. Each type is one Metadata API call,
so snapshot time scales with list length. Defaults to a curated list of
~20 common types (Apex, LWC, Flow, PermissionSet, CustomObject, etc.).
Trim it down for faster snapshots, or add org-specific types.
Known limitations (v1.2)
lastModifiedDate isn't perfectly reliable — a handful of
metadata types don't update it consistently on every save, so a rare
edit may not register as "modified." This is a known trade-off of
not depending on source tracking.
- CustomField isn't tracked directly. Fields aren't independently
listable via
listMetadata() — they're nested under CustomObject
and would need a separate describe call per object. Not yet
implemented; if you rename/add fields often, keep this in mind when
reviewing the handoff.
- Shared sandboxes: there's no per-developer attribution with this
approach, so if multiple devs work in the same sandbox concurrently,
the diff includes everyone's changes during that window.
MetadataComponentDependency doesn't cover every metadata type (some
Flow/field-level-security references inside Permission Sets are
missed). A static-scan fallback (regex/AST over Apex/Flow XML/LWC) is
planned but not yet implemented — flagged as a TODO in
dependencyScan.ts.
- No machine-readable export (JSON/CSV/
package.xml) yet — markdown
only, per current scope.
Next steps
- Add static-scan dependency fallback
- Add
package.xml / JSON export alongside the markdown
- CustomField tracking via per-object describe calls
- Optional: detect if source tracking IS available on the target org
and use the more precise
SourceMember/RevisionCounter approach
automatically when it is, falling back to listMetadata() otherwise
| |