dx-org-analyze

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

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
.

仅使用 Bash 工具来执行所有
sf
CLI 命令和 Python 脚本。
sf
命令始终包含
--json
。不要使用
mcp__salesforce_dx__*
工具。
用于评估/测试的输出产物: 当有输出目录时,将结果写入该目录。执行技能后:(1)如果用户指定了输出路径,立即写入;(2)否则运行
[ -d force-app/main/adk-eval-output/ ] && echo 'force-app/main/adk-eval-output'
检测评估目录;(3)将完整 JSON 结果写入
<output-dir>/dx-org-analyze-result.json
,并将 Markdown 报告写入
<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.

查询组织数据时,始终遵循以下优先级:
  1. SF CLI 命令 — 首选。使用
    sf org list metadata-types
    、
    sf org list metadata
    、
    sf org display
    、
    sf data query
    、
    sf limits api display
    等。
  2. 直接 REST/Tooling API 调用 — 最后手段,仅当 SF CLI 无法提供数据时。
切勿绕过此层级。如果存在适用于该操作的 SF CLI 命令,即使直接 API 调用更简单,也应使用它。

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
    .

  • 所有认证必须通过 SF CLI(
    sf org login web
    、
    sf org login jwt
    、
    sf org login access-token
    )。
  • 切勿直接接受用户的原始凭据(用户名 + 密码)、会话 ID 或访问令牌。
  • 收集脚本仅通过
    sf org display --json
    获取其访问令牌。

Workflow

工作流程

Step 0: List Authenticated Orgs

步骤 0:列出已认证的 Org

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.
运行此命令以发现所有已认证的 org:
bash
sf org list --json --skip-connection-status
解析 JSON 输出。从所有桶(
devHubs
、
nonScratchOrgs
、
scratchOrgs
、
sandboxes
、
other
)中收集 org。以可读表格形式展示已认证的 org:
#别名用户名实例 URLOrg ID类型
如果已认证的 org 少于 2 个但至少有 1 个可用,提供单组织内省模式(参见下方内省工作流程)。如果没有已认证的 org,则停止并建议:
您至少需要 1 个已认证的 org。运行
sf org login web --alias <name>
进行认证。
如果用户明确请求单组织内省或清单,无论有多少个可用 org,均使用内省工作流程。

Step 1: User Selects Two Orgs

步骤 1:用户选择两个 Org

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>
    )
要求用户从列表中选择两个 org。两者都必须明确命名——不允许隐式/默认 org。
选择两个 org 进行比较。哪个是源(参考/预期状态)?哪个是目标(待比较对象)?
接受:别名、用户名或列表中的编号。将每个选择解析为具体的用户名。如果 org 缺少别名,提示用户分配一个。确认:
比较:
  • 源:
    <alias>
    (
    <username>
    )
  • 目标:
    <alias>
    (
    <username>
    )

Step 2: Validate Connectivity

步骤 2:验证连接

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>
对于每个 org,使用不会泄露机密的轻量查询确认可达性:
bash
sf data query --target-org <alias-or-username> --query "SELECT Id FROM Organization LIMIT 1" --json
如果查询成功(退出码 0 且返回一条记录),则 org 已连接。如果失败并出现
INVALID_SESSION_ID
或认证错误:
bash
sf org login web --alias <alias>

Step 3: Collect Data (per org)

步骤 3:收集数据(每个 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
.
生成唯一的运行 ID 并为每个 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
退出码:
0
= 成功,
1
= 致命错误(向用户报告 stderr),
2
= 会话过期(重新认证步骤 2 并重试)。
有关收集脚本收集内容的详细信息,请参阅
references/collection-details.md
。

Step 4: Compute Diff and Report

步骤 4:计算差异和报告

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.
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"
如果用户希望详细列出共享组件,请使用
--show-shared
。

Step 5: Present Results

步骤 5:呈现结果

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

读取
/tmp/dx-org-comparison-${RUN_ID}.md
并呈现给用户。如果用户提出后续问题,请使用
/tmp/dx-org-comparison-${RUN_ID}.json
进行数据查询。然后解析输出目录并将两个文件复制到那里:
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.
当用户想要检查单个 org 的配置,或仅有一个 org 已认证时,使用此工作流程。

Introspect Step 1: Validate Connectivity

内省步骤 1:验证连接

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

Introspect Step 2: Collect Data

内省步骤 2:收集数据

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}
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

内省步骤 3:生成报告

bash
python3 ./scripts/introspect_org.py \
  --org /tmp/dx-org-analysis-${RUN_ID} \
  --output /tmp/dx-org-analysis-${RUN_ID} \
  --format both \
  --label "OrgName"
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

内省步骤 4:呈现结果

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

读取
/tmp/dx-org-analysis-${RUN_ID}.md
并呈现给用户。报告涵盖:元数据清单、组织设置、组织限制、已安装包、许可、系统权限和深度数据记录。然后解析输出目录并将两个文件复制到那里:
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.

生成的报告包括:
  1. 漂移评分 — 加权总分(60% 元数据、30% 权限、10% 配置文件),带严重级别(低/中/高/严重)
  2. 摘要统计 — 每种元数据类型的计数,包含来自深度数据的相同/不同列
  3. 按类型划分的元数据组件 — 仅源有、仅目标有、按类型共享
  4. 配置文件 — 共享、仅源、仅目标
  5. 已安装包 — 版本比较、仅源、仅目标
  6. 包组件 — 按命名空间分组的命名空间组件
  7. 组织权限 — 按类别划分的布尔启用/禁用差异,以及值差异
  8. 系统权限 — PermissionSet 上的 PermissionsXxx 字段,按集合差异
  9. 组织值和限制 — 按身份、存储、API、功能限制分组
  10. 许可 — 用户、权限集、包许可数量差异
  11. 深度数据 — Apex、Flow、验证规则、自定义字段等的内容级差异

Rules / Constraints

规则 / 约束

ConstraintRationale
Always use
--json
with sf commands
Structured 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

约束理由
始终对 sf 命令使用
--json
结构化输出,便于可靠解析
将 org 解析为用户名,而非别名别名可能有歧义;用户名是唯一的
跳过过期和断开的 org无法从未知 org 查询元数据
只读——绝不部署或修改此技能仅比较,绝不更改任一 org
仅 SF CLI 认证所有认证都通过 SF CLI 凭据存储
两个 org 必须明确绝不比较未命名或隐式/默认 org

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
"INVALID_SESSION_ID" 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

问题解决方法
"未找到 org
<alias>
"
org 未认证——运行
sf org login web --alias <name>
已认证 org 少于 2 个在比较之前认证更多 org
"INVALID_SESSION_ID" 或认证错误会话过期——重新运行
sf org login web --alias <name>
收集脚本退出代码 2会话过期——重新认证并重试
元数据列表期间出现 API 限制错误使用
--skip-deep-data
以更快地通过且减少细节
版本差异(DE 与 EE)许多差异是版本固有的,而非配置漂移
大型 org 在深度数据上超时使用
--skip-deep-data
标志;在有针对性的后续操作中运行完整深度数据

Cross-Skill Integration

跨技能集成

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

需求委托给
从 org 检索特定元数据
platform-metadata-retrieve
将元数据部署到 org
platform-metadata-deploy
创建用于比较的 scratch org
dx-org-manage
比较后切换默认 org
dx-org-switch

Reference File Index

参考文件索引

FileWhen to read
references/collection-details.md
For details on what the collection script gathers and how
references/report-format.md
For drift score formula and report section details
scripts/collect_org_data.py
Data collection script (per org)
scripts/compute_diff.py
Diff computation and report generation script
scripts/introspect_org.py
Single-org introspection report script
文件何时阅读
references/collection-details.md
了解收集脚本收集什么以及如何收集
references/report-format.md
了解漂移评分公式和报告部分细节
scripts/collect_org_data.py
数据收集脚本(每个 org)
scripts/compute_diff.py
差异计算和报告生成脚本
scripts/introspect_org.py
单组织内省报告脚本