
SFDXLabs Salesforce Toolkit is a Salesforce development, administration, architecture, and governance workspace for Visual Studio Code. It brings schema exploration, org-to-org comparison, impact analysis, data operations, Flow and User Access Policy automation, security review, Apex testing, GraphQL, and operational diagnostics into one extension.
The toolkit works with the locally installed Salesforce CLI and the orgs already authenticated on the machine. It does not embed Salesforce credentials or introduce an external service. Connected-org operations use an explicitly selected target, while generated evidence is stored either inside the Salesforce project or in private VS Code extension storage according to the workflow and configured data policy.
Built primarily with AI, and offered as-is. Most of this extension's code was written with
AI assistance. It is covered by an automated test suite and static checks, but it has not been
through the breadth of real-world use that a mature tool accumulates, and not every workflow has
been exercised against every org shape. Use it at your own risk. Review what it is about to do
before confirming any guarded write, and try new workflows against a sandbox before a production
org. Bugs and surprises are expected — please report them.
What the extension provides
The extension is designed around four related activities:
- Understand — explore schema, relationships, automation, access, configuration, runtime activity, and data.
- Plan — calculate change impact, compare environments, and review safety evidence.
- Execute — query and update records, run tests, import data, activate User Access Policies, and manage selected configuration through guarded workflows.
- Govern — track security and schema drift, retain evidence, and apply accountable exceptions.
Every major workflow is available from the SFDXLabs activity-bar view, Find Toolkit Action, or the Command Palette. The sidebar uses one compact tree with the same sections documented below.
Requirements
- Visual Studio Code 1.90 or later
- Salesforce CLI (
sf) installed and available to the VS Code extension host
- At least one authenticated Salesforce org for connected workflows
- A Salesforce DX project containing
sfdx-project.json
- A trusted VS Code workspace for Salesforce CLI execution
If sf works in the integrated terminal but the extension cannot find it, set SFDXLabs Salesforce Toolkit: Salesforce CLI Path to the full executable path returned by command -v sf on macOS/Linux or (Get-Command sf).Source in PowerShell.
Getting started
- Open a trusted Salesforce DX project in VS Code.
- Open the SFDXLabs Salesforce Toolkit icon in the activity bar.
- Run Environment Doctor to confirm the project, CLI, org connection, and API version.
- Open Toolkit Home and select or verify the active org.
- Load objects from an org in the Schema section when you want schema-aware queries, data validation, impact analysis, or documentation.
- Open a workflow directly from its sidebar section or use Find Toolkit Action.
The extension supports multi-root workspaces and Salesforce projects nested inside a workspace. Long-running operations expose cancellable progress notifications where the underlying operation can be stopped safely.
These actions appear above the feature sections in the sidebar.
Search every primary workflow by name, section, or description. Actions can be marked as favourites, reopened from recent history, or filtered for Developer, Administrator, and Architect use cases.
Toolkit Home is the operational starting point. It shows:
- Active org alias, username, org ID, and environment classification
- Connection and Salesforce project health
- Shortcuts into frequently used workflows
- Up to 100 recent guarded write operations and their outcomes
- Quick org switching through the status bar
- Clear visual treatment for production targets
Environment Doctor
Environment Doctor checks the complete local execution path:
- Workspace trust and selected Salesforce project
- Resolved
sf executable and CLI version
- Required CLI capabilities and target-org connectivity
- Effective Salesforce REST API version
- Loaded schema session and cache state
- Artifact directories and privacy-related storage settings
Its copy action produces a privacy-redacted diagnostic summary suitable for support without including access tokens, query values, or local user paths.
Report Centre
Report Centre discovers generated evidence from the configured project output directory and project-scoped private extension storage. It can:
- Search and filter reports by category, org, status, storage policy, sensitivity, and age
- Group related artifacts using versioned sidecar manifests
- Reopen generated reports and compare two JSON documents
- Mark reports as favourites
- Identify age-based retention candidates while excluding favourites
- Export exact copies or sanitized copies of supported sensitive text artifacts
- Move selected artifacts to the operating-system Trash after confirmation
Sanitization redacts common credentials, Salesforce IDs, email addresses, and local user paths, but it should not be treated as guaranteed anonymization of arbitrary business data.
Manifest Builder
Builds a package.xml by picking from what the org actually contains, rather than by recalling metadata type names and spelling members correctly by hand.
- The left pane lists every metadata type the org exposes, including child types such as
CustomField that are addressable in a manifest in their own right. The right pane lists the members of whichever type is open.
- Members load only when a type is opened. An org exposes a few hundred types, so listing all of their members up front would be a few hundred org calls before anything could be picked. Each type is fetched once and cached for the session.
* is a first-class choice per type, not something to type by hand. A wildcard keeps tracking the org as it changes; naming members pins exactly what was chosen. Ticking a member replaces a wildcard rather than sitting alongside it.
- Folder types work.
Report, Dashboard, Document, and EmailTemplate are enumerated folder by folder, because Salesforce will not list their contents otherwise. The folders themselves are offered too, since they are deployable components.
- Members from managed packages are labelled with their namespace, since most orgs cannot retrieve or deploy them.
- Filter types and members, or narrow the type list to only what has been selected. A live preview shows the exact XML.
- It opens with your existing manifest. If
manifest/package.xml is already in the project, its selections are loaded so you are editing that file rather than starting from nothing. Save package.xml writes straight back to it, creating the manifest folder if it does not exist. Save as… writes somewhere else.
- Open package.xml… loads a different manifest. Types the current org does not expose are kept rather than dropped, since the file may target another org.
- It can be seeded from a drift comparison. Add to manifest… in the drift report or metadata comparison opens the builder with those components selected, merged into whatever is already there. A type already set to
* is left alone, since narrowing it would drop components the manifest currently deploys.
Saving replaces the project manifest without interrupting, because that is the file the builder opened. It only asks if the file changed on disk since then — pulled, or edited by hand — so those changes are not lost silently.
Output is deterministic — types and members are sorted — so regenerating an unchanged manifest produces an identical file and diffs stay readable. The builder only lists metadata and writes a file; it never deploys or retrieves.
Org Health & Limits
Captures an operational snapshot for an explicitly selected org:
- Salesforce limits with used, remaining, and maximum values
- Healthy, warning, and critical utilization thresholds
- Data and file storage limits when returned by Salesforce
- Asynchronous Apex and the Apex flex queue
- Scheduled jobs
- Recent deployment activity
- Bulk API 2.0 ingest jobs
- Recent debug-log inventory
- Utilization changes compared with the prior snapshot
Utilization below 75% is healthy, 75–89.9% is a warning, and 90% or above is critical. Categories that cannot be queried because of permissions or API support are shown as unavailable rather than empty.
Setup Audit Trail
Who changed what in Setup, and when. A drift report says two orgs differ; this is where the reason
for it lives.
- Pick a window of 7, 30, 90, or 180 days. Salesforce retains 180 days and no more, so a longer
window is clamped rather than quietly returning less than asked for.
- Filter by Setup area, by user, or by text across the change description.
- Changes made while logged in as another user show both the acting and the delegate user.
- Exports as CSV, JSON, or Excel.
- Reaching the row cap is stated, so a truncated window is never mistaken for a quiet one. Reading
the trail needs the View Setup and Configuration permission in the target org.
GraphQL Workspace
Provides a Salesforce GraphQL request workspace with:
- Versioned
/graphql endpoint requests against an explicit target org
- Query and JSON-variable editors
- A schema-introspection starter query
- Saved workspace requests
- Structured data and error inspection
- Discovery of Relay
pageInfo objects
- Cursor buttons that populate the next
after variable
Salesforce server errors, including CRUD and field-level access errors, are preserved. Safety budgets limit queries to 512 KiB, complete requests to 2 MiB, and displayed results to 4 MiB.
Keeps configuration-data workflows separate from the general record browser. It can:
- Discover Custom Metadata types from a selected org
- Browse and export up to 200 records from one type
- Compare two exports at record and field level
- Generate deployable
.md-meta.xml records under force-app/main/default/customMetadata
- Generate a corresponding
package.xml and reveal it for review
Generated metadata is never deployed automatically.
Schema
The Schema section provides the shared metadata foundation used throughout the toolkit.
Loading objects
You do not load a whole org. Load objects from an org asks for an org, then for the objects you want — everything else in this section works on what you load.
Once loaded, the Schema section leads with a single header naming the org and how much of it is loaded (poc · 56 objects · 787 fields), and three actions beneath it:
- Add or remove objects… — change the loaded list, or name it as a saved selection
- Reload from org — fetch the latest schema instead of the cached copy
- Load a different org… — start again somewhere else
A saved selection is a named list of object API names you can reopen later without picking them again. It stores only the org identifier and the object names, never credentials. Saved selections can be opened, renamed, duplicated, and deleted from Saved selections…, which appears once you have one.
When picking objects you can take primary custom objects while excluding generated __Share, __History, and __ChangeEvent companions, combine those with selected standard objects, take everything accessible, or choose a manual list. The last session is restored from an identity-safe cache without contacting Salesforce, and the object and field tree can be searched and filtered by custom, required, formula, relationship, external-ID, and picklist fields.
Schema cache entries are scoped to the org ID and effective API version so an alias that later points to another org cannot reuse stale metadata.
Object and field exploration
- Open rich object and field details
- Review descriptions, formulas, defaults, relationship properties, capabilities, and picklists
- Copy API names and starter SOQL
- Jump to matching local metadata XML
- Visualize loaded-object relationships in an interactive graph
- Drag and keyboard-position nodes while connectors stay attached
- Search the graph and selectively enable or disable relationships
Impact analysis and data quality
Right-click an object or field to run Find Where Used or Run Safe Delete Check. The cancellable, change-aware index scans supported local source and combines it with loaded schema formulas and relationships. Results are confidence-labelled and link directly to source lines.
Run Data Quality Audit checks selected rules for missing object and field documentation, missing inline help, empty picklists, missing relationship names, and duplicate field labels.
When the audit finds fields missing a description or help text, it offers Document them, which opens those findings as a single editable worklist: one row per field with description and help text side by side. Filling them in writes straight into the project's .field-meta.xml files, so a run of fifty findings is one pass rather than fifty visits to the field editor. Drafts survive closing the panel, ⌘/Ctrl+Enter saves, and a checkbox hides rows already filled in.
The audit reads the loaded org schema while this editor writes project source, so a reported field with no local source file cannot be documented here. Those are listed separately with the reason rather than silently omitted, so the worklist never overstates how much of the audit it can address.
Field Manager
Creates new Salesforce fields and edits existing ones as project source, in one panel. Choose an object, then work in whichever tab suits:
- Add one field — a form that adapts to the type, showing length for Text, precision and scale for Number, values for a Picklist, the related object for a Lookup, and so on. The API name is suggested from the label until you type your own.
- Add many fields — paste a table straight from a spreadsheet or a ticket. Tab, comma, and pipe separated input all work, a header row lets columns arrive in any order, and common spellings (
string, boolean, dropdown, money, multi-select) are understood. Every row is validated as you type and reported against its line number.
Validation covers the platform's own rules — label and API-name limits, consecutive underscores, length and precision ranges, duplicate picklist values, attributes a type does not support, and names already used on the object. A missing description is a warning rather than a blocker.
Writing produces one .field-meta.xml per field plus a manifest/<Object>-fields-package.xml naming exactly those fields. An existing file is never overwritten. Nothing is deployed — the files go through whatever review and deployment process the project already has.
Edit one field loads an existing .field-meta.xml and edits the attributes that are safe to change: label, description, help text, required, unique, external ID, default value, picklist values, relationship label, and visible lines. A running list shows exactly what will change.
Edit many fields lists every field on the object in one grid — label, description, help text, and the required, unique, and external ID flags, all editable in place. Changed rows are highlighted and name what changed, and only those rows are written. Filter by name, label, or type, or narrow to just the changed or just the undocumented rows. A checkbox the field's type cannot carry is disabled and says why on hover. Type, length, and picklist values are not editable in the grid; use Edit one field for those.
Type, length, precision, API name, and the target of a relationship are deliberately not editable here, and the panel says why for each. Salesforce rejects most type conversions and applies the rest destructively, and a length reduction permanently truncates data. Create a new field and migrate instead. Elements the editor does not model — such as securityClassification — are preserved verbatim when the file is rewritten.
Dependency Viewer
Answers "what does this need, and what needs it?" for one org component, using the Tooling API's MetadataComponentDependency rather than a local source search. Pick a metadata type (Apex class, Apex trigger, Flow, custom field, custom object, validation rule, LWC, Aura component, Visualforce page or component), pick the component, and choose how far to follow the graph:
- Requires — what the component needs. Deleting or renaming any of it can break the component.
- Used by — what needs the component. Changing or deleting it affects them.
- Following two or three levels also reports indirect components and the component each was reached through.
Any listed component can be selected to become the next root, so a graph can be walked without starting over. Results are filterable and written to a JSON report in Report Centre.
This complements Find Where Used, which greps local project source: the Dependency API sees org metadata that is not in the project, while the local search sees dynamic references the Dependency API cannot track. Salesforce does not report dependencies expressed in Apex string literals, dynamic SOQL, formula text, or external integrations, so an empty result means low risk rather than proof that nothing uses a component. Orgs need API version 47.0 or later for the Dependency API to answer at all.
Compare Two Orgs
Object and field drift between any two authenticated orgs, read from describes. No retrieve, so it
is the fast way to answer "why does this work in UAT and not production". Pick two orgs and a scope
of custom, standard, or every object.
- Reports objects present in one org only, fields added or removed, and fields present in both that
differ — types, lengths, required, unique, formulas, help text, picklist values, and more.
- Attributes that reflect the connected user rather than the schema are never compared.
createable, updateable, filterable, sortable, and groupable all vary with the login, so
comparing them would report on the two users instead of the two orgs.
- Both orgs are read fresh rather than from the schema cache, so the comparison is of one moment
rather than a cached snapshot against a live read.
- Formula whitespace, lookup target ordering, and inactive picklist values are not treated as
drift. Picklist order is, but as a separate finding that is hidden until asked for.
- An object whose describe fails on either side is excluded and named, rather than being reported
as missing from the other org. Companion objects (
__Share, __History, __ChangeEvent) are
left out, since Salesforce generates them from their parent.
A describe only returns what the connected user can see, so compare with logins of equivalent
access — otherwise field-level security is reported as missing schema. The panel says so.
Retrieves the same metadata from two orgs and diffs it line by line: Apex, Flows, FlexiPages,
Lightning web and Aura components, and objects with their fields, validation rules, record types
and list views. Permission sets, layouts, custom labels, tabs, apps and quick actions are available
but off by default.
- Findings are grouped by component rather than by file, so an Apex class is one result even
though it is two files, and a Lightning bundle is one result even though it is five.
- Open diff shows the change in the editor's own diff view — syntax highlighting, side by side
or inline, and change navigation. A file present on one side only opens on its own rather than
beside an empty pane.
- Retrieved metadata is normalised before it is compared, or the report would be unusable.
Element ordering, indentation, and the XML declaration are not drift, and neither are managed
package version pins. Order is preserved where a user can see it — layout field placement and
picklist value order are not sorted away. In code files only line endings and trailing whitespace
are touched; comments and blank lines are real changes.
- Profiles are never compared. A retrieve returns a different part of a profile depending on
what else is in the manifest, so two retrieves of one profile are not comparable.
- Both retrieves go to a temporary directory outside the project, removed when the panel closes.
Nothing is written into your source tree. Leftovers from a session that never cleaned up are
swept on the next run.
Retrieving is a read, but it is slow — expect minutes on a wide scope. Files too large to diff line
by line say so rather than hanging.
Full Drift Report
Runs both comparisons and returns a single report of every difference, and only differences. Pick
which halves to include; either can run alone.
- Opens with counts by finding and a breakdown by type, then one filterable table.
- Read as rewords every finding as the action a deployment would take — Add to uat, Update in
uat — for either direction. A component missing from the source is never described as a removal,
because a deploy does not delete what its manifest omits.
- Add to manifest… sends the components to the Manifest Builder, so a report becomes the
package.xml that fixes it. Only components the source org actually has are listed, since
deploying cannot create what the source lacks. Types that cannot be listed under the name they
compare under are skipped and counted rather than guessed at.
- Exports as a Markdown report — summary, tables per area, the actual changed lines, and a
section naming what the report does not cover — or as CSV, JSON, or Excel with one row per
difference.
The two halves overlap on fields deliberately: a describe reports the schema as the org computes
it, a retrieve reports the source definition, and each catches things the other cannot.
Compare Local Source With an Org
Compares the working tree against an org: what is checked out but not deployed, what is in the org
but not the repo, and what exists in both but has diverged. Same metadata groups and same diff view
as the org-to-org comparison, with one org retrieved instead of two.
- The working tree is only ever read. The retrieve still lands in a scratch project outside your
directory, so nothing here can overwrite uncommitted work.
- A retrieve names a class
classes/Foo.cls and a working tree names it
force-app/main/default/classes/Foo.cls. Both sides are re-keyed onto canonical paths before
pairing, or every component would be reported as changed with the whole file added and removed.
- Files a retrieve can never return —
jsconfig.json, .eslintrc, __tests__ — are left out of
the local side, so your tooling setup is not reported as drift on every run.
- A component held by more than one package directory is counted and stated rather than silently
collapsed: which copy the org matched is what decides whether there is drift.
An incomplete retrieve is refused rather than compared. The Salesforce CLI exits successfully for a
partial retrieve, and anything Salesforce left out would otherwise be reported as missing from the
org — which, in a comparison against your repo, reads as work you still need to deploy.
Analyse Field Usage
Counts how many records populate each field of an object, emptiest first. The dictionary says a
field exists and the safe-delete check says whether anything references it; this says whether anyone
ever filled it in, and the three disagree often enough to be worth all three before deleting.
- Counts are batched, so an object with two hundred fields costs a handful of queries rather than
two hundred. If one field cannot be aggregated, that batch is retried field by field so its
neighbours keep their measurements.
- Fields Salesforce cannot aggregate — long text, encrypted, base64, compound — are listed with the
reason rather than omitted. So are formula and auto-number fields, which are populated on every
record by definition, so a count would say nothing about use.
- A field that could not be measured is never shown as empty. Zero would read as "nobody uses this",
which is the reading that gets a field deleted.
- Fields with no data offer a direct jump to the safe-delete check, when the object is loaded in the
schema explorer.
Data dictionary export
Exports the loaded schema to deterministic CSV, JSON, and Markdown, at whichever level of detail you need:
- One row per field — every field with its label, API name, description, type, length, precision, scale, SOAP type, formula, default, relationships, controlling field, picklist state, and create/query/update/filter/sort/group capabilities.
- One row per object — each object once, with its label, API name, type, description, permissions, field counts broken down by custom, standard, required, formula, relationship, picklist, and external ID, the objects it relates to, and whether it is documented.
The object grain is for reviewing an object model; the field grain repeats every object attribute on each of its fields, which is the wrong shape for that. Column choices are remembered separately for each, and the two write to different files so neither overwrites the other:
data-dictionary/salesforce-data-dictionary.{csv,json,md} — field grain
data-dictionary/salesforce-object-dictionary.{csv,json,md} — object grain
Data
SOQL & Record Workspace
The multi-tab workspace supports UI-built and free-form SOQL:
- Schema-aware validation and formatting
- Object, field, relationship-path, and keyword completion
- Lookup and master-detail fields open their parent object in the field list itself: click the
› beside one and the list shows that parent's fields, with a breadcrumb back. Ticking a field there selects it by its full path (Make__r.Owner.Email), and parents chain up to the five levels Salesforce allows. A lookup whose target is not loaded says so rather than offering a dead end.
- A Related… control for the clauses that have no inline equivalent: a child-relationship subquery (
(SELECT Id FROM Contacts)), a semi-join filter (AccountId IN (SELECT Id FROM Account WHERE Name = 'TEST')), or a parent field on an object that is not loaded
- Sortable result columns; sorting orders every returned row, not only the displayed page
- A Clear control beside the field filter unselects every field at once, including parent-path and subquery selections that have no checkbox of their own.
Id is kept, since the builder always queries it, and a running count of selected fields sits alongside
- Recent and favourite queries
- Salesforce Query Plan inspection
- Visible-column selection, filtering, sorting, and optional limits
- A collapsible query pane, so results can use the full panel width
- Bounded result rendering up to 1,000 rows and 4 MiB
- One Export control that asks for CSV, JSON, SpreadsheetML, or a tab-separated clipboard copy, and always writes every row the query returned — not only the rows the grid displays
- Inline editing for supported single-object results that include record IDs
- Highlighted changes and guarded multi-record updates, sent in batches of up to 200 records per request rather than one request per record
- Discard edits reverts every unsaved cell in the tab, and Escape in a cell reverts just that one, so unsaved work never blocks re-running, sorting, or closing a tab
Only confirmed successes are cleared after a mixed or cancelled update; failed and unattempted edits remain available for review or retry. Tabular exports flatten relationship values such as Account.Name, while JSON preserves the nested response. Inline editing applies to the displayed rows; exports are not limited by the display budget.
Import Records from CSV
Imports through Bulk API 2.0 Insert, Update, or Upsert with:
- Streaming CSV/TSV inspection without copying the original source
- Suggested mappings by API name and unique field label
- Explicit mapping or skipping for every column
- Update and upsert identifier enforcement
- Optional conversion of non-identifier blanks to Salesforce’s
#N/A null marker
- Full-file validation for IDs, booleans, dates, datetimes, numbers, lengths, required-on-create fields, and restricted picklists
- Private, reusable recipes scoped to org, object, operation, and exact headers
- Explicit target and write confirmation before submission
The normalized upload and job lineage are retained privately for safe result correlation. Abandoned uploads are cleaned on activation, and retained job artifacts are bounded by age and count.
Monitor Bulk API Job
Checks a selected Bulk ingest job, shows processing and record counts, and retrieves bounded failed or unprocessed result previews after the job reaches a terminal state. When Salesforce returns sufficient original field data, Prepare rows for retry creates a private CSV containing only failed and unprocessed records and returns it through the normal mapping and confirmation flow.
Datasets & Seeding
Export Relationship Dataset
Exports parent/child SOQL results as Salesforce sObject tree JSON plus an ordered import plan. Salesforce Composite tree limits the export to 2,000 records.
Import Relationship Dataset
Imports a generated tree plan or explicitly ordered JSON files only after target-org confirmation.
Create Seed Recipe
Stores reusable, relationship-aware SOQL for repeatable sandbox seeding.
Run Sandbox Seed Recipe
Runs a saved recipe from a source org and can import its output into a separately selected target. Every run receives a new timestamped directory to prevent an earlier plan being imported accidentally.
Create Anonymized Dataset
Replaces selected string-like field values deterministically while retaining record IDs for correlation. Anonymized output remains controlled data and should be reviewed before sharing.
Automation
Lint All Flows
Detects missing fault paths, record queries or DML inside loops, hard-coded Salesforce IDs, same-object after-save update risks, unreachable elements, missing descriptions, and inactive Flows. Findings link back to the matching metadata line.
Object Automation Map
Builds an approximate object-level order-of-execution view across validation rules, before-save Flows, Apex triggers, after-save Flows, legacy workflow rules, and scheduled or asynchronous automation. Entry criteria, recursion, managed packages, and org-only automation can change actual runtime behavior.
Cleanup
Clean Up Inactive Local Flows
Reviews inactive local Flow files and moves only selected metadata to the operating-system Trash.
Delete Inactive Org Flow Versions
Queries inactive org Flow versions through the Tooling API and permanently deletes only selected versions after a generated phrase is typed into a modal confirmation.
Flow lint and automation-map evidence is generated beneath the configured output directory in automation/.
Security 360
The sidebar groups Security 360 into five categories so the right tool is easy to find. Open Security 360 is the starting point for most sessions; the rest are organized by task below.
Open Security 360
Provides a connected inventory of Profiles, Permission Sets, Permission Set Groups, muting sets, system permissions, custom permissions, Apex access, object CRUD, field access, tabs, applications, and record types. Permission Set Groups are resolved through their members and exposed muting metadata before effective access is presented.
Look Up Access
Answers "what can this user or record access, and why?"
- Explain User Access — select a connected user, object, and optional field to trace effective CRUD and FLS back to the Profile, Permission Set, or Permission Set Group that grants it.
- Diagnose Record Access — uses
UserRecordAccess as the authoritative effective-access result, supplemented by available ownership, group, role-hierarchy, territory, team, and share-row evidence. Supporting mechanisms are presented as evidence rather than replacing the authoritative result.
- Find Access Grant Sources — reverse lookup Profiles, Permission Sets, and groups that grant a selected capability.
Compare Access
Answers "what's different, or what would change?"
- Compare User Access — compares two users across effective CRUD, fields, tabs, assignments, and contributing grant sources.
- Compare Effective Access — compares Profiles, Permission Sets, or resolved Permission Set Groups.
- Compare Permission Sources — reviews direct metadata differences between two local sources.
- Assignment Impact — previews access that would be added, removed, or retained through another source before a permission assignment change. Elevated capabilities, affected users, and available license requirements are highlighted without changing the org.
Audit & Findings
Proactively scans for risk rather than answering a specific question.
- Security Findings — audits elevated system permissions, sensitive-object CRUD, View All Fields, redundant assignments, inactive-user assignments, and unused Permission Sets.
- Field Security Risks — finds explicit readable or editable access to potentially sensitive fields and sensitive fields exposed through View All Fields.
- Cleanup Recommendations — reviews unused, redundant, overlapping, and inactive-user access as read-only recommendations.
- Manage Finding Exceptions — records an accountable owner, reason, and expiry for accepted findings. Expired exceptions stop suppressing matching evidence.
Browse Permission Sources
Inspects a single Profile, Permission Set, or group in detail.
- Review Permission Set or Group — inspect CRUD, fields, tabs, applications, record types, classes, permissions, group members, and muting.
- Permission Matrix — compare object CRUD and field access across local Profiles and Permission Sets.
Security Snapshots
Tracks access drift over time.
- Save Security Snapshot — captures dated source inventory, assignments, CRUD, FLS, group composition, system permissions, and findings.
- Compare Security Snapshots — displays semantic access and finding drift between two saved dates.
Security evidence and spreadsheet-safe CSV exports are private by default. Connected-org queries are briefly cached, refresh choices expose cache age, and unavailable categories are visibly marked rather than presented as empty.
Apex & Logs
Anonymous Apex Scripts
Each script is its own .apex document, kept per org, so VS Code's own tabs, split editors, search, and save apply. Anonymous Apex Scripts opens a searchable library of them:
- Type to filter by name or by the first line of the script; press Enter to open
- Each entry shows when it was last edited, its length, and a preview line
- Rename, duplicate, and delete without leaving the list; a deleted script goes to Trash
- Type a name and choose New script to create and open one in a single step
Editing keeps the native Apex experience:
- Apex editing, completion, syntax highlighting, and formatting
- Loaded-schema object and field suggestions
- Local Apex class and static-method suggestions
- Selected-code or whole-document execution, bound to the org the script was opened for
- Automatic correction of accidental double-quoted Apex string literals
- Structured compilation, execution, exception, user-debug, and log output
Run buttons appear in the editor title bar for these documents. Use Ctrl/Cmd+Enter to run the script and Ctrl/Cmd+Shift+Enter to run the selection.
Scripts that were cells in the previous notebook workspace are moved into separate files the first time the library is opened for an org. The notebook file is left in place, and the notebook editor stays registered, so existing .sfdxlabs-apex files still open and run.
Open Debug Log Viewer
Select from recent org logs and inspect a structured timeline for SOQL, DML, callouts, validation, Flow, exceptions, and user-debug events. Governor-limit usage is ranked by percentage consumed. Log filters include This Frame, Executable, Debug Only, and live text search.
Apex Tests & Coverage
Run Apex Test Classes
Select and run one or more local test classes.
Run Apex Test Suite
Select and run one or more Apex Test Suites from the org.
Run Local Tests
Runs Salesforce RunLocalTests with code coverage.
Rerun Failed Tests
Reruns every class that failed in the previous recorded run.
View Last Test Dashboard
Shows passed, failed, and skipped methods, failure details, per-class uncovered lines, and test-run coverage. Source links open the matching .cls file.
Apex Test History
Retains recent outcomes and aggregate coverage trends.
Test reports, raw logs, and parsed analyses are kept in private extension storage by default. Set sfdxlabs-tool-kit.sensitiveOutputLocation to project only when this evidence is intentionally meant to be shared or versioned.
Shared safety and data handling
- CLI execution is blocked in untrusted workspaces.
- Connected workflows require an explicit Salesforce project and target org.
- Production targets receive prominent environment treatment and guarded write confirmation.
- Record edits, metadata deployment, tree import, CSV import, production Anonymous Apex, and permanent Flow cleanup expose the affected target and operation before execution.
- Salesforce access tokens are never written into toolkit artifacts.
- CLI diagnostics redact queries, submitted values, credentials, and common local identities.
- Standard evidence uses the configured project output directory; sensitive evidence is private by default.
- Unavailable Salesforce result categories remain marked unavailable rather than being represented as empty or successful.
- Generated manifests record report identity, category, command, org, time, status, storage location, sensitivity, and related artifact names.
- No external telemetry is sent by the extension.
Two editor-side tools that need no org connection. Both open with whatever is selected in the active editor, keep the text editable with syntax highlighting as you type, and can copy the result or push it into a new editor document.
JSON Beautifier
Formats, minifies, and optionally sorts the keys of any JSON — an API response, a platform-event payload, a line from a debug log. Indentation is configurable (2 spaces, 4 spaces, or a tab), and JSON that arrived as an escaped string is unwrapped automatically.
Values are re-indented, never re-serialised. Parsing JSON and stringifying it again silently rewrites anything a double cannot hold — an 18-digit number, 1.0, 1e3 — so this formatter moves whitespace between the original tokens instead. Invalid JSON reports what is wrong and the line and column it is on.
Lays out a Salesforce formula so it can be read: short calls stay on one line, longer calls break one argument per line with nesting indented, and long && / || chains break before each operator. Only whitespace changes — every field, literal, operator, and comment is preserved, so the formatted formula compiles exactly as the original did. Unbalanced parentheses and unterminated text literals are reported with their position.
Settings
sfdxlabs-tool-kit.salesforceCLIPath — optional full path to sf; blank uses the extension host PATH.
sfdxlabs-tool-kit.outputDirectory — output directory inside the Salesforce project.
sfdxlabs-tool-kit.apiVersion — optional API override; blank resolves the latest REST version supported by the selected org.
sfdxlabs-tool-kit.outputFormats — any combination of csv, json, and markdown for dictionary output.
sfdxlabs-tool-kit.useTimestamps — generate timestamped dictionary snapshots instead of stable filenames.
sfdxlabs-tool-kit.concurrency — simultaneous describe requests from 1 to 10; with batching on, this is the number of concurrent batches.
sfdxlabs-tool-kit.bulkDescribe — describe objects in composite batches of 25 (default true), so a schema load spends one Salesforce CLI call per batch instead of one per object. Disable to force a request per object.
sfdxlabs-tool-kit.cacheTtlMinutes — org- and API-scoped schema-cache lifetime; 0 bypasses reads.
sfdxlabs-tool-kit.sensitiveOutputLocation — private extension storage by default or deliberate project-local sensitive output.
sfdxlabs-tool-kit.debugOutputLocation — legacy debug-specific storage override retained for compatibility.
sfdxlabs-tool-kit.reportRetentionDays — age at which Report Centre identifies non-favourite retention candidates; 0 disables age-based selection.
Run SFDXLabs Salesforce Toolkit: Clear Cached Org Metadata to drop cached describes and Apex test discovery and force a complete refresh.
Keyboard shortcuts
- Ctrl/Cmd+Enter — run the active SOQL query or Anonymous Apex script where supported.
- Ctrl/Cmd+Shift+F — format the active SOQL query.
- Ctrl/Cmd+Shift+Enter — run selected Anonymous Apex.
- Ctrl+Space — request schema-aware SOQL or Apex suggestions.
Development
npm ci
npm run check:static
npm test
npm run test:coverage
npm run test:extension
npm run check:package
npm run package
Coverage enforces a 55% line threshold. Release builds are minified, source maps are excluded from the VSIX, and release checks enforce an 800 KiB activation-bundle budget plus a 3 MiB total JavaScript budget. The implementation separates command orchestration, Salesforce CLI access, schema loading and caching, evidence generation, and lazy-loaded VS Code UI modules.