接続されたSalesforce環境(組織)に対して、匿名Apex(認証を不要とするコード実行方式)を実行するスキルです。.apexファイルまたはコピー&ペーストされたコード片から実行でき、デバッグログ(実行時の詳細記録)を取得し、コンパイルエラーと実行時エラーを表示して、結果を要約します。 次のような場合に使用: 「この匿名Apexを実行して」「このスクリプトを私の環境で実行して」「このApexコード片を実行して」「このコードは何を返すか」「scripts/foo.apexを実行して」といった指示。 検証用スクリプトはセーブポイント(実行地点の保存)と自動ロールバック(実行前の状態に戻す処理)でラップされるため、組織の状態は変わりません。本番環境での実行前には警告を表示します。 **実行しないケース:** - .cls または .trigger ファイルの作成(platform-apex-generate を使用) - Apex単体テストの実行(platform-apex-test-run を使用) - デバッグログの詳細分析(platform-apex-logs-debug を使用)
Use this skill to run anonymous Apex against the connected Salesforce org — from a .apex file or a pasted snippet — capturing the debug log, surfacing compile and runtime errors, and summarizing results. Trigger on phrases like "run this anonymous apex", "execute this script against my org", "run this snippet of Apex", "what does this code return", or "execute scripts/foo.apex". Wraps verification-style scripts in a savepoint and rollback so org state is untouched, and warns before running against production. DO NOT TRIGGER for authoring .cls or .trigger files (use platform-apex-generate), running Apex unit tests (use platform-apex-test-run), or deep debug-log analysis (use platform-apex-logs-debug).
接続されたSalesforce環境に対して匿名Apex(許可されたコード実行)を sf apex run --file で実行し、デバッグログを取得して、コンパイル時およびランタイムの結果を開発者に報告します。
VS Codeの「匿名Apexの実行」コマンドに相当する、エージェント側のスキルです。
このスキルは実行専用です。.clsファイルや.triggerファイルの作成にはplatform-apex-generateを、Apexユニットテストの実行にはplatform-apex-test-runを、詳細なデバッグログ分析(リソース消費の詳細、SQLループの検出など)にはplatform-apex-logs-debugを使用してください。
Bash ツールのみを使用してsf apex runを実行し、Writeツールでテンポラリファイルを作成してください。実行にMCPツールを使用しないでください。
匿名Apexは実行ユーザーの権限で動作し、データベース操作、API呼び出し、プラットフォームイベントが実行可能です。すべての実行を書き込み操作として扱ってください(開発者が明確に読み取り専用だと述べた場合を除く)。
検証スタイルスクリプト(「これをテストして」に推奨): 本体をセーブポイント(一時的な保存地点)とロールバック(元に戻す)で囲み、環境の状態を変更しないようにします:
Savepoint sp = Database.setSavepoint();
try {
// ... テスト対象コード ...
} finally {
Database.rollback(sp);
}
本番環境での注意: 指定された環境が本番環境である場合(sf org display --jsonにスクラッチ環境やサンドボックス環境のマーカーがない場合)、実行前に明確な警告を表示してください。これは情報提供のみです。自動的にブロックされることはありません。本番環境で破壊的なスクリプトを実行する前に、開発者の明確な「実行してください」を待ってください。
自分で生成したか確認した匿名Apexのみ実行してください。開発者がスニペット(コード断片)を貼り付けた場合は、その内容を繰り返し確認した後に実行してください。
設定からアクティブな環境のエイリアスを解決します。target-orgが設定されている場合、コマンドから--target-orgフラグを省略できますが、常にレポートで使用したエイリアスをログに記録してください。
sf config get target-org --json
このスキル全体を通じて、<alias>は解決されたエイリアスまたはユーザー名です。target-orgが設定されていない場合は開発者に確認してください。黙って既定値を選ばないでください。環境が認証されていない場合は、sf org login webで再認証するか、dx-org-switchスキルで環境を切り替えてください。
| モード | 条件 | 操作 |
|---|---|---|
| ファイルモード | 開発者が.apexで終わるパスを指定、またはパスを指定 |
sf apex run --file <path>を直接実行 |
| スニペットモード | 開発者が会話にApexコードを貼り付け | .sfdx/tmp/anon-<unix-ts>.apexに書き込み、その後sf apex run --file <tmp-path>を実行 |
スニペットについてインラインフラグではなくテンポラリファイルを使う理由: 現在のsf apex runCLIは--file(および対話型stdin)のみをサポートしています。--apex-codeフラグのような形式を公開していません。複数行のApexをインラインで渡すと、シェルの特殊文字処理の問題が発生します(文字列内のシングルクォート、バックスラッシュ、埋め込まれた$)。テンポラリファイルに書き込むことが、任意のスニペットに対する唯一の信頼できる方法です。
CLIフラグを事前に確認してください:
sf apex run --help
サポートされるフラグ(現在):--file/-f、--target-org/-o、--api-version、--json、--flags-dir。フラグを自分で追加しないでください — タスクが一覧にないものを要求する場合は、それを開発者に報告してください。推測で対応しないでください。
sf apex runは、実行ユーザーのTraceFlag(トレースフラグ:デバッグ情報記録設定)がアクティブな場合、またはストリーミング監視が有効な場合にのみデバッグログを返します。推奨される方法は、別のターミナルで開発者にログを監視させることです:
sf apex tail log --target-org <alias> --color
このコマンドは実行ユーザーの短期的なTraceFlag を自動作成し、匿名Apexが実行される際のログをストリーミング表示します。レポートでこれを開発者に伝え、コピー&ペーストできるようにしてください。
トレースフラグが設定されていない場合、sf apex runはコードを実行してコンパイル/ランタイムステータスを返しますが、デバッグログの本文は欠落または不完全になります。
入力が貼り付けられたスニペットの場合のみ適用:
mkdir -p .sfdx/tmp
TS=$(date +%s)
# エージェントのWriteツールを使用してスニペット内容を.sfdx/tmp/anon-${TS}.apexに書き込み(シェルのheredocではなく)
エージェントのWriteツール(heredocではなく)を使用し、スニペットが確実に保持されるようにしてください。heredocはコンテンツを追加のシェル展開にさらします。解決されたテンポラリパスをレポートで開発者に伝えてください。実行後、テンポラリファイルを自動削除しないでください。検査用として.sfdx/tmp/の下に保持してください。.sfdx/ディレクトリは慣例的にgitignoreされています。
sf apex run --file <path> --target-org <alias> --json
--jsonを渡してください。通常のフォーマット出力ではコンパイルエラーとランタイムエラーが混在します。target-orgが既に設定されている場合、--target-orgは省略できますが、使用したエイリアスをログに記録してください。sf apex run --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自体が失敗したことを意味します(認証なし、ファイルなし、ネットワークエラー)。生のエラーを報告して停止してください。
.sfdx/tmp/anon-<ts>.logに書き込み、パスを報告。最後の30行を末尾サマリーとしてインラインで記載。ログに存在する場合、これらのパターンをハイライト表示:
| パターン | なぜ重要か |
|---|---|
LIMIT_USAGE_FOR_NS行 |
リソース消費量の目安 — SQL問い合わせ/データベース操作/CPU が上限に近い場合はフラグを立てる |
EXCEPTION_THROWN |
匿名ブロック内の未処理例外 |
FATAL_ERROR |
回復不可能なエラー — 末尾のブロック全体を表示 |
ループ内のSOQL_EXECUTE_BEGINカウント > 1 |
ループ内SQL問い合わせのヒント(platform-apex-logs-debugに引き継ぎ) |
DML_BEGINカウント高 |
バッチ処理されていないデータベース操作のヒント |
ここで完全なログ解析を試みないでください。シグナルのみを表示し、詳細分析はplatform-apex-logs-debugに引き継ぎます。
匿名Apex実行: <1行サマリー — ファイルまたはスニペット、成功または失敗>
環境: <alias> (モード: スクラッチ | サンドボックス | 本番環境)
ソース: <ファイルパス、またはスニペット用テンポラリパス>
コンパイル: 成功 | <エラー + line:column>
ランタイム: 成功 | <例外タイプ + メッセージ>
リソース制限: <CPU=x/10000ms, SOQL=y/100, DML=z/150> (ログに LIMIT_USAGE_FOR_NS が含まれる場合のみ)
ログ: <インライン | パス .sfdx/tmp/anon-<ts>.log>
ロールバック: 実行 | 実行なし | 該当なし
次のステップ: <推奨される後続操作>
"デフォルト環境に対して
scripts/seed-test-data.apexを実行してください。"
sf config get target-org --jsonから<alias>を解決。sf apex run --file scripts/seed-test-data.apex --target-org <alias> --jsonを実行。"
System.debug([SELECT count() FROM Account]);を実行して、件数を教えてください。"
<alias>を解決。.sfdx/tmp/anon-<ts>.apexに書き込み(Write ツール)。sf apex run --file .sfdx/tmp/anon-<ts>.apex --target-org <alias> --jsonを実行。result.logsを解析。件数のUSER_DEBUG行を抽出。.sfdx/tmp/anon-<ts>.apex(参照用に保持)。」"このApexが正しくContactをアップサート(新規作成または更新)し、その後ロールバックしてください。"
<alias>を解決。本番環境の場合、実行前に頭出し警告を表示。
開発者のスニペットをラップ:
Savepoint sp = Database.setSavepoint();
try {
// ---- 開発者スニペット開始 ----
Contact c = new Contact(LastName = 'Smoke', Email = 'smoke@example.com');
upsert c Email;
System.debug('Upserted: ' + c.Id);
// ---- 開
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.
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.
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:
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.
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.
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.
| Mode | When | Action |
|---|---|---|
| File mode | Developer points at an existing path ending in .apex (or any path they specify) |
Run sf apex run --file <path> directly |
| Snippet mode | Developer pastes Apex code into the conversation | Write 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:
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.
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:
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.
Only applies when the input is a pasted snippet:
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
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.
sf apex run --file <path> --target-org <alias> --json
--json. Human-format output conflates compile vs runtime errors.target-org is already configured, --target-org may be omitted, but log the alias used.The sf apex run --json response shape (relevant fields):
{
"status": 0,
"result": {
"compiled": true,
"success": true,
"compileProblem": "",
"exceptionMessage": "",
"exceptionStackTrace": "",
"line": -1,
"column": -1,
"logs": "...full debug log text..."
}
}
Decision tree:
compiled |
success |
Meaning | Surface |
|---|---|---|---|
false |
— | Compile failure | compileProblem, line, column, the offending source line |
true |
false |
Runtime exception | exceptionMessage, exceptionStackTrace, plus log tail |
true |
true |
Success | Whatever 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.
.sfdx/tmp/anon-<ts>.log and report the path. Include the last 30 lines inline as a tail summary.Highlight these patterns when present in the log:
| Pattern | Why 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.
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>
"Run
scripts/seed-test-data.apexagainst my default org."
<alias> from sf config get target-org --json.file not found.sf apex run --file scripts/seed-test-data.apex --target-org <alias> --json."Execute
System.debug([SELECT count() FROM Account]);and tell me the count."
<alias>..sfdx/tmp/anon-<ts>.apex (Write tool).sf apex run --file .sfdx/tmp/anon-<ts>.apex --target-org <alias> --json.result.logs; extract the USER_DEBUG line for the count..sfdx/tmp/anon-<ts>.apex (kept for reference).""Test that this Apex correctly upserts a Contact, then rollback."
Resolve <alias>. If prod, surface a heads-up before running.
Wrap the developer's snippet:
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.');
}
Write to .sfdx/tmp/anon-<ts>.apex, execute, parse JSON.
Report compile/runtime status, the upserted Id from the log, and Rollback: applied.
| Symptom | Cause | Recovery |
|---|---|---|
No authorization information found for ... |
Org not authenticated, or alias is wrong | Run 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 error | Surface compileProblem, line, column; show that line; suggest a fix |
success: false with exceptionMessage |
Runtime exception inside the anonymous block | Surface 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 execution | Surface raw stderr; do not retry blindly |
| Unrecognized flag error | Spec drift with the installed CLI | Re-check sf apex run --help; do not invent flags |
--json.<alias> from configuration or the developer; never hardcode.--apex-code-style inline flags — they are not supported by the current CLI and are escape-hostile. Always go through --file.Database.setSavepoint() + Database.rollback()..sfdx/tmp/..cls/.trigger files. For those, hand off to platform-apex-generate, the deploy skills, or platform-apex-test-generate.platform-apex-logs-debug.原文・著作権は Anthropic および各プラグイン作者に帰属します。日本語訳は Claude API による自動翻訳です。