forcedotcom/sf-skills2 files

Platform Manifest Generate

Use to generate a package.xml (and optionally destructiveChanges.xml / Pre / Post) from a source dir, a component list, or org introspection. Trigger on 'generate a package.xml from this folder', 'create a manifest for these classes', 'I need a deploy manifest', or 'destructiveChanges.xml for deletions'. Encodes wildcard-vs-explicit-member rules per metadata type. DO NOT TRIGGER to deploy (platform-metadata-deploy), delete (platform-destructive-deploy), or retrieve (platform-metadata-retrieve).

Specification
Skill ID
forcedotcom/sf-skills/platform-manifest-generate
Publisher
forcedotcom
Repository
sf-skills
Installs
0
Files
2
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

forcedotcom/sf-skills/platform-manifest-generateInstalls these files
  • SKILL.md
  • references/wildcard-allowlist.md

What this skill tells the agent

platform-manifest-generate

Produce a Salesforce metadata manifest — package.xml (or one of the destructive variants) — from local source, an org, or an explicit component list. This skill is purely about authoring the manifest file. Hand off to platform-metadata-deploy or platform-destructive-deploy once the file exists.


Tool Restrictions

Use ONLY the Bash tool to run sf project generate manifest, and the Write tool for the hand-built fallback path. Do NOT use MCP tools.


When This Skill Owns the Task

Use platform-manifest-generate when the work involves any of:

  • Building a package.xml from a source directory (e.g. force-app/main/default/classes/)
  • Building a manifest from an explicit list of components (e.g. AccountService, ContactSelector, Account)
  • Building a manifest by introspecting an org via --from-org
  • Producing destructiveChanges.xml, destructiveChangesPre.xml, or destructiveChangesPost.xml for a deletion
  • Producing both a package.xml and a destructive manifest in one operation

Delegate elsewhere when the user is:

  • Running the deploy itself → platform-metadata-deploy
  • Validating before a prod release → platform-deploy-validate
  • Executing the destructive deploy → platform-destructive-deploy (that skill uses the manifest this skill generates)
  • Retrieving metadata to local → platform-metadata-retrieve

Two Generation Paths

Path A — CLI-driven (recommended)

Wrap sf project generate manifest. Always prefer this path; it knows about every metadata type and produces canonical XML — and never emits *, sidestepping the wildcard hazard entirely.

The CLI offers three input modes (mutually exclusive):

InputFlagUse when
Source directory--source-dir (-p)User points to a folder containing already-on-disk metadata
Component list--metadata (-m)User names specific components, e.g. ApexClass:AccountService CustomObject:Account
Org introspection--from-orgUser wants every component currently in an org (or a filtered subset)

You can specify either --source-dir or --metadata, not both. --from-org may be combined with --metadata (filter included types) or --excluded-metadata (filter out types).

Verified flags (do not invent flags — verify with sf project generate manifest --help if unsure):

FlagPurpose
--source-dir, -pLocal source paths to scan
--metadata, -mComponent names to include (e.g. ApexClass:AccountService)
--from-orgUsername or alias of org to introspect
--name, -nCustom output filename (mutually exclusive with --type)
--type, -tPredefined manifest kind: package \pre \post \destroy
--output-dir, -dDirectory to write the manifest into
--api-versionOverride the API version for the request
--include-packages, -cInclude managed and/or unlocked package metadata when using --from-org
--excluded-metadataTypes to exclude when using --from-org
--jsonMachine-readable output

Manifest filename by `--type`:

--typeOutput file
package (default)package.xml
predestructiveChangesPre.xml
postdestructiveChangesPost.xml
destroydestructiveChanges.xml

You can specify either --type or --name, not both.

Canonical CLI examples
# Build package.xml from a source dir
sf project generate manifest \
  --source-dir force-app/main/default \
  --name package.xml \
  --output-dir manifest \
  --json

# Build package.xml from an explicit component list
sf project generate manifest \
  --metadata ApexClass:AccountService \
  --metadata ApexClass:ContactSelector \
  --metadata CustomObject:Account \
  --name package.xml \
  --output-dir manifest \
  --json

# Build destructiveChanges.xml from a component list
sf project generate manifest \
  --metadata CustomField:Account.OldField__c \
  --metadata CustomField:Account.OldStatus__c \
  --type destroy \
  --output-dir manifest \
  --json

# Build a manifest by introspecting an org (filtered)
sf project generate manifest \
  --from-org <alias> \
  --metadata ApexClass,CustomObject,CustomLabels \
  --output-dir manifest \
  --json

If both a package.xml and a destructive manifest are needed, run the CLI twice — once with --type package (or default), once with --type destroy / pre / post.

Path B — Hand-built fallback

Use this only when the CLI cannot express the user's intent — e.g. they want "just the Apex classes I changed today" and the change set is derived from git diff rather than a clean directory or component list. In that case:

  1. Resolve the components yourself (e.g. parse git diff --name-only and map paths back to metadata types).
  2. Group by metadata type.
  3. Emit the XML inline using the schema below.
  4. Always cross-check by running sf project deploy start --manifest <file> --dry-run (hand off to platform-metadata-deploy).
Manifest XML schema

Root element is <Package> in the metadata namespace. Each metadata type gets one <types> block containing one <members> per component plus a single <name>. The trailing <version> declares the API version for the manifest.

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>AccountService</members>
        <members>ContactSelector</members>
        <name>ApexClass</name>
    </types>
    <types>
        <members>Account</members>
        <name>CustomObject</name>
    </types>
    <types>
        <members>Account.Status__c</members>
        <name>CustomField</name>
    </types>
    <version>62.0</version>
</Package>

Notes:

  • For component-bound types like CustomField, BusinessProcess, RecordType, Layout, ListView, ValidationRule, WebLink, members use Object.Name notation.
  • destructiveChanges.xml, destructiveChangesPre.xml, and destructiveChangesPost.xml use the same XML structure — only the filename and intent differ.
  • An empty manifest (no <types> blocks) is legal and is sometimes paired with a destructive manifest:
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <version>62.0</version>
</Package>

API Version Handling

The <version> element at the bottom of every manifest must reflect the project's API version.

Resolution order:

  1. Read sourceApiVersion from sfdx-project.json at the project root.
  2. If --api-version was passed by the user, use that instead.
  3. If neither is available, fall back to the value reported by sf --version (the CLI's bundled API version) — but warn the user and recommend they set sourceApiVersion in sfdx-project.json for reproducibility.
  4. Never silently hardcode a value (e.g. 62.0) into output without surfacing the source.
# Quick read of sourceApiVersion
jq -r '.sourceApiVersion' sfdx-project.json

When using the CLI path, omit --api-version unless the user explicitly overrides — the CLI already reads sourceApiVersion.


Wildcard Members (<members>*</members>)

A wildcard member matches every component of that metadata type. It is not legal for every type. Using * for a disallowed type causes deploy/retrieve errors like Wildcards are not supported for this metadata type.

Wildcard NOT allowed (must enumerate)

These types require explicit member names. Common examples: Profile, PermissionSet, PermissionSetGroup, CustomLabels, CustomObjectTranslation, Layout, Workflow (in some package configurations), SharingRules, StandardValueSet, ManagedTopics, and most "container" types whose contents are object-bound (CustomField, RecordType, BusinessProcess, ListView, ValidationRule, WebLink, CompactLayout).

More from forcedotcom

Use this skill in a project

Open any RiverX project, search the Skills panel for forcedotcom/sf-skills/platform-manifest-generate, and install it in one click.

Use this skill