/platform-destructive-deploy
Execute the destructiveChanges.xml delete-and-deploy workflow against a Salesforce org. TRIGGER when the user asks to delete/remove a custom object, field, Apex class, flow, or any metadata component FROM an org, or to perform a 'destructive deploy' / removal as part of a
$ npx -y skills add forcedotcom/sf-skills --skill platform-destructive-deploy --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/platform-destructive-deploy
Context preview
The summary Claude sees to decide when to auto-load this skill.
Execute the destructiveChanges.xml delete-and-deploy workflow against a Salesforce org. TRIGGER when the user asks to delete/remove a custom object, field, Apex class, flow, or any metadata component FROM an org, or to perform a 'destructive deploy' / removal as part of a
SKILL.md
platform-destructive-deploy.SKILL.mdname: platform-destructive-deploy
description: "Execute the destructiveChanges.xml delete-and-deploy workflow against a Salesforce org. TRIGGER when the user asks to delete/remove a custom object, field, Apex class, flow, or any metadata component FROM an org, or to perform a 'destructive deploy' / removal as part of a release. Validates first and gates production with explicit confirmation. DO NOT TRIGGER for local file deletion (use Bash), or for net-new deploys (use platform-metadata-deploy)."
allowed-tools:
- Bash
- Read
- Write
- Glob
- Grep
Handling Destructive Changes
Coordinate metadata deletion against a Salesforce org via the destructiveChanges manifest. Runs in three phases: scope → validate → execute, with stricter guardrails for production.
Phase 1 — Scope the deletion
Step 1a — Gather the components to remove
Ask the user (or infer from context) which components to delete. For each, capture:
- Metadata type (e.g. `CustomObject`, `CustomField`, `ApexClass`, `Flow`, `PermissionSet`)
- API name (e.g. `Project__c`, `Account.Status__c`, `MyController`)
Step 1b — Local dependency scan (best-effort)
Before generating the manifest, scan the local project for references to each component. Use Grep over `force-app/`:
grep -rn "<componentApiName>" force-app/ --include='*.cls' --include='*.trigger' --include='*.xml' --include='*.js' --include='*.html'
If references are found:
- List them to the user
- Recommend either updating those references first OR removing them in the same destructive deploy
- Do NOT proceed silently — surface the dependency risk
Step 1c — Generate `destructiveChanges.xml`
Write to `manifest/destructiveChangesPre.xml` (for pre-deploy deletion) or `manifest/destructiveChangesPost.xml` (for post-deploy deletion). Use the standard Salesforce metadata format:
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
<members>Project__c</members>
<members>OldThing__c</members>
<name>CustomObject</name>
</types>
<types>
<members>Account.Status__c</members>
<name>CustomField</name>
</types>
<version>62.0</version>
</Package>Use the API version from `sfdx-project.json`'s `sourceApiVersion`.
Group components by metadata type (one `<types>` block per type). For namespaced fields, use `Object.Field` notation.
Phase 2 — Validate
ALWAYS validate before executing a destructive deploy:
sf project deploy validate \
--pre-destructive-changes manifest/destructiveChangesPre.xml \
--manifest manifest/package.xml \
--target-org <alias> \
--test-level RunLocalTests \
--json
(For post-destructive: use `--post-destructive-changes`.)
If `package.xml` doesn't exist, create an empty one alongside (deletion-only deploy needs a package descriptor):
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<version>62.0</version>
</Package>If validation fails, surface errors and STOP. Common failure modes:
- "Cannot delete: referenced by Apex/Flow/Layout" → component still has references
- "Cannot delete: required for license" → managed-package or license dependency
- "Insufficient access" → user lacks delete permission
Phase 3 — Execute
Production path
Confirm whether the target is production before executing. The reliable check is the gate's classifier (returns `production|sandbox|scratch|trial|devhub|unknown`):
sf org display --target-org <alias> --json | "${CLAUDE_PLUGIN_ROOT}/scripts/sf-deploy-gate" classifyIf the classifier returns `production`: 1. Display destructive confirmation banner (mirroring `platform-quick-deploy`) 2. List EVERY component that will be deleted 3. Require explicit "yes, delete from PRODUCTION" confirmation 4. Reject `--purge-on-delete` unless the user types it explicitly
The PreToolUse hook (`sf-deploy-gate destructive`) will already block bare destructive commands against prod — surface that denial to the user, do not work around it.
Sandbox / Scratch path
sf project deploy start \
--pre-destructive-changes manifest/destructiveChangesPre.xml \
--manifest manifest/package.xml \
--target-org <alias> \
--json \
--wait 30
Add `--purge-on-delete` only if the user explicitly asked to permanently delete (skip the recycle bin).
Phase 4 — Post-delete cleanup
After a successful destructive deploy:
- Recommend a `sf project retrieve start --metadata <Type>:<Name>` is NOT useful (component is gone) — instead suggest cleaning up the local source:
# Remove the now-deleted local files to keep source tracking accurate
rm -rf force-app/main/default/<path-to-component>
- If deleting a custom field with data, remind the user that data is gone (or in the recycle bin until purged)
- Recommend running tests to confirm no runtime regressions
Rules
- ALWAYS validate first; NEVER skip Phase 2
- ALWAYS scan for local references; NEVER delete blindly
- ALWAYS gate production with explicit user confirmation
- NEVER add `--purge-on-delete` without explicit user request
- NEVER use `--ignore-errors` on a destructive deploy
- ALWAYS use the API version from `sfdx-project.json`, not a hardcoded value
- If the user is deleting a field with `required="true"` or that's used in `RecordType` picklist values, surface the cascade impact before proceeding
Read more
name: platform-destructive-deploy description: "Execute the destructiveChanges.xml delete-and-deploy workflow against a Salesforce org. TRIGGER when the user asks to delete/remove a custom object, field, Apex class, flow, or any metadata component FROM an org, or to perform a 'destructive deploy' / removal as part of a release. Validates first and gates production with explicit confirmation. DO NOT TRIGGER for local file deletion (use Bash), or for net-new deploys (use platform-metadata-deploy)." allowed-tools: - Bash - Read - Write - Glob - Grep
Handling Destructive Changes
Coordinate metadata deletion against a Salesforce org via the destructiveChanges manifest. Runs in three phases: scope → validate → execute, with stricter guardrails for production.
Phase 1 — Scope the deletion
Step 1a — Gather the components to remove
Ask the user (or infer from context) which components to delete. For each, capture:
- Metadata type (e.g. `CustomObject`, `CustomField`, `ApexClass`, `Flow`, `PermissionSet`)
- API name (e.g. `Project__c`, `Account.Status__c`, `MyController`)
Step 1b — Local dependency scan (best-effort)
Before generating the manifest, scan the local project for references to each component. Use Grep over `force-app/`:
grep -rn "<componentApiName>" force-app/ --include='*.cls' --include='*.trigger' --include='*.xml' --include='*.js' --include='*.html'
If references are found:
- List them to the user
- Recommend either updating those references first OR removing them in the same destructive deploy
- Do NOT proceed silently — surface the dependency risk
Step 1c — Generate `destructiveChanges.xml`
Write to `manifest/destructiveChangesPre.xml` (for pre-deploy deletion) or `manifest/destructiveChangesPost.xml` (for post-deploy deletion). Use the standard Salesforce metadata format:
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
<members>Project__c</members>
<members>OldThing__c</members>
<name>CustomObject</name>
</types>
<types>
<members>Account.Status__c</members>
<name>CustomField</name>
</types>
<version>62.0</version>
</Package>Use the API version from `sfdx-project.json`'s `sourceApiVersion`.
Group components by metadata type (one `<types>` block per type). For namespaced fields, use `Object.Field` notation.
Phase 2 — Validate
ALWAYS validate before executing a destructive deploy:
sf project deploy validate \ --pre-destructive-changes manifest/destructiveChangesPre.xml \ --manifest manifest/package.xml \ --target-org <alias> \ --test-level RunLocalTests \ --json
(For post-destructive: use `--post-destructive-changes`.)
If `package.xml` doesn't exist, create an empty one alongside (deletion-only deploy needs a package descriptor):
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<version>62.0</version>
</Package>If validation fails, surface errors and STOP. Common failure modes:
- "Cannot delete: referenced by Apex/Flow/Layout" → component still has references
- "Cannot delete: required for license" → managed-package or license dependency
- "Insufficient access" → user lacks delete permission
Phase 3 — Execute
Production path
Confirm whether the target is production before executing. The reliable check is the gate's classifier (returns `production|sandbox|scratch|trial|devhub|unknown`):
sf org display --target-org <alias> --json | "${CLAUDE_PLUGIN_ROOT}/scripts/sf-deploy-gate" classifyIf the classifier returns `production`: 1. Display destructive confirmation banner (mirroring `platform-quick-deploy`) 2. List EVERY component that will be deleted 3. Require explicit "yes, delete from PRODUCTION" confirmation 4. Reject `--purge-on-delete` unless the user types it explicitly
The PreToolUse hook (`sf-deploy-gate destructive`) will already block bare destructive commands against prod — surface that denial to the user, do not work around it.
Sandbox / Scratch path
sf project deploy start \ --pre-destructive-changes manifest/destructiveChangesPre.xml \ --manifest manifest/package.xml \ --target-org <alias> \ --json \ --wait 30
Add `--purge-on-delete` only if the user explicitly asked to permanently delete (skip the recycle bin).
Phase 4 — Post-delete cleanup
After a successful destructive deploy:
- Recommend a `sf project retrieve start --metadata <Type>:<Name>` is NOT useful (component is gone) — instead suggest cleaning up the local source:
# Remove the now-deleted local files to keep source tracking accurate rm -rf force-app/main/default/<path-to-component>
- If deleting a custom field with data, remind the user that data is gone (or in the recycle bin until purged)
- Recommend running tests to confirm no runtime regressions
Rules
- ALWAYS validate first; NEVER skip Phase 2
- ALWAYS scan for local references; NEVER delete blindly
- ALWAYS gate production with explicit user confirmation
- NEVER add `--purge-on-delete` without explicit user request
- NEVER use `--ignore-errors` on a destructive deploy
- ALWAYS use the API version from `sfdx-project.json`, not a hardcoded value
- If the user is deleting a field with `required="true"` or that's used in `RecordType` picklist values, surface the cascade impact before proceeding
This repository provides a curated collection of Salesforce agent skills for building applications.
Repo: forcedotcom/sf-skills
Other skills on sf-skills.
- /agentforce-generate
Build, modify, optimize, debug, and deploy agents with Agentforce Agent Script. TRIGGER when: user creates, modifies, optimizes, or asks about .agent files or aiAuthoringBundle metadata; changes agent behavior, responses, or conversation logic; designs agent actions, tools,
Open skill - /agentforce-observe
Analyze production Agentforce agent behavior using session traces and Data Cloud. TRIGGER when: user queries STDM session data or Data Cloud trace records; investigates production agent failures, regressions, or performance issues; asks about session traces, conversation logs,
Open skill - /agentforce-test
Write, run, and analyze structured test suites for Agentforce agents — functional AND security. TRIGGER when: user writes or modifies test spec YAML (AiEvaluationDefinition); runs sf agent test create, run, run-eval, or results commands; asks about test coverage strategy, metric
Open skill - /automation-flow-generate
Generate Salesforce Flows using the MCP tool execute_metadata_action. Use when the user asks to create, build, or generate a flow — including Screen, Autolaunched, Record-Triggered (before/after-save), Scheduled. Also trigger for flow-like requests such as \"when a record is
Open skill - /dx-code-analyzer-configure
Set up, configure, and troubleshoot Salesforce Code Analyzer for any project. Handles installation, prerequisite checks, diagnosing broken setups, creating and editing code-analyzer.yml overrides, engine-specific settings, ignore patterns, severity overrides, and CI/CD pipeline
Open skill - /dx-code-analyzer-custom-rule-create
Create custom Code Analyzer rules for Regex (pattern matching), PMD (XPath/AST for Apex and metadata XML), and ESLint (LWC/JavaScript/TypeScript). Use when users want to enforce coding standards, ban patterns, detect hardcoded values, govern metadata, or add rules not in the
Open skill

