mcpField
P
platform-apex-anonymous-run

platform-apex-anonymous-run

github.com/forcedotcom开发1.1k3.2k 次安装1 天前更新
代码仓库

关于 platform-apex-anonymous-run

为 Salesforce 开发者提供运行匿名 Apex 的 Agent 技能,通过 Salesforce CLI 执行代码并整理编译、运行结果与调试日志。它强调执行可能修改组织数据,并提供回滚验证和生产环境确认规则。

主要功能

  1. 01通过 Salesforce CLI 执行 Apex
  2. 02区分编译错误与运行时错误
  3. 03捕获并呈现调试日志
  4. 04验证脚本支持保存点回滚
  5. 05执行前检查目标组织

适用场景

  1. 01在连接的组织中运行 Apex 片段
  2. 02验证脚本并回滚数据更改
  3. 03排查匿名 Apex 的编译或运行错误

MCP 相关

此技能规定使用 Bash 工具运行 Salesforce CLI,明确禁止使用 MCP 工具执行 Apex。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/forcedotcom/sf-skills --skill platform-apex-anonymous-run

安装后在 Claude Code 中输入/platform-apex-anonymous-run确认已加载。

详细介绍

platform-apex-anonymous-run

通过 sf apex run --file 对已连接的 Salesforce 组织运行匿名 Apex,捕获调试日志,并向开发者说明编译时和运行时结果。

这相当于 Agent 端的 VS Code Execute Anonymous Apex(文档和选区)命令。

此技能用于运行,不用于生成——编写 .cls / .trigger 文件请使用 platform-apex-generate;运行 Apex 单元测试请使用 platform-apex-test-run;深入分析调试日志(管理器用量明细、SOQL 循环检测)请转交给 platform-apex-logs-debug。


工具限制

只能使用 Bash 工具执行 sf apex run,并使用 Write 工具暂存代码片段临时文件。不要使用 MCP 工具执行命令。


匿名 Apex 并非只读操作

匿名 Apex 会以当前运行用户的权限执行,可以执行 DML、发出调用请求并发布平台事件。除非开发者另有说明,否则每次运行都应视为写入操作。

  • **验证类脚本(针对“测试这个”的首选方式):**将脚本主体放在保存点和回滚操作中,确保组织状态不受影响:

    Savepoint sp = Database.setSavepoint();
    try {
        // ... code under test ...
    } finally {
        Database.rollback(sp);
    }
    
  • **生产组织提醒:**如果解析出的 <alias> 指向生产组织(sf org display --json 中没有临时组织/沙盒标记),运行前请明确提醒。这仅作告知,不会自动阻止操作。若脚本会在生产环境中执行破坏性操作,务必等开发者明确回复“是,运行”后再执行。

  • 绝不要运行你未生成或未查看过的匿名 Apex——如果开发者粘贴了代码片段,请先原样复述并确认,然后再执行。


工作流

第 1 步 — 确定目标组织

从配置中解析活动组织别名。如果设置了 target-org,命令中可以省略 --target-org 标志,但报告中始终要注明使用的别名。

sf config get target-org --json

在此技能中,<alias> 指解析出的别名或用户名。如果未设置 target-org,请询问开发者;不要默认使用某个组织。如果组织未经身份验证,请使用 sf org login web 重新进行身份验证,或使用 dx-org-switch 技能切换组织。

第 2 步 — 确定输入模式
模式情况操作
文件模式开发者指定一个以 .apex 结尾的现有路径(或其指定的任意路径)直接运行 sf apex run --file <path>
代码片段模式开发者在对话中粘贴 Apex 代码先将代码写入 .sfdx/tmp/anon-<unix-ts>.apex,再运行 sf apex run --file <tmp-path>

为什么代码片段要写入临时文件,而不使用内联标志? 当前的 sf apex run CLI 只支持 --file(以及交互式 stdin),不支持 --apex-code 标志。即使其他工具支持内联代码,多行 Apex 内联传递也容易遇到 shell 转义问题(字符串字面量中的单引号、反斜杠、内嵌的 $)。对于任意代码片段,写入临时文件是唯一可靠的方式。

更改用法前,请先验证 CLI 标志:

sf apex run --help

截至本文编写时,支持的标志包括:--file/-f、--target-org/-o、--api-version、--json、--flags-dir。不要杜撰标志——如果任务要求使用未列出的标志,请告知开发者,不要猜测。

第 3 步 — 设置跟踪标志(以获取有用的日志)

只有在当前运行用户已启用 TraceFlag(或已附加流式日志跟踪)时,sf apex run 才会返回调试日志。推荐做法是让开发者在另一个终端中跟踪日志:

sf apex tail log --target-org <alias> --color

此操作会为当前运行用户自动创建一个短时 TraceFlag,并在匿名 Apex 执行时流式输出日志。请在报告中提及这一点,方便开发者复制粘贴命令。

如果未设置跟踪标志,sf apex run 仍会执行代码并返回编译/运行时状态,但调试日志正文会缺失或内容较少。

步骤 4 — 代码片段模式:写入临时文件

仅当输入是粘贴的代码片段时适用:

mkdir -p .sfdx/tmp
TS=$(date +%s)
# write the snippet content to .sfdx/tmp/anon-${TS}.apex via the Write tool, NOT via shell heredoc

使用 Agent 的 Write 工具(不要使用 heredoc),以原样保留代码片段——heredoc 会对内容进行额外的 shell 展开。在报告中向开发者回显解析后的临时路径。执行后不要自动清理临时文件——将其保留在 .sfdx/tmp/ 下以供检查。按照惯例,.sfdx/ 目录会被 git 忽略。

步骤 5 — 执行
sf apex run --file <path> --target-org <alias> --json
  • 始终传入 --json。人类可读格式的输出会混淆编译错误和运行时错误。
  • 如果已配置 target-org,可以省略 --target-org,但要记录使用的别名。
  • 命令遇到编译错误时会以非零状态码退出。捕获标准输出和解析后的 JSON。
步骤 6 — 解析 JSON 响应

sf apex run --json 响应结构(相关字段):

{
  "status": 0,
  "result": {
    "compiled": true,
    "success": true,
    "compileProblem": "",
    "exceptionMessage": "",
    "exceptionStackTrace": "",
    "line": -1,
    "column": -1,
    "logs": "...full debug log text..."
  }
}

判定流程:

compiledsuccess含义呈现内容
false—编译失败compileProblem、line、column、出错的源代码行
truefalse运行时异常exceptionMessage、exceptionStackTrace,以及日志尾部
truetrue成功脚本通过 System.debug 输出的内容(从 logs 中提取)

顶层的 status !== 0 表示 CLI 本身执行失败(未通过身份验证、找不到文件、网络问题)。呈现原始错误并停止。

步骤 7 — 呈现调试日志
  • 短日志(少于约 200 行): 在报告中用围栏代码块内联日志正文。
  • 长日志: 将日志写入 .sfdx/tmp/anon-<ts>.log 并报告路径。内联显示最后 30 行作为尾部摘要。
  • 日志为空或缺失: 可能没有启用 TraceFlag。呈现步骤 3 中的设置提示,并根据返回的编译/运行时状态继续处理。

如果日志中出现以下模式,请突出显示:

模式重要性
LIMIT_USAGE_FOR_NS 行Governor 用量快照——标记接近上限的 SOQL/DML/CPU 用量
EXCEPTION_THROWN匿名代码块中出现未处理异常
FATAL_ERROR不可恢复错误——显示完整的尾部内容
循环内 SOQL_EXECUTE_BEGIN 次数 > 1SOQL 循环提示(转交给 platform-apex-logs-debug)
DML_BEGIN 次数较多未批处理 DML 提示

不要在此处尝试完整解析日志——只呈现信号,然后转交给 platform-apex-logs-debug 进行深入分析。

步骤 8 — 报告
Anonymous Apex run: <one-line summary — file or snippet, success or failure>
Org: <alias>  (mode: scratch | sandbox | production)
Source: <file path or temp path for snippet>
Compile: success | <error + line:column>
Runtime: success | <exception type + message>
Limits: <CPU=x/10000ms, SOQL=y/100, DML=z/150>  (only when log includes LIMIT_USAGE_FOR_NS)
Log: <inline | path .sfdx/tmp/anon-<ts>.log>
Rollback: applied | not applied | n/a
Next: <suggested follow-up>

示例

示例 1 — 文件模式

“针对我的默认组织运行 scripts/seed-test-data.apex。”

  1. 通过 sf config get target-org --json 解析 <alias>。
  2. 确认文件存在;如果不存在,则停止并提示 file not found。
  3. 运行 sf apex run --file scripts/seed-test-data.apex --target-org <alias> --json。
  4. 解析 JSON。报告编译/运行时状态、日志尾部和组织模式。
  5. 建议:“如果此操作填充了真实数据,而你想在不持久化数据的情况下进行验证,请使用回滚包装器重新运行(代码片段模式)。”
示例 2 — 代码片段模式(读取查询)

“执行 System.debug([SELECT count() FROM Account]); 并告诉我计数。”

  1. 解析 <alias>。
  2. 回显代码片段并确认。
  3. 将代码片段写入 .sfdx/tmp/anon-<ts>.apex(使用 Write 工具)。
  4. 运行 sf apex run --file .sfdx/tmp/anon-<ts>.apex --target-org <alias> --json。
  5. 解析 result.logs;提取用于获取计数的 USER_DEBUG 行。
  6. 报告:“Account 数量 = N。来源:.sfdx/tmp/anon-<ts>.apex(已保留以供参考)。”
示例 3 — 回滚验证

“测试这段 Apex 是否能正确 upsert Contact,然后回滚。”

  1. 解析 <alias>。如果是生产环境,运行前先提示。

  2. 包装开发者的代码片段:

    Savepoint sp = Database.setSavepoint();
    try {
        // ---- developer snippet begins ----
        Contact c = new Contact(LastName = 'Smoke', Email = '[email protected]');
        upsert c Email;
        System.debug('Upserted: ' + c.Id);
        // ---- developer snippet ends ----
    } finally {
        Database.rollback(sp);
        System.debug('Rolled back savepoint.');
    }
    
  3. 写入 .sfdx/tmp/anon-<ts>.apex,执行并解析 JSON。

  4. 报告编译/运行时状态、日志中 upsert 的 Id,以及 Rollback: applied。


故障模式

症状原因恢复方法
No authorization information found for ...组织尚未通过身份验证,或别名错误运行 sf org list --json;使用 sf org login web 重新进行身份验证,或使用 dx-org-switch
ENOENT: no such file or directory, open '<path>'.apex 文件路径错误,或相对于错误的当前工作目录确认绝对路径;重新运行
JSON 中的 compileProblem 非空Apex 编译错误显示 compileProblem、line、column;展示对应行;建议修复方法
success: false 且带有 exceptionMessage匿名代码块中发生运行时异常显示异常类型、消息和堆栈;如有治理限制计数,也一并显示
即使成功,logs 字段也为空运行用户没有启用 TraceFlag告知开发者在另一个终端中运行 sf apex tail log --target-org <alias>,然后重新运行
status !== 0 且没有 result执行前发生 CLI、网络或身份验证故障显示原始 stderr;不要盲目重试
无法识别标志的错误已安装的 CLI 与规范不一致重新检查 sf apex run --help;不要臆造标志

规则

  • 始终传入 --json。
  • 始终从配置或开发者处解析 <alias>;绝不要硬编码。
  • 绝不要使用 --apex-code 风格的内联标志——当前 CLI 不支持这些标志,而且容易出现转义问题。始终通过 --file 执行。
  • 执行前,始终将粘贴的代码片段回显给开发者确认。
  • 对于验证类脚本,默认使用 Database.setSavepoint() + Database.rollback() 包装。
  • 对于生产组织,提示风险,但不要自动阻止——由开发者负责决定。
  • 不要自动删除 .sfdx/tmp/ 下的临时文件。
  • 此技能执行匿名 Apex;不会编写、部署或测试 .cls/.trigger 文件。如需处理这些文件,请转交给 platform-apex-generate、部署技能或 platform-apex-test-generate。
  • 如需深入分析日志,请转交给 platform-apex-logs-debug。

评论

支持 Markdown