Skip to content
Development
Skill

/dx-org-analyze

Compare two Salesforce orgs side-by-side and produce a comparison report with drift score, or analyze a single org to produce an inventory covering metadata components, org permissions, system permissions, profiles, installed packages, licenses, and org limits. Use this skill

From plugin
forcedotcom-sf-skills-2
1k200 skills2 agents14 commands3 MCP
Install
$ npx -y skills add forcedotcom/sf-skills --skill dx-org-analyze --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/dx-org-analyze

Context preview

The summary Claude sees to decide when to auto-load this skill.

Compare two Salesforce orgs side-by-side and produce a comparison report with drift score, or analyze a single org to produce an inventory covering metadata components, org permissions, system permissions, profiles, installed packages, licenses, and org limits. Use this skill

SKILL.md

dx-org-analyze.SKILL.md
name: dx-org-analyze
description: "Compare two Salesforce orgs side-by-side and produce a comparison report with drift score, or analyze a single org to produce an inventory covering metadata components, org permissions, system permissions, profiles, installed packages, licenses, and org limits. Use this skill when the user wants to compare orgs, diff orgs, audit configuration drift, find what changed between two environments, compare sandbox against production, or analyze a single org. Trigger phrases include: 'compare orgs', 'compare these 2 orgs', 'compare my orgs', 'diff orgs', 'org diff', 'what is different between these orgs', 'compare metadata', 'org comparison', 'audit org differences', 'compare sandbox to production', 'introspect org', 'org inventory', 'what is in my org', 'analyze org', 'org analysis', 'analyze my org', 'analyze my Salesforce org'. Do NOT use for retrieving metadata (use platform-metadata-retrieve), deploying metadata (use platform-metadata-deploy), or switching orgs (use dx-org-switch)."
metadata:
  version: "1.0"
  minApiVersion: "62.0"
  domains: ["Developer Experience"]
  relatedSkills:
    - "dx-org-manage"
    - "dx-org-switch"
    - "platform-metadata-deploy"
    - "platform-metadata-retrieve"
  cliTools:
    - tool: ["python3"]
      semver: ">=3.10"
    - tool: ["sf"]
      semver: ">=2.0.0"

Tool Restrictions

**Use ONLY the Bash tool** to execute all `sf` CLI commands and Python scripts. Always include `--json` for `sf` commands. Do NOT use `mcp__salesforce_dx__*` tools.

**Output artifacts for eval/testing:** When an output directory is available, write results there. After executing the skill: (1) if the user specified an output path, write there immediately; (2) otherwise run `[ -d force-app/main/adk-eval-output/ ] && echo 'force-app/main/adk-eval-output'` to detect the eval directory; (3) write the full JSON result to `<output-dir>/dx-org-analyze-result.json` and the markdown report to `<output-dir>/dx-org-analyze-result.md`.

---

Data Access Hierarchy

When querying org data, always follow this priority order:

1. **SF CLI commands** — Preferred. Use `sf org list metadata-types`, `sf org list metadata`, `sf org display`, `sf data query`, `sf limits api display`, etc. 2. **Direct REST/Tooling API calls** — Last resort, only when SF CLI cannot provide the data.

Never bypass this hierarchy. If an SF CLI command exists for the operation, use it even if a direct API call would be simpler.

---

Authentication Rules

  • **All authentication MUST go through SF CLI** (`sf org login web`, `sf org login jwt`, `sf org login access-token`).
  • Never accept raw credentials (username + password), session IDs, or access tokens directly from the user.
  • The collection script obtains its access token exclusively via `sf org display --json`.

---

Workflow

Step 0: List Authenticated Orgs

Run this command to discover all authenticated orgs:

sf org list --json --skip-connection-status

Parse the JSON output. Collect orgs from **all buckets** (`devHubs`, `nonScratchOrgs`, `scratchOrgs`, `sandboxes`, `other`). Present authenticated orgs in a readable table:

| # | Alias | Username | Instance URL | Org ID | Type | |---|-------|----------|--------------|--------|------|

If fewer than 2 orgs are authenticated but at least 1 is available, offer the **single-org introspect** mode (see Introspect Workflow below). If no orgs are authenticated, STOP and advise: > You need at least 1 authenticated org. Run `sf org login web --alias <name>` to authenticate.

If the user explicitly requests a single-org introspection or inventory, use the **Introspect Workflow** regardless of how many orgs are available.

Step 1: User Selects Two Orgs

Ask the user to select two orgs from the list. Both must be explicitly named — do NOT allow implicit/default orgs.

> Select two orgs to compare. Which is the **source** (reference/expected state)? Which is the **target** (to compare against)?

Accept: alias, username, or number from the list. Resolve each selection to a concrete **username**. If an org lacks an alias, prompt the user to assign one. Confirm:

> Comparing: > - **Source**: `<alias>` (`<username>`) > - **Target**: `<alias>` (`<username>`)

Step 2: Validate Connectivity

For each org, confirm reachability with a lightweight query that does not expose secrets:

sf data query --target-org <alias-or-username> --query "SELECT Id FROM Organization LIMIT 1" --json

If the query succeeds (exit 0 and a record is returned), the org is connected. If it fails with `INVALID_SESSION_ID` or auth errors:

sf org login web --alias <alias>

Step 3: Collect Data (per org)

Generate a unique run ID and run the collection script for each org:

RUN_ID=$(date +%Y%m%d-%H%M%S)

python3 ./scripts/collect_org_data.py \
  --org-alias "$SOURCE_ORG" \
  --output /tmp/dx-org-comparison-${RUN_ID}-source

python3 ./scripts/collect_org_data.py \
  --org-alias "$TARGET_ORG" \
  --output /tmp/dx-org-comparison-${RUN_ID}-target

**Exit codes:** `0` = success, `1` = fatal error (report stderr to user), `2` = session expired (re-authenticate Step 2 and retry).

For details on what the collection script gathers, see `references/collection-details.md`.

Step 4: Compute Diff and Report

python3 ./scripts/compute_diff.py \
  --org-a /tmp/dx-org-comparison-${RUN_ID}-source \
  --org-b /tmp/dx-org-comparison-${RUN_ID}-target \
  --output /tmp/dx-org-comparison-${RUN_ID} \
  --format both \
  --org-a-label "Source" \
  --org-b-label "Target"

Use `--show-shared` if the user wants shared components listed in detail.

Step 5: Present Results

Read `/tmp/dx-org-comparison-${RUN_ID}.md` and present to the user. If the user asks follow-up questions, use `/tmp/dx-org-comparison-${RUN_ID}.json` for data lookups. Then resolve the output directory and copy both files there:

OUTPUT_DIR=""
if [ -n "$USER_OUTPUT_PATH" ]; then
Read more
Ships withforcedotcom-sf-skills-2

This repository provides a curated collection of Salesforce agent skills for building applications.

Get the whole plugin

Other skills on forcedotcom-sf-skills-2.