forcedotcom/sf-skills

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 lim…

소스 보기

사용 방법

  1. 설치 명령을 복사하고 자신의 에이전트 환경에 설치하기 전에 소스 패키지를 확인하세요.
  2. 필요한 도구, 인증 정보, 지원 환경은 원본 문서에서 확인하세요.
  3. 입력과 원하는 산출물을 설명하고 출처와 결과를 대조하세요.
npx skills add https://github.com/forcedotcom/sf-skills --skill dx-org-analyze

시작 전 확인

  • 설치에는 모델 구독, API 한도, 파일 접근 권한이 포함되지 않습니다.
  • 별점 수와 설치 수는 활동 지표이며 독립적인 품질·보안 검증이 아닙니다.
원본 Skill 문서

원본 저장소의 제목, 예시, 코드, 표, 링크, 이미지를 유지해 표시합니다.

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:

bash
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:

#AliasUsernameInstance URLOrg IDType

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:

bash
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:

bash
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:

bash
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

bash
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:

bash
OUTPUT_DIR=""
if [ -n "$USER_OUTPUT_PATH" ]; then
  OUTPUT_DIR="$USER_OUTPUT_PATH"
elif [ -d "force-app/main/adk-eval-output" ]; then
  OUTPUT_DIR="force-app/main/adk-eval-output"
fi

if [ -n "$OUTPUT_DIR" ]; then
  cp /tmp/dx-org-comparison-${RUN_ID}.json "$OUTPUT_DIR/dx-org-analyze-result.json"
  cp /tmp/dx-org-comparison-${RUN_ID}.md "$OUTPUT_DIR/dx-org-analyze-result.md"
fi

Introspect Workflow (Single-Org Mode)

Use this workflow when the user wants to inspect a single org's configuration, or when only one org is authenticated.

Introspect Step 1: Validate Connectivity

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

Introspect Step 2: Collect Data

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

python3 ./scripts/collect_org_data.py \
  --org-alias "$ORG" \
  --output /tmp/dx-org-analysis-${RUN_ID}

Introspect Step 3: Generate Report

bash
python3 ./scripts/introspect_org.py \
  --org /tmp/dx-org-analysis-${RUN_ID} \
  --output /tmp/dx-org-analysis-${RUN_ID} \
  --format both \
  --label "OrgName"

Introspect Step 4: Present Results

Read /tmp/dx-org-analysis-${RUN_ID}.md and present to the user. The report covers: metadata inventory, org settings, org limits, installed packages, licenses, system permissions, and deep data records. Then resolve the output directory and copy both files there:

bash
OUTPUT_DIR=""
if [ -n "$USER_OUTPUT_PATH" ]; then
  OUTPUT_DIR="$USER_OUTPUT_PATH"
elif [ -d "force-app/main/adk-eval-output" ]; then
  OUTPUT_DIR="force-app/main/adk-eval-output"
fi

if [ -n "$OUTPUT_DIR" ]; then
  cp /tmp/dx-org-analysis-${RUN_ID}.json "$OUTPUT_DIR/dx-org-analyze-result.json"
  cp /tmp/dx-org-analysis-${RUN_ID}.md "$OUTPUT_DIR/dx-org-analyze-result.md"
fi

Report Structure

The generated report includes:

  1. Drift Score — Weighted overall score (60% metadata, 30% permissions, 10% profiles) with severity level (LOW/MODERATE/HIGH/CRITICAL)
  2. Summary Statistics — Counts per metadata type with Identical/Different columns from deep data
  3. Metadata Components by Type — Only-in-Source, only-in-Target, shared per type
  4. Profiles — Shared, source-only, target-only
  5. Installed Packages — Version comparison, only-in-Source, only-in-Target
  6. Package Components — Namespaced components grouped by namespace
  7. Org Permissions — Boolean enabled/disabled diffs by category, plus value diffs
  8. System Permissions — PermissionsXxx fields on PermissionSet, per-set diffs
  9. Org Values & Limits — Grouped by Identity, Storage, API, Feature Limits
  10. Licenses — User, Permission Set, Package license quantity diffs
  11. Deep Data — Content-level diffs for Apex, Flows, Validation Rules, Custom Fields, etc.

Rules / Constraints

ConstraintRationale
Always use --json with sf commandsStructured output for reliable parsing
Resolve orgs to usernames, not aliasesAliases can be ambiguous; usernames are unique
Skip expired and disconnected orgsCannot query metadata from inaccessible orgs
Read-only — never deploy or modifyThis skill compares only, never mutates either org
SF CLI auth onlyAll authentication through SF CLI credential store
Both orgs must be explicitNever compare unnamed or implicit/default orgs

Troubleshooting

IssueResolution
"No org found for \<alias\>"Org not authenticated — run sf org login web --alias <name>
Fewer than 2 authenticated orgsAuthenticate additional orgs before comparing
"INVALIDSESSIONID" or auth errorsSession expired — re-run sf org login web --alias <name>
Collection script exits with code 2Session expired — re-authenticate and retry
API limit errors during metadata listingUse --skip-deep-data for a faster pass with less detail
Edition differences (DE vs EE)Many differences are edition-inherent, not configuration drift
Large orgs timeout on deep dataUse --skip-deep-data flag; run full deep data on targeted follow-ups

Cross-Skill Integration

NeedDelegate to
Retrieve specific metadata from an orgplatform-metadata-retrieve
Deploy metadata to an orgplatform-metadata-deploy
Create a scratch org for comparisondx-org-manage
Switch default org after comparisondx-org-switch

Reference File Index

FileWhen to read
references/collection-details.mdFor details on what the collection script gathers and how
references/report-format.mdFor drift score formula and report section details
scripts/collect_org_data.pyData collection script (per org)
scripts/compute_diff.pyDiff computation and report generation script
scripts/introspect_org.pySingle-org introspection report script

관련 작업

같은 저장소의 Skills

더 많은 Skills

모든 Skills
forcedotcom
커뮤니티

platform-custom-application-generate

Use this skill when users need to create or configure tab-based Salesforce Custom Applications with navigation, branding, and action overrides. Trigger when users mention custom apps, application metadata, app navigation, or organizing tabs into applications. Use when users want to create app containers for tabs and pages. Do NOT use when the goal is hosting a React UI bundle in the App Launcher — use experience-ui-bundle-custom-app-generate for that case.

설치 수
1
GitHub Stars
1.1천
업데이트
10월 23일
forcedotcom
커뮤니티

platform-custom-field-generate

Use when users create, generate, or validate Salesforce Custom Field metadata. Trigger on custom fields, field types, Roll-Up Summary, Master-Detail/Lookup relationships, formula fields, picklists, dependent (controlling) picklists, referencing a value set from a field, or scoping picklist values per record type; also field deployment errors, including a record type that won't deploy without a business process. DO NOT TRIGGER for creating/customizing the value set itself — a new GlobalValueSet o

설치 수
1
GitHub Stars
1.1천
업데이트
10월 23일
forcedotcom
커뮤니티

platform-custom-metadata-type-generate

Use to create, generate, or validate Salesforce Custom Metadata Type metadata — the mdt object, fields, and deployable records. Trigger on custom metadata types, CMDT, mdt objects, .md-meta.xml files, or cross-org reference/config data; also admin-maintained mapping/lookup/crosswalk tables (config that changes without a deploy belongs in a CMDT, never hardcoded in Apex/Flow), and CMDT deploy errors. DO NOT TRIGGER for Custom Settings (use platform-custom-setting-generate), business-record object

설치 수
1
GitHub Stars
1.1천
업데이트
10월 23일
forcedotcom
커뮤니티

platform-custom-report-type-generate

Use to create, generate, or validate Salesforce Custom Report Type metadata. Trigger on custom report types, CRTs, cross-object reports, report builder data sources, exposing fields for reporting across related objects, inner vs outer joins in reports, report type categories, or deployment errors for .reportType-meta.xml files. Do NOT trigger for running, editing, or filtering existing reports; creating report folders, dashboards, or list views; or non-authoring reporting questions.

설치 수
1
GitHub Stars
1.1천
업데이트
10월 23일