关于 dx-org-analyze
用于比较 Salesforce 组织配置或检查单个组织的技能,面向管理员和团队。通过 SF CLI 收集元数据、权限、许可及深层数据差异,并生成 JSON 和 Markdown 报告。
主要功能
- 01比较两个组织的配置差异
- 02检查单个组织并生成清单
- 03分析元数据、权限与许可
- 04对 Apex、Flow 等进行深层差异分析
- 05输出 JSON 与 Markdown 报告
适用场景
- 01核对源组织与目标组织的配置漂移
- 02盘点单个组织的元数据与设置
- 03排查许可或权限差异
- 04为组织比较留存报告
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ forcedotcom/ sf-skills --skill dx-org-analyze安装后在 Claude Code 中输入/dx-org-analyze确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdreferences/collection-details.mdreport-format.mdscripts/collect_org_data.pycompute_diff.pyintrospect_org.pytests/README.mdtest_compute_diff.shtest_consistency.shtests/fixtures/org_a.jsonorg_b.json详细介绍
工具限制
仅使用 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。
数据访问层级
查询组织数据时,始终遵循以下优先顺序:
- SF CLI 命令——首选。使用
sf org list metadata-types、sf org list metadata、sf org display、sf data query、sf limits api display等命令。 - 直接 REST/Tooling API 调用——最后手段,仅在 SF CLI 无法提供数据时使用。
切勿绕过此层级。如果存在可执行该操作的 SF CLI 命令,即使直接调用 API 更简单,也必须使用 SF CLI 命令。
身份验证规则
- 所有身份验证必须通过 SF CLI(
sf org login web、sf org login jwt、sf org login access-token)。 - 切勿接受用户直接提供的原始凭据(用户名 + 密码)、会话 ID 或访问令牌。
- 收集脚本只能通过
sf org display --json获取访问令牌。
工作流
步骤 0:列出已通过身份验证的组织
运行此命令,发现所有已通过身份验证的组织:
sf org list --json --skip-connection-status
解析 JSON 输出。从所有类别(devHubs、nonScratchOrgs、scratchOrgs、sandboxes、other)中收集组织。以易读的表格列出已通过身份验证的组织:
| # | 别名 | 用户名 | 实例 URL | 组织 ID | 类型 |
|---|
如果已通过身份验证的组织少于 2 个,但至少有 1 个可用,则提供单组织检查模式(参见下文的检查工作流)。如果没有组织通过身份验证,则停止并告知用户:
你至少需要 1 个已通过身份验证的组织。运行
sf org login web --alias <name>以进行身份验证。
如果用户明确请求单组织检查或清点,则无论有多少个组织可用,都使用检查工作流。
步骤 1:用户选择两个组织
请用户从列表中选择两个组织。必须明确指定两者——不允许隐式/默认组织。
选择两个要比较的组织。哪个是源组织(参考/预期状态)?哪个是目标组织(用于对比的组织)?
接受:列表中的别名、用户名或编号。将每项选择解析为具体的用户名。如果组织没有别名,请提示用户分配别名。确认:
正在比较:
- 源组织:
<alias>(<username>)- 目标组织:
<alias>(<username>)
步骤 2:验证连接
对每个组织执行轻量级查询,确认其可访问性,且不泄露机密:
sf data query --target-org <alias-or-username> --query "SELECT Id FROM Organization LIMIT 1" --json
如果查询成功(退出代码为 0 且返回了一条记录),则表示组织已连接。如果因 INVALID_SESSION_ID 或身份验证错误而失败:
sf org login web --alias <alias>
步骤 3:收集数据(每个组织)
生成唯一的运行 ID,并为每个组织运行收集脚本:
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。
步骤 4:计算差异并生成报告
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。
步骤 5:呈现结果
读取 /tmp/dx-org-comparison-${RUN_ID}.md 并呈现给用户。如果用户提出后续问题,请使用 /tmp/dx-org-comparison-${RUN_ID}.json 查询数据。然后确定输出目录,并将两个文件复制到该目录:
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
检查工作流(单组织模式)
当用户想要检查单个组织的配置,或只有一个组织已通过身份验证时,请使用此工作流。
检查步骤 1:验证连接
sf data query --target-org <alias-or-username> --query "SELECT Id FROM Organization LIMIT 1" --json
检查步骤 2:收集数据
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}
检查步骤 3:生成报告
python3 ./scripts/introspect_org.py \
--org /tmp/dx-org-analysis-${RUN_ID} \
--output /tmp/dx-org-analysis-${RUN_ID} \
--format both \
--label "OrgName"
检查步骤 4:展示结果
读取 /tmp/dx-org-analysis-${RUN_ID}.md 并向用户展示。报告涵盖:元数据清单、组织设置、组织限制、已安装的软件包、许可证、系统权限和深度数据记录。然后解析输出目录并将两个文件复制到该目录:
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
报告结构
生成的报告包括:
- 差异评分 — 加权总体评分(元数据占 60%,权限占 30%,配置文件占 10%),并附严重级别(LOW/MODERATE/HIGH/CRITICAL)
- 摘要统计信息 — 每种元数据类型的计数,以及深度数据中的“相同/不同”列
- 按类型分类的元数据组件 — 每种类型中仅源组织有、仅目标组织有和共有的组件
- 配置文件 — 共有、仅源组织有、仅目标组织有
- 已安装的软件包 — 版本比较、仅源组织有、仅目标组织有
- 软件包组件 — 按命名空间分组的带命名空间组件
- 组织权限 — 按类别列出的布尔值启用/禁用差异,以及值差异
- 系统权限 — PermissionSet 上的 PermissionsXxx 字段,以及各权限集的差异
- 组织值和限制 — 按 Identity、Storage、API、Feature Limits 分组
- 许可证 — 用户、权限集和软件包的许可证数量差异
- 深度数据 — Apex、Flows、Validation Rules、Custom Fields 等的内容级差异
规则 / 约束
| 约束 | 原因 |
|---|---|
始终为 sf 命令使用 --json | 结构化输出可确保可靠解析 |
| 将组织解析为用户名,而非别名 | 别名可能有歧义;用户名是唯一的 |
| 跳过已过期和已断开连接的组织 | 无法从无法访问的组织查询元数据 |
| 只读——绝不部署或修改 | 此技能只进行比较,不会更改任何一个组织 |
| 仅使用 SF CLI 身份验证 | 所有身份验证都通过 SF CLI 凭据存储进行 |
| 必须明确指定两个组织 | 绝不比较未命名或隐式/默认组织 |
故障排除
| 问题 | 解决方法 |
|---|---|
| “No org found for <alias>” | 组织未通过身份验证——运行 sf org login web --alias <name> |
| 已通过身份验证的组织少于 2 个 | 比较前请为其他组织进行身份验证 |
| “INVALID_SESSION_ID” 或身份验证错误 | 会话已过期——重新运行 sf org login web --alias <name> |
| 收集脚本以代码 2 退出 | 会话已过期——重新进行身份验证并重试 |
| 列出元数据时出现 API 限制错误 | 使用 --skip-deep-data,以较少细节更快完成检查 |
| 版本差异(DE 与 EE) | 许多差异由版本本身决定,并非配置漂移 |
| 大型组织的深度数据处理超时 | 使用 --skip-deep-data 标志;针对后续检查运行完整的深度数据处理 |
跨技能集成
| 需求 | 委托给 |
|---|---|
| 从组织检索特定元数据 | platform-metadata-retrieve |
| 将元数据部署到组织 | platform-metadata-deploy |
| 创建用于比较的临时组织 | dx-org-manage |
| 比较后切换默认组织 | dx-org-switch |
参考文件索引
| 文件 | 何时阅读 |
|---|---|
references/collection-details.md | 了解收集脚本收集哪些内容以及如何收集 |
references/report-format.md | 了解差异评分公式和报告各部分的详情 |
scripts/collect_org_data.py | 数据收集脚本(每个组织) |
scripts/compute_diff.py | 差异计算和报告生成脚本 |
scripts/introspect_org.py | 单组织检查报告脚本 |