mcpField
A
automation-sandbox-post-copy-configure

automation-sandbox-post-copy-configure

github.com/forcedotcomクラウド・DevOps1.1k2.1k 回インストール1 日前に更新
リポジトリ

automation-sandbox-post-copy-configure について

Salesforce サンドボックスのコピー後自動化 JSON 設定を、対象組織に適用するスキルです。変更前に設定種別とレコードを検証し、メタデータ、スケジュール済み Apex、フローの状態を種別ごとに処理します。

主な機能

  1. 01設定項目と対象組織の検証
  2. 02変更前の設定 API の確認
  3. 03複合 PATCH によるメタデータ更新
  4. 04スケジュール済み Apex の個別処理
  5. 05状態確認付きフローの有効化・無効化

活用シーン

  1. 01Salesforce サンドボックスへのコピー後設定の適用
  2. 02Outbound Messages または Remote Site Settings の更新
  3. 03設定に基づく Apex ジョブのスケジュール
  4. 04対象組織でのフロー有効状態の設定

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/forcedotcom/sf-skills --skill automation-sandbox-post-copy-configure

インストール後、Claude Code で/automation-sandbox-post-copy-configureを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

assets/
api_request_templates.json
scheduled_apex_template.apex
examples/
sample_config_input.json
sample_execution_summary.md
sample_scheduled_apex_config.json
references/
api_endpoints.md
authentication.md
execution_phasing.md
flow_activation_path.md
rules_gotchas.md
scheduled_apex_path.md
scripts/
build-scheduled-apex.mjs
classify-patch-result.mjs
map-metadata-key.mjs
plan-phases.mjs
resolve-target-org.mjs
soql-escape-job-name.mjs

詳細

自動化:サンドボックスのコピー後設定

Salesforce サンドボックスのコピー後自動化 JSON 設定を、対象組織に適用します。正規の ConfigurationName 値として、次の 4 つが固定されています。 OutboundMessages + RemoteSiteSettings → 複合 Metadata PATCH(ステップ A~E); ScheduledApex → 匿名 Apex(ステップ F)。CronTrigger は読み取り専用です; Flows → フローの有効化(ステップ G)。A~E と同じ複合 Metadata トランスポートを使用し、変更キーは activeVersionNumber に固定されます。また、状態を考慮した事前チェック(ALREADY_ACTIVE/ALREADY_INACTIVE)を行います。正規名以外は導出し、describe で検証します。 A~E の各エントリは、PATCH を計画する前にステップ B(describe で 200 が返り、複合 Metadata フィールドがあること)を必ず通過する必要があります。ScheduledApex ではステップ B を省略します。検証できないエントリは概要に明記してスキップし、決して推測で補いません。

ツールの制限事項

sf CLI コマンド(sf data query --use-tooling-api、sf api request rest、sf org display)の実行には、Bash ツールのみを使用してください。 execute_soql などの MCP ツールは使用しないでください。このスキルで必要な複合 Metadata PATCH パターンは、MCP ラッパーでは利用できません。 ユーザーがエイリアスを指定していない場合は、--target-org を付けずに sf を実行してください(ハーネスが CLI のデフォルトを設定します)。--target-org default は渡さないでください(NamedOrgNotFoundError)。SOQL over REST は同じ OAuth を使用します。Salesforce 以外のデータベースへの直接アクセスや、Salesforce 以外の SQL アクセスはできません。

停止 — API 呼び出しの前に必ず実行すること

記憶を頼りに組織へアクセスしてはいけません。最初のリクエストを行う前に、次の手順を実行してください。

  1. ユーザーが指定した正確なパス(デフォルトは ./post-copy-config.json)から、設定 JSON を最初から最後まで読み込みます。各エントリには 5 つのキー(ConfigurationName、Label、Fields、IsActive、ExecutionOrder)がすべて必要です。エントリに不備があれば、中断し、ファイルパスとエントリのインデックスを示してください。一部だけ適用してはいけません。**エントリを捏造してはいけません。**ファイルが見つからない場合は停止してユーザーに確認してください。合成したラベルを使って適用計画を作ってはいけません。
  2. 設定に含まれる ConfigurationName ごとに、PATCH を計画する前に、以下の導出と describe 検証の手順を実行します。API を検証できないエントリを、PATCH の適用予定に含めてはいけません。事前に除外してください。
  3. ユーザーが明示的に指定していない場合は、対象組織のエイリアスをユーザーに確認します。このスキルは稼働中の組織を変更します。誤った組織(たとえば、デフォルトに設定された本番環境のエイリアス)への書き込みは、最も重大な失敗につながります。

設定ファイルを読み込み、すべての異なる ConfigurationName について describe 検証を完了する前に「今から…を適用します」と伝えてしまった場合は、いったん停止して、先にこれらの手順を実行してください。


エントリごとの手順(このスキルの中核)

このスキルでは、以下の正規タイプに対する固定マッピングと、それ以外のタイプに対する導出後の検証手順を定めています。すべてのエントリについて、次の手順を順番に実行してください。マッピングが固定テーブル由来か導出経由かにかかわらず、Step B(describe 検証)は必須です。その HTTP ステータスを必ず概要に記載してください。

ステップ A — Tooling API の sObject とルックアップフィルターを解決する

固定された正規値(権威ある値です。別の sObject 名に置き換えないでください):

ConfigurationNameTooling API sObjectレコードルックアップ用 SOQL
OutboundMessagesWorkflowOutboundMessageSELECT Id, FullName FROM WorkflowOutboundMessage WHERE EntityDefinition.QualifiedApiName = '<Fields.Object>' — その後、クライアント側で FullName == '<Fields.Object>.<Label>' の行を選択します。この sObject では、SOQL で FullName を直接フィルターできません。
RemoteSiteSettingsRemoteProxySELECT Id, SiteName FROM RemoteProxy WHERE SiteName = '<Label>'。
ScheduledApexCronTrigger(読み取り専用 — 匿名 Apex 経由の手順についてはステップ F を参照)ステップ F を参照 — 事前チェックとして SELECT Id FROM CronTrigger WHERE CronJobDetail.Name = '<escaped>' のゲートを実行します。
FlowsFlowDefinition(固定の activeVersionNumber 変更を伴う複合 Metadata PATCH — ステップ G を参照)ステップ G を参照 — 事前チェックとして SELECT Id, DeveloperName, ActiveVersion.VersionNumber FROM FlowDefinition WHERE DeveloperName = '<Fields.FlowApiName>' を実行します。

正規値には、固定された sObject と SOQL をそのまま使用し、「導出」はスキップしてください。OutboundMessage、RemoteSiteSetting、または MasterLabel の別表記を作らないでください。フィールド名の解決(上書き、大小文字のルール、存在確認)は scripts/map-metadata-key.mjs が担います。

非正規値:候補を導出します(通常は Metadata API の型名の単数形)。ステップ B で誤った推測を排除します。ステップ C の一般的な SOQL パターンを使用してください。

ステップ B — 候補が存在し、Metadata の書き込みに対応していることを確認する

候補ごとに、describe を GET します:

sf api request rest \
  "/services/data/v<apiVersion>/tooling/sobjects/<Candidate>/describe/"

次の両方を満たす場合にのみ、候補を採用します:

  • HTTP 200(この sObject がこの組織の Tooling API に存在する)、および
  • describe レスポンスの fields 配列に Metadata という名前のフィールドが含まれている(複合フィールドであり、PATCH の書き込み先です)。

どの候補も両方のゲートを通過しない場合、エントリを API_NOT_IDENTIFIED としてマークし、スキップします。REST パスを推測しないでください — 最悪の場合、誤ったパスは別のレコードを更新し、最善の場合でも 404 になります。

ステップ C — レコード Id を解決する(SOQL-over-REST)

固定された正規値の場合:ステップ A の表にある SOQL を、そのまま実行します(<Label> / <Fields.Object> を置き換えます)。MasterLabel など、別のフィルター列に置き換えないでください — 固定 SOQL は、その sObject に対してテスト済みの正しいフィルターです。

非正規(導出された)sObject の場合:検証済みの sObject に対し、エントリの Label(および存在する場合は Fields.Object)で特定されるレコードをクエリします:

# SOQL to a variable + separate jq call — avoids the most common
# shell-quoting failure in this skill.
SOQL='SELECT Id, FullName FROM <VerifiedSobject> WHERE <UniqueFilter>'
sf data query --use-tooling-api --json --query "$SOQL" \
  > /tmp/entry-<Slug>-lookup.json
ID=$(jq -r '.result.records[0].Id // empty' /tmp/entry-<Slug>-lookup.json)

ステップ B の describe レスポンスに示されたクエリ可能なフィールドに基づいて、<UniqueFilter> を選択します。行に FullName フィールドが含まれる場合、SOQL では通常、FullName = ... による直接フィルターは拒否されます — describe に示された直接の列(例:EntityDefinition.QualifiedApiName、DeveloperName、SiteName)でフィルターし、クライアント側で FullName を照合します(jq -r '.result.records[] | select(.FullName == "<Object>.<Label>") | .Id')。

結果:

  • 0 行 → NOT_FOUND(挿入へのフォールバックは行いません)。
  • クライアント側のフィルタリング後に複数行 → AMBIGUOUS(概要にすべての Id を示してスキップします。誤った Id を使うより、Id がないほうが安全です)。
  • ちょうど 1 行 → ステップ D に進みます。
ステップ D — 現在の Metadata を GET し、変更して PATCH で戻す

Metadata は全体置換です。PATCH で省略したキーは空になります。ステップ D-1 の GET で取得した既存キーをすべて保持し、変更したキーだけを上書きしてください。サマリーの「予定する PATCH ボディ」(適用時およびドライラン時)は、この全キーを統合したオブジェクトです。ドライランでは、詳細な値や組織固有の値を "<preserved-from-GET>" として表示してもかまいませんが、すべてのキーを含める必要があります。

各ステップ D のファイル名には、ステップ C のレコード <Id> を必ず含めてください(例:/tmp/entry-<Id>-meta.json)。フェーズ並列のエントリは作業ディレクトリを共有するため、名前を共通にすると上書きされます。

  1. 現在の Metadata を GET → /tmp/entry-<Id>-meta.json。
  2. 変更キーを解決する(汎用パスのみ。Flows ではステップ G の固定キー activeVersionNumber を使用し、ScheduledApex ではステップ F の匿名 Apex を使用します。どちらの場合もこのスクリプトは実行しないでください)。各 Fields.<Xxx> に対して、次を実行します。 node scripts/map-metadata-key.mjs "<ConfigurationName>" "<ConfigFieldName>" /tmp/entry-<Id>-meta.json {"status":"OK","key":...} の場合は、返されたキーを使用します。{"status":"FIELD_MAP_UNKNOWN",...} の場合は、エントリにその旨を記録してスキップします。このスクリプトを省略し、先頭の文字を単純に小文字化して推測してはいけません。RemoteSiteSettings.Fields.RemoteSiteUrl は Metadata.remoteSiteUrl ではなく Metadata.url に対応します。このような例外はスクリプトが処理します。
  3. PATCH — heredoc で /tmp/entry-<Id>-mutation.json を作成し、次のコマンドでマージします。 jq --slurpfile m /tmp/entry-<Id>-mutation.json '. + $m[0] | {Metadata: .}' /tmp/entry-<Id>-meta.json > /tmp/entry-<Id>-patch.json (JSON の型を保持します)。-b @/tmp/entry-<Id>-patch.json を指定して PATCH し、レスポンスボディを /tmp/entry-<Id>-response.json に保存します。完全な bash の例は references/api_endpoints.md §Step D にあります。--arg は使用しないでください(ブール値や数値が文字列化され、特殊文字で問題が発生します)。PATCH は for attempt in 1 2; do <cmd> && break; done で囲みます。シェルまたは jq のクォート処理に失敗した場合(HTTP リクエストが送信される前に終了コードが 0 以外になった場合)は、1 回再試行してください。
  4. 分類する — node scripts/classify-patch-result.mjs "<httpCode>" /tmp/entry-<Id>-response.json を実行します。終了コード 0 → SUCCESS、終了コード 2 → FAILED(解析済みエラーは標準出力に表示されます)。204 でボディが空でない場合は FAILED です。
ステップ E — 変更が反映されたことを確認する

レコードを再読み込みし、PATCH が反映されたことを確認します。

  • 変更したフィールドが sobject 上で SOQL により直接クエリできる列である場合(まれです。Metadata への書き込みが可能なフィールドのほとんどは該当しません)、Id による SELECT で十分です。
  • それ以外の場合はレコードを GET し、.Metadata 内の対応するキーを確認します。

再読み込みした値が要求した値と一致しない場合は、FAILED_VERIFY と記録してください。PATCH は 204 を返しましたが、変更が確認できません(通常は名前または権限の問題です)。

ステップ F — Scheduled Apex(匿名 Apex のルート)

references/scheduled_apex_path.md を読んでください。ステップ A〜E は適用されません(CronTrigger は読み取り専用です)。匿名 Apex を使う手順 F-1〜F-4(事前チェックの AMBIGUOUS ゲート、スニペットの作成、sf apex run、検証、ドライラン)と、ステップ F のサマリー形式については、リファレンスを参照してください。

ステップ G — Flow の有効化/無効化(Flows)

references/flow_activation_path.md を読んでください。ステップ A と B は引き続き適用されます(固定された sobject は FlowDefinition です。ステップ B では Metadata 複合フィールドを確認します)。固定の変更キー activeVersionNumber を使用する Metadata 複合フィールドの PATCH 手順 G-1〜G-4(ステップ D-2 のキー導出は適用されません)、判断ルール(FlowApiName の検証、ALREADY_ACTIVE/ALREADY_INACTIVE のショートサーキット、禁止されている兄弟キー)、ドライランの仕様、および Flows のサマリー形式については、リファレンスを参照してください。


IsActive のセマンティクス

  • IsActive: true → Steps A–E に従って PATCH します(Flows の場合は Step G)。
  • IsActive: false → PATCH しません。SKIPPED_INACTIVE を記録し、エントリの ConfigurationName と Label を含む箇条書きを Follow-ups に追加して、変更されずに残されたことが顧客に伝わるようにします。

理由:IsActive: false は「このサンドボックスではアクティブではない」という意味であり、「既存レコードを無効化する」という意味ではありません。稼働中の統合を暗黙に無効化することは、そのまま残す場合よりもはるかに大きな影響範囲をもたらします。


標準出力形式(必ずこの形式で出力すること)

./post-copy-<mode>-summary.md に書き込む単一の Markdown サマリー(mode は dry-run または apply)を、ユーザーにも表示します。JSON のサイドファイル(plan/phases.json、requests/*.request.json など)は作成せず、予定または実際のリクエストをすべて Markdown 内に記述します。

Flows と ScheduledApex では、ステップ固有のサマリー形式を使用します。これはラベル付きの説明ブロックで、以下の汎用形式の Planned request: ブロックを置き換えます(フェーズテーブルは変更しません)。各リファレンスの「Summary shape」セクションを参照してください。それ以外の ConfigurationName では、すべて汎用形式を使用します。

フェーズの列挙はスクリプトが管理します。 node scripts/plan-phases.mjs <config.json> を実行し、その phases[] をそのまま使用します。各エントリには、見出し用の ordinal(1 始まり)と、(ExecutionOrder = <raw>) 用の生の値 executionOrder が含まれます。疎な値は詰められ、IsActive:false のエントリには事前に SKIP_INACTIVE が設定されます。実例については references/execution_phasing.md を参照してください。

対象組織の解決はスクリプトが管理します。 node scripts/resolve-target-org.mjs を実行し、返された .alias をヘッダーに使用します。<env:SF_TARGET_ORG> や $SF_TARGET_ORG をそのまま出力してはいけません。

dry-run のエントリでは、HTTP 列の値は — です。サマリーは次の文で終わらせます。 No PATCH requests were issued. To apply, re-run without the dry-run flag.

# Post-Copy Configure Run — <N> entries <planned|applied> against `<alias>`

Config file: `<path>`
Target org: `<alias>`
Mode: <dry-run|apply>

## Phase <ExecutionOrder> — <count> entr(y|ies)

Planned request:
- Method: `PATCH`
- Path: `/services/data/v<apiVersion>/tooling/sobjects/<VerifiedSobject>/<Id>`
- Body: `<FULL merged Metadata: every key from the Step D-1 GET overlaid with the mutated keys. Verbose/org-specific values may render as "<preserved-from-GET>", but every key must be present. NEVER emit a minimal body.>`

| ConfigurationName | Label | Object | Sobject | Describe | Outcome | HTTP |
|-------------------|-------|--------|---------|----------|---------|------|
| <name>            | <lbl> | <obj>  | <VerifiedSobject> | <200 or 404> | <outcome> | <code> |

## Totals

| Outcome | Count |
|---------|-------|
| <state> | <n>   |

## Follow-ups

- <bullet per SKIPPED_INACTIVE / API_NOT_IDENTIFIED / AMBIGUOUS / FIELD_MAP_UNKNOWN / NOT_FOUND entry>

列の意味:Object = エントリの Fields.Object または —。Sobject = Step A で解決された sobject。Describe = Step B の HTTP ステータス(200 は検証済み、404 は API_NOT_IDENTIFIED)— スキップされた Step B が確認できるよう必須です。結果の語彙:SUCCESS、NOT_FOUND、AMBIGUOUS、API_NOT_IDENTIFIED、FIELD_MAP_UNKNOWN、FAILED、FAILED_VERIFY、SKIPPED_INACTIVE、SKIPPED、DRY_RUN、DELETE_NOT_SUPPORTED、ALREADY_ACTIVE(Flows:要求されたバージョンはすでにアクティブ — PATCH なし)、ALREADY_INACTIVE(Flows:Deactivate だがすでに非アクティブ — PATCH なし)、NOT_ATTEMPTED。

スクリプトは内部用です — 生の node scripts/… の標準出力や「node … を実行しました」という説明をサマリーにそのまま記載してはいけません。JSON を読み取り、返された値を使用して、上記の正確な形式で出力します。

対象範囲

  • 対象範囲内:コピー後の設定 JSON を稼働中の組織に適用します — ExecutionOrder ごとにフェーズをグループ化し、sobject を導出・検証し、SOQL-over-REST で Id を解決し、複合 Metadata を使って PATCH し、結果を報告します。
  • 対象範囲外:SOP からの設定 JSON の生成(automation-sandbox-post-copy-config-generate に委任);metadata-XML のデプロイ;ATF Java オーケストレーター;describe プローブに失敗したエントリの API パスの推測(API_NOT_IDENTIFIED → 停止)。

稼働中の組織を変更するツール:まず --dry-run を優先してください。失敗したエントリを別のエンドポイントに対して黙って再試行してはいけません。


必須入力

適用する前に、以下を収集するか推定してください。

  • 設定ファイルのパス:automation-sandbox-post-copy-config-generate の JSON(既定値は ./post-copy-config.json)。見つからない場合 → 停止して確認してください。
  • 対象組織のエイリアス/ユーザー名:既定値を決して仮定しないでください。指定されていない場合は、 sf org list --json で一覧を取得して確認してください。
  • ドライランフラグ(既定値は false):読み取りは許可、書き込みは禁止 — 「ネットワーク呼び出しなし」ではありません。Step B の describe GET、Step C の SOQL、Step D-1 の GET は引き続き実行します。予定される PATCH 本文が正確になるのは、実際の Metadata ブロックに対してのみです。Step D-3(PATCH)と Step E(検証)はスキップします(Flows:Step G を参照 — G-3 の GET と PATCH はどちらもスキップし、G-1 と G-2 は引き続き実行します)。読み取りに失敗した場合(401、404、NamedOrgNotFoundError)は、その内容を提示して停止してください。メモリ上の計画へのフォールバックは禁止です。初回はドライランを推奨します。
  • エラー時に続行(既定値は true):true = 失敗したエントリがあってもフェーズを中断しません。false = フェーズの途中で中断します。

明確な設定ファイルのパスと対象エイリアスが指定されている場合は、追加の確認をせずに進めてください。


ワークフロー

すべての手順では、Bash 経由で実際の sf CLI コマンドを実行します。コマンドを実行せずに計画を説明するだけではいけません — このスキルは対象組織を変更します。

  1. 設定 JSON の読み込みと検証 — Read ツールで読み込みます。 すべてのエントリに5つのトップレベルキーが必要です。不正な形式の場合 → 即時停止します。

  2. 対象組織と API バージョンの解決 — sf org display --json を実行します。 エイリアスが解決されることを確認し、result.apiVersion を取得します。 生の JSON は出力しないでください — アクセストークンが含まれています。

  3. フェーズの計画 — node scripts/plan-phases.mjs <config.json> を実行し、 出力された phases[] を順に処理します。同時実行数の上限については references/execution_phasing.md を参照してください。

  4. エントリごとの describe 検証 — 異なる ConfigurationName のうち ScheduledApex 以外について、Step A と Step B をそれぞれ1回実行し、検証済みの sobject をキャッシュします。Step B が失敗した場合、その名前を持つすべてのエントリは API_NOT_IDENTIFIED になります。ScheduledApex は describe 検証をスキップします(Step F は複合 Metadata ではなく、匿名 Apex を使用します)。Flows は describe 検証を実行します(PATCH の転送には FlowDefinition 上の複合 Metadata を使用します)。スキップするのは Step D の変更キー導出のみです(Step G-3 では固定キーを使用します)。

  5. エントリごとの適用処理 — 各フェーズ内の各エントリについて、以下を実行します。

    • plan-phases の結果が SKIP_INACTIVE の場合 → SKIPPED_INACTIVE として記録し、Follow-ups の箇条書きを追加して続行します。
    • ScheduledApex → Step F(F-1→F-4)。ドライランの場合は F-1 と F-2 のみを実行し、DRY_RUN として記録します。
    • Flows → Step G(G-1→G-4)。事前確認で ALREADY_ACTIVE/ALREADY_INACTIVE の場合は PATCH を省略します。ドライランの場合は G-1 と G-2 のみを実行し、DRY_RUN として記録します。
    • その他すべて → Step C(Id)、Step D(GET+変更+PATCH)、Step E(検証)。ドライランの場合は C と D-1/D-2 のみを実行し、DRY_RUN として記録します。
  6. フェーズ間の処理 — 次のフェーズを開始する前に、現在のフェーズのすべてのエントリが完了するまで待機します。

  7. サマリーファイルの書き込み — 「Canonical output shape」セクションに従い、 ./post-copy-<mode>-summary.md に Markdown 形式で保存し、ユーザーにも表示します。アクセストークンや sf org display の生出力は決して書き込まないでください。サマリー内の URL に埋め込まれた認証情報はマスクします(https://user:***@host/...)。実際の PATCH 本文には URL がそのまま含まれます。


ルールと注意点

重要な不変条件(never insert;すべての ConfigurationName で describe を必ず実行する;複合 Metadata PATCH で既存ブロック全体を保持する;IsActive: false → SKIPPED_INACTIVE;生のアクセストークンを決して出力しない;フェーズ内の同時実行数を5に制限する)と、各実行時エラーに対する標準応答(実行途中の401、429、認証情報を含む URL、Fields.Action = "Delete"、describe 404、SOQL の行数が0件または複数件の場合)は references/rules_gotchas.md に記載されています。Step A~E の手順から逸脱する前に、そのファイルを読んでください。

スキル間の連携

必要な作業委任先
顧客の SOP を、このスキルが使用する JSON 設定に変換するautomation-sandbox-post-copy-config-generate
複合 Metadata Tooling パターンを使わずにメタデータ XML をデプロイする対応する generating-* スキル + メタデータのデプロイフロー
ターゲット組織にまだ存在しないレコードを新規作成するplatform-metadata-deploy
API 呼び出しに必要な権限セットを割り当てるdx-org-permission-set-assign

参考ファイル一覧

ファイル参照するタイミング
references/api_endpoints.mdステップ A〜E — 汎用手順の全体 + OBM/RSS の実例
references/scheduled_apex_path.mdステップ F — ScheduledApex 用の匿名 Apex 経由の手順
references/flow_activation_path.mdステップ G — フローの有効化/無効化(Flows)
references/execution_phasing.mdステップ 3 — plan-phases.mjs の基盤となるフェーズグループ化モデル
references/authentication.mdステップ 2 — セッション確認 + 実行途中の 401 エラーへの対応
references/rules_gotchas.mdステップ A〜E から逸脱する前 — 不変条件 + 失敗時の応答
scripts/plan-phases.mjsステップ 3 — フェーズプランナー
scripts/map-metadata-key.mjsステップ D-2 — メタデータキーの解決ツール
scripts/classify-patch-result.mjsステップ D-4 — HTTP 結果の分類ツール
scripts/resolve-target-org.mjs出力形式 — ターゲット組織エイリアスの解決ツール
scripts/build-scheduled-apex.mjsステップ F-2 — 匿名 Apex スニペットのビルダー
scripts/soql-escape-job-name.mjsステップ F-1/F-4 — JobName の SOQL エスケープ
assets/api_request_templates.jsonステップ A〜E — describe/lookup/GET+PATCH テンプレート
assets/scheduled_apex_template.apexステップ F-2 — 匿名 Apex テンプレート
examples/sample_config_input.jsonステップ 1 — 設定 JSON の形式
examples/sample_scheduled_apex_config.jsonステップ 1 — ScheduledApex エントリーの形式
examples/sample_execution_summary.mdステップ 7 — サマリーレポートの形式

コメント