platform-apex-anonymous-run

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

platform-apex-anonymous-run

platform-apex-anonymous-run

Run anonymous Apex against the connected Salesforce org via
sf apex run --file
, capture the debug log, and narrate compile-time and runtime outcomes back to the developer.
This is the agent-side equivalent of VS Code's Execute Anonymous Apex (document and selection) commands.
This skill is runtime, not generation — for authoring
.cls
/
.trigger
files use
platform-apex-generate
; for running Apex unit tests use
platform-apex-test-run
; for deep debug-log analysis (governor breakdowns, SOQL-in-loop detection) hand off to
platform-apex-logs-debug
.

通过
sf apex run --file
在已连接的Salesforce org上运行匿名Apex,捕获调试日志,并向开发者反馈编译及运行时结果。
这是VS Code中「Execute Anonymous Apex」(文档和选中内容)命令的Agent端等价功能。
此Skill专注于运行时,而非代码生成——如需编写
.cls
/
.trigger
文件,请使用
platform-apex-generate
;如需运行Apex单元测试,请使用
platform-apex-test-run
;如需深度调试日志分析(如 governor 消耗 breakdown、循环内SOQL检测),请转交至
platform-apex-logs-debug
处理。

Tool Restrictions

工具限制

Use ONLY the Bash tool to execute
sf apex run
, and the
Write
tool to stage snippet temp files. Do NOT use MCP tools for execution.

仅使用Bash工具执行
sf apex run
,使用
Write
工具暂存代码片段的临时文件。请勿使用MCP工具执行。

Anonymous Apex is NOT read-only

匿名Apex并非只读

Anonymous Apex executes with the running user's permissions and can perform DML, callouts, and platform events. Treat every invocation as a write unless the developer has stated otherwise.
  • Verification-style scripts (preferred for "test this"): wrap the body in a savepoint + rollback so org state is untouched:
    apex
    Savepoint sp = Database.setSavepoint();
    try {
        // ... code under test ...
    } finally {
        Database.rollback(sp);
    }
  • Production org heads-up: if the resolved
    <alias>
    points at a production org (no scratch/sandbox markers in
    sf org display --json
    ), surface a clear warning before running. This is informational only — there is no automated block. Always wait for an explicit "yes, run it" before executing destructive scripts in prod.
  • Never run anonymous Apex you did not generate or have not been shown — if the developer pastes a snippet, echo it back and confirm before executing.

匿名Apex以运行用户的权限执行,可执行DML、外部调用(callouts)和平台事件。除非开发者明确说明,否则请将每次调用视为写入操作。
  • 验证类脚本(推荐用于“测试此代码”场景):将代码主体包装在保存点+回滚操作中,确保org状态不受影响:
    apex
    Savepoint sp = Database.setSavepoint();
    try {
        // ... 待测试代码 ...
    } finally {
        Database.rollback(sp);
    }
  • 生产环境提醒:如果解析后的
    <alias>
    指向生产环境org(
    sf org display --json
    中无scratch/sandbox标记),在运行前需显示明确警告。这仅为提示信息——无自动拦截机制。在生产环境中执行破坏性脚本前,务必等待开发者明确回复“yes, run it”。
  • 切勿运行未生成或未展示的匿名Apex:如果开发者粘贴了代码片段,需先回显该片段并确认后再执行。

Workflow

工作流程

Step 1 — Identify the target org

步骤1 — 确定目标org

Resolve the active org alias from configuration. If
target-org
is set, the
--target-org
flag may be omitted from the command, but always log which alias was used in the report.
bash
sf config get target-org --json
Throughout this skill,
<alias>
is the resolved alias or username. If no
target-org
is set, ask the developer; do not silently default. If the org is not authenticated, re-authenticate with
sf org login web
or switch orgs with the
dx-org-switch
skill.
从配置中解析激活的org别名。如果已设置
target-org
,则命令中可省略
--target-org
参数,但需在报告中记录使用的别名。
bash
sf config get target-org --json
在整个Skill流程中,
<alias>
为解析后的别名或用户名。如果未设置
target-org
,请询问开发者;请勿静默默认。如果org未认证,请使用
sf org login web
重新认证,或使用
dx-org-switch
Skill切换org。

Step 2 — Resolve the input mode

步骤2 — 解析输入模式

ModeWhenAction
File modeDeveloper points at an existing path ending in
.apex
(or any path they specify)
Run
sf apex run --file <path>
directly
Snippet modeDeveloper pastes Apex code into the conversationWrite to
.sfdx/tmp/anon-<unix-ts>.apex
first, then run
sf apex run --file <tmp-path>
Why a temp file for snippets, instead of an inline flag? The current
sf apex run
CLI only supports
--file
(and interactive stdin). It does not expose an
--apex-code
flag. Even where inline code is supported by other tooling, multi-line Apex passed inline runs into shell-escaping pitfalls (single quotes in string literals, backslashes, embedded
$
). Writing to a temp file is the only reliable path for arbitrary snippets.
Verify CLI flags before deviating:
bash
sf apex run --help
Supported flags (as of writing):
--file/-f
,
--target-org/-o
,
--api-version
,
--json
,
--flags-dir
. Do not invent flags — if the task asks for something not listed, surface that to the developer rather than guessing.
模式触发场景操作
文件模式开发者指定了以
.apex
结尾的现有路径(或任意指定路径)
直接运行
sf apex run --file <path>
代码片段模式开发者在对话中粘贴了Apex代码先将代码写入
.sfdx/tmp/anon-<unix-ts>.apex
,再运行
sf apex run --file <tmp-path>
为何代码片段要写入临时文件而非使用内联参数? 当前
sf apex run
CLI仅支持
--file
(和交互式标准输入)。它不支持
--apex-code
参数。即使其他工具支持内联代码,多行Apex通过内联传递会遇到shell转义问题(字符串字面量中的单引号、反斜杠、嵌入的
$
)。写入临时文件是处理任意代码片段的唯一可靠方式。
在偏离前请验证CLI参数:
bash
sf apex run --help
当前支持的参数(截至文档编写时):
--file/-f
,
--target-org/-o
,
--api-version
,
--json
,
--flags-dir
请勿自行创造参数——如果任务要求的功能未在列表中,请告知开发者而非猜测。

Step 3 — Set up trace flags (for useful logs)

步骤3 — 设置跟踪标记(获取有用日志)

sf apex run
returns a debug log only if a
TraceFlag
is active for the running user (or a streaming tail is attached). Recommended path — let the developer tail logs in another terminal:
bash
sf apex tail log --target-org <alias> --color
This auto-creates a short-lived TraceFlag for the running user and streams logs as anonymous Apex executes. Mention this in the report so the developer can copy/paste it.
If no trace flag is set up,
sf apex run
will still execute the code and return compile/runtime status — only the debug log body will be missing or sparse.
仅当运行用户存在激活的
TraceFlag
(或已附加流式日志尾部)时,
sf apex run
才会返回调试日志。推荐方案——让开发者在另一个终端中跟踪日志:
bash
sf apex tail log --target-org <alias> --color
此命令会自动为运行用户创建一个短期的TraceFlag,并在匿名Apex执行时流式输出日志。需在报告中提及此命令,以便开发者复制使用。
如果未设置跟踪标记,
sf apex run
仍会执行代码并返回编译/运行状态——仅调试日志内容会缺失或简略。

Step 4 — Snippet mode: write the temp file

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

Only applies when the input is a pasted snippet:
bash
mkdir -p .sfdx/tmp
TS=$(date +%s)
仅适用于输入为粘贴的代码片段的场景:
bash
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

通过Write工具将代码片段内容写入.sfdx/tmp/anon-${TS}.apex,请勿使用shell heredoc


Use the agent's `Write` tool (not a heredoc) so the snippet is preserved verbatim — heredocs subject the content to additional shell expansion. Echo the resolved temp path to the developer in the report. Do not auto-clean the temp file after execution — leave it under `.sfdx/tmp/` for inspection. The `.sfdx/` directory is conventionally gitignored.

使用Agent的`Write`工具(而非heredoc)确保代码片段被完整保留——heredoc会使内容受到额外的shell扩展。在报告中向开发者回显解析后的临时文件路径。执行后请勿自动清理临时文件——将其保留在`.sfdx/tmp/`目录供检查。`.sfdx/`目录通常会被git忽略。

Step 5 — Execute

步骤5 — 执行

bash
sf apex run --file <path> --target-org <alias> --json
  • Always pass
    --json
    . Human-format output conflates compile vs runtime errors.
  • If
    target-org
    is already configured,
    --target-org
    may be omitted, but log the alias used.
  • The command exits non-zero on compile errors. Capture both stdout and the parsed JSON.
bash
sf apex run --file <path> --target-org <alias> --json
  • 务必传递
    --json
    参数。人类可读格式的输出会混淆编译错误和运行时错误。
  • 如果已配置
    target-org
    ,可省略
    --target-org
    参数,但需记录使用的别名。
  • 命令在编译错误时会返回非零退出码。需同时捕获标准输出和解析后的JSON。

Step 6 — Parse the JSON response

步骤6 — 解析JSON响应

The
sf apex run --json
response shape (relevant fields):
json
{
  "status": 0,
  "result": {
    "compiled": true,
    "success": true,
    "compileProblem": "",
    "exceptionMessage": "",
    "exceptionStackTrace": "",
    "line": -1,
    "column": -1,
    "logs": "...full debug log text..."
  }
}
Decision tree:
compiled
success
MeaningSurface
false
Compile failure
compileProblem
,
line
,
column
, the offending source line
true
false
Runtime exception
exceptionMessage
,
exceptionStackTrace
, plus log tail
true
true
SuccessWhatever the script printed via
System.debug
(extracted from
logs
)
status !== 0
(top-level) means the CLI itself failed (not authenticated, file not found, network). Surface the raw error and stop.
sf apex run --json
的响应结构(相关字段):
json
{
  "status": 0,
  "result": {
    "compiled": true,
    "success": true,
    "compileProblem": "",
    "exceptionMessage": "",
    "exceptionStackTrace": "",
    "line": -1,
    "column": -1,
    "logs": "...完整调试日志文本..."
  }
}
决策树:
compiled
success
含义展示内容
false
编译失败
compileProblem
line
column
、出错的源代码行
true
false
运行时异常
exceptionMessage
exceptionStackTrace
及日志尾部
true
true
执行成功脚本通过
System.debug
输出的内容(从
logs
中提取)
顶层
status !== 0
表示CLI本身执行失败(未认证、文件未找到、网络问题)。需展示原始错误并停止流程。

Step 7 — Surface the debug log

步骤7 — 展示调试日志

  • Short logs (< ~200 lines): inline the log body in the report between fenced code blocks.
  • Large logs: write the log to
    .sfdx/tmp/anon-<ts>.log
    and report the path. Include the last 30 lines inline as a tail summary.
  • Empty / missing log: likely no active TraceFlag. Surface the Step 3 setup hint and proceed with whatever compile/runtime status was returned.
Highlight these patterns when present in the log:
PatternWhy it matters
LIMIT_USAGE_FOR_NS
lines
Governor consumption snapshot — flag SOQL/DML/CPU near-limit
EXCEPTION_THROWN
Unhandled exception within the anonymous block
FATAL_ERROR
Unrecoverable error — show the full trailing block
SOQL_EXECUTE_BEGIN
count > 1 inside a loop
SOQL-in-loop hint (hand off to
platform-apex-logs-debug
)
DML_BEGIN
count high
Unbatched DML hint
Do not attempt full log parsing here — surface signals only, then hand off to
platform-apex-logs-debug
for deep analysis.
  • 短日志(<约200行):在报告中使用代码块内联日志内容。
  • 大日志:将日志写入
    .sfdx/tmp/anon-<ts>.log
    并报告路径。同时内联最后30行作为摘要。
  • 空日志/缺失日志:可能是运行用户无激活的TraceFlag。展示步骤3的设置提示,并继续返回编译/运行状态。
当日志中存在以下模式时需高亮显示:
模式重要性
LIMIT_USAGE_FOR_NS
Governor消耗快照——标记接近限制的SOQL/DML/CPU使用情况
EXCEPTION_THROWN
匿名块内未处理的异常
FATAL_ERROR
不可恢复的错误——展示完整的尾部块
循环内
SOQL_EXECUTE_BEGIN
计数>1
循环内SOQL提示(转交至
platform-apex-logs-debug
处理)
DML_BEGIN
计数过高
未批处理DML提示
请勿在此尝试完整的日志解析——仅展示关键信号,然后转交至
platform-apex-logs-debug
进行深度分析。

Step 8 — Report

步骤8 — 报告

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

text
匿名Apex执行:<一行摘要——文件或代码片段,成功或失败>
Org:<alias> (模式:scratch | sandbox | production)
来源:<文件路径或代码片段的临时路径>
编译:成功 | <错误信息 + 行号:列号>
运行:成功 | <异常类型 + 消息>
限制:<CPU=x/10000ms, SOQL=y/100, DML=z/150> (仅当日志包含LIMIT_USAGE_FOR_NS时展示)
日志:<内联 | 路径.sfdx/tmp/anon-<ts>.log>
回滚:已应用 | 未应用 | 不适用
下一步:<建议后续操作>

Examples

示例

Example 1 — File mode

示例1 — 文件模式

"Run
scripts/seed-test-data.apex
against my default org."
  1. Resolve
    <alias>
    from
    sf config get target-org --json
    .
  2. Confirm the file exists; if not, stop and surface
    file not found
    .
  3. Run
    sf apex run --file scripts/seed-test-data.apex --target-org <alias> --json
    .
  4. Parse JSON. Report compile/runtime status, log tail, and org mode.
  5. Suggest: "If this seeded real data and you'd like to verify without persisting, re-run with the rollback wrapper (snippet mode)."
"在我的默认org上运行
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。报告编译/运行状态、日志尾部及org模式。
  5. 建议:“如果此脚本生成了真实数据且您希望在不持久化的情况下验证,请使用回滚包装重新运行(代码片段模式)。”

Example 2 — Snippet mode (read query)

示例2 — 代码片段模式(查询)

"Execute
System.debug([SELECT count() FROM Account]);
and tell me the count."
  1. Resolve
    <alias>
    .
  2. Echo the snippet back; confirm.
  3. Write the snippet to
    .sfdx/tmp/anon-<ts>.apex
    (Write tool).
  4. Run
    sf apex run --file .sfdx/tmp/anon-<ts>.apex --target-org <alias> --json
    .
  5. Parse
    result.logs
    ; extract the
    USER_DEBUG
    line for the count.
  6. Report: "Account count = N. Source:
    .sfdx/tmp/anon-<ts>.apex
    (kept for reference)."
"执行
System.debug([SELECT count() FROM Account]);
并告诉我计数。"
  1. 解析
    <alias>
  2. 回显代码片段;确认执行。
  3. 通过Write工具将代码片段写入
    .sfdx/tmp/anon-<ts>.apex
  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
    (已保留供参考)。”

Example 3 — Verification with rollback

示例3 — 带回滚的验证

"Test that this Apex correctly upserts a Contact, then rollback."
  1. Resolve
    <alias>
    . If prod, surface a heads-up before running.
  2. Wrap the developer's snippet:
    apex
    Savepoint sp = Database.setSavepoint();
    try {
        // ---- developer snippet begins ----
        Contact c = new Contact(LastName = 'Smoke', Email = 'smoke@example.com');
        upsert c Email;
        System.debug('Upserted: ' + c.Id);
        // ---- developer snippet ends ----
    } finally {
        Database.rollback(sp);
        System.debug('Rolled back savepoint.');
    }
  3. Write to
    .sfdx/tmp/anon-<ts>.apex
    , execute, parse JSON.
  4. Report compile/runtime status, the upserted Id from the log, and
    Rollback: applied
    .

"测试此Apex是否正确upsert Contact,然后回滚。"
  1. 解析
    <alias>
    。如果是生产环境,在运行前显示提醒。
  2. 包装开发者的代码片段:
    apex
    Savepoint sp = Database.setSavepoint();
    try {
        // ---- 开发者代码片段开始 ----
        Contact c = new Contact(LastName = 'Smoke', Email = 'smoke@example.com');
        upsert c Email;
        System.debug('Upserted: ' + c.Id);
        // ---- 开发者代码片段结束 ----
    } finally {
        Database.rollback(sp);
        System.debug('Rolled back savepoint.');
    }
  3. 将代码写入
    .sfdx/tmp/anon-<ts>.apex
    ,执行并解析JSON。
  4. 报告编译/运行状态、日志中的upserted Id,以及
    回滚:已应用

Failure Modes

故障模式

SymptomCauseRecovery
No authorization information found for ...
Org not authenticated, or alias is wrongRun
sf org list --json
; re-auth with
sf org login web
or use
dx-org-switch
ENOENT: no such file or directory, open '<path>'
.apex
file path is wrong or relative to the wrong cwd
Confirm absolute path; re-run
compileProblem
non-empty in JSON
Apex compile errorSurface
compileProblem
,
line
,
column
; show that line; suggest a fix
success: false
with
exceptionMessage
Runtime exception inside the anonymous blockSurface exception type + message + stack; show governor counts if present
logs
field is empty even on success
No active
TraceFlag
for running user
Tell developer to run
sf apex tail log --target-org <alias>
in another terminal, then re-run
status !== 0
with no
result
CLI / network / auth failure before executionSurface raw stderr; do not retry blindly
Unrecognized flag errorSpec drift with the installed CLIRe-check
sf apex run --help
; do not invent flags

症状原因恢复方案
No authorization information found for ...
Org未认证,或别名错误运行
sf org list --json
;使用
sf org login web
重新认证或使用
dx-org-switch
切换org
ENOENT: no such file or directory, open '<path>'
.apex
文件路径错误或相对于错误的当前工作目录
确认绝对路径;重新运行
JSON中
compileProblem
非空
Apex编译错误展示
compileProblem
line
column
;显示出错行;建议修复方案
success: false
且存在
exceptionMessage
匿名块内的运行时异常展示异常类型+消息+堆栈;如果存在,展示governor计数
执行成功但
logs
字段为空
运行用户无激活的
TraceFlag
告知开发者在另一个终端运行
sf apex tail log --target-org <alias>
,然后重新执行
status !== 0
且无
result
CLI/网络/认证在执行前失败展示原始标准错误输出;请勿盲目重试
未识别参数错误已安装的CLI版本与文档不符重新检查
sf apex run --help
;请勿自行创造参数

Rules

规则

  • Always pass
    --json
    .
  • Always resolve
    <alias>
    from configuration or the developer; never hardcode.
  • Never use
    --apex-code
    -style inline flags — they are not supported by the current CLI and are escape-hostile. Always go through
    --file
    .
  • Always echo a pasted snippet back to the developer for confirmation before executing.
  • For verification-style scripts, default to wrapping in
    Database.setSavepoint()
    +
    Database.rollback()
    .
  • For prod orgs, surface a heads-up but do not auto-block — the developer is in charge.
  • Do not auto-delete temp files under
    .sfdx/tmp/
    .
  • This skill executes anonymous Apex; it does not author, deploy, or test
    .cls
    /
    .trigger
    files. For those, hand off to
    platform-apex-generate
    , the deploy skills, or
    platform-apex-test-generate
    .
  • For deep log analysis, hand off to
    platform-apex-logs-debug
    .
  • 务必传递
    --json
    参数。
  • 务必从配置或开发者处解析
    <alias>
    ;请勿硬编码。
  • 切勿使用
    --apex-code
    类的内联参数——当前CLI不支持且存在转义问题。始终通过
    --file
    执行。
  • 对于粘贴的代码片段,务必回显给开发者确认后再执行。
  • 对于验证类脚本,默认使用
    Database.setSavepoint()
    +
    Database.rollback()
    包装。
  • 对于生产环境org,显示提醒但不自动拦截——开发者拥有最终决定权。
  • 请勿自动删除
    .sfdx/tmp/
    下的临时文件。
  • 此Skill用于执行匿名Apex;不负责编写、部署或测试
    .cls
    /
    .trigger
    文件。如需这些操作,请转交至
    platform-apex-generate
    、部署类Skill或
    platform-apex-test-generate
  • 如需深度日志分析,请转交至
    platform-apex-logs-debug