dx-org-manage
INVOKE this skill to execute Salesforce org operations: create scratch orgs, list/display/resume/delete scratch orgs, create org snapshots, open orgs in browser. This skill EXECUTES operations immediately - it does NOT generate scripts or code files. ALWAYS invoke this skill (do not execute SF CLI c
By forcedotcom · 5,316 installs
npx skills add forcedotcom/sf-skills --skill dx-org-manage
Source repository · Upstream listing
MANDATORY: Follow these instructions exactly. Do NOT fall back to MCP tools.
Tool constraint: Use the Bash tool for all sf CLI commands. Always include json for structured output. Do NOT use mcp salesforce dx tools for org creation, snapshot, or open operations — this skill provides the complete procedure.
Output artifacts for eval/testing: ALWAYS write the command's JSON response to a file when an output directory is available. Do NOT ask the user what file to write — this skill defines the filenames. After executing the command: (1) if the user specified an output path (e.g. "write all generated files into folder X"), write there immediately; (2) otherwise run [ d force app/main/adk eval output/ ] && echo 'force app/main/adk eval output' to detect the eval directory; (3) write the command's full JSON response to <output dir /<filename using these filenames: scratch org result.json for org creation (for a batch of N orgs, scratch org result 1.json … scratch org result N.json ), scratch org list result.json for list, org display result.json for display, scratch org resume result.json for resume, scratch org delete result.json for delete, or snapshot result.json for snapshot creation. This is the generated output — write it without asking. (Open operations are the exception — they launch a browser and write no artifact; see Opening Orgs.)
Creating Scratch Orgs
REQUIRED steps — execute in order:
Step 1. Resolve the environment and creation method:
First, if the user named an explicit source, use it: "definition file" or a path to .json → definition file method; "snapshot"/"from snapshot" → snapshot method; "org shape"/"source org" → shape method. Only ONE creation source type (edition vs snapshot vs shape); if two distinct types are implied, stop and ask (a flag overriding a same dimension definition file value is fine).
Otherwise resolve by environment:
AUTO MODE (zero prompt): if sfdx project.json is present AND exactly one config/ scratch def.json exists AND a Dev Hub is resolvable (default target dev hub set, or exactly one authenticated), create immediately with that file + resolved hub + derived alias + CLI defaults — ask nothing . This also honors a batch count (see below).
STATE A (in a project), not auto: enumerate config/ scratch def.json — 0 files → default edition developer (or author one if features/settings are wanted, see below); 1 file → use it; many → ask which one (never silently pick).
STATE B (no sfdx project.json ): do NOT block and do NOT silently create a throwaway — present the guided 3 way choice (point to a project / scaffold one via sf template generate project name <name / create a throwaway here, then guide the source). See references/scratch org create.md .
Batch — "create N scratch orgs": there is no native count flag — loop the create command N times with N distinct aliases ( <base 1 … <base N , each collision guarded so it never re points an existing org). Report each org and write one artifact per org. On a mid loop Dev Hub limit error, surface the CLI's error unchanged and report which orgs already succeeded.
Definition file authoring: if features/settings are requested and no suitable file exists, author a new purpose named definition file (seed then modify; documented fields only; no clobber), show it, and create from it. In a non interactive/eval context, author the file AND proceed to create without waiting for edit confirmation. Details in references/scratch org create.md and references/definition file options.md .
Step 2. Resolve the Dev Hub to a concrete value — then pass it explicitly. Resolve it once to an actual username or alias and pass that exact value via target dev hub on every command in Step 3. Resolution order:
1. A Dev Hub the user named explicitly → use it verbatim.
2. Else the default: the non empty result[0].value from sf config get target dev hub json .
3. Else the single authenticated Dev Hub. Run this exact command — do NOT hand write your own filter. A Dev Hub can appear in any of the sf org list buckets ( devHubs , nonScratchOrgs , other , sandboxes , scratchOrgs ); a filter that checks only one bucket (e.g. only .other[] ) misses it and makes you think no hub exists:
Exactly one username printed → use it.
Zero printed → no hub is authenticated. Do NOT run sf org create at all — there is nothing to pass to target dev hub , and any create attempt will fail. Instead, STOP here: advise sf org login web set default dev hub , and if an output directory is available write that advisory as the artifact. Do not proceed to Step 3.
Two or more → ask the user which one (do not pick arbitrarily).
Never invent or guess a Dev Hub name. Fabricating a placeholder alias (e.g. eval target , my dev hub , DevHub ) is the top eval failure — the CLI correctly rejects it with NotADevHubError . If the command above prints nothing, that means no Dev Hub exists in this environment — it does NOT mean you should substitute a name. There is no valid fallback name to invent: an unresolved hub is a hard stop, not a value to guess. Do NOT run sf org create scratch with a made up target dev hub , and do NOT run it with no target dev hub flag either (that yields NoDefaultDevHubError ). Stop and advise sf org login web set default dev hub .
The default target dev hub may be directory scoped in some CLI setups ( sf config get can return empty after a cd ), which is why step 3's all bucket sf org list check is the reliable fallback — it is not directory scoped.
Do NOT proceed until a concrete Dev Hub value is resolved.
Step 3. Build and execute the command based on method:
Definition file:
Edition only:
From snapshot:
From org shape:
source org takes the 15 character source org ID — the ID of the org the shape was captured from (a 00D… org ID), NOT the 3SR… shape record ID shown by sf org list shape . Pass the ID the user gives you through unchanged. If the CLI rejects it (e.g. InvalidIdLengthError , InvalidPrefixError ), surface that error verbatim and stop — do NOT truncate, reformat, guess, or retry with a different ID.
Apply these flags when requested:
duration days <days — default 7, max 30
set default — make this the default org
no track source — disable source tracking (for CI/CD)
Step 4. MANDATORY Run org list and write output (SUCCESS path only): This step runs only when Step 3 created an org successfully. If Step 3 returned an error, SKIP this step and follow Error handling below instead. After the org is created, you MUST run this command:
Then:
1. Parse the JSON result and find the scratchOrgs array
2. Find the entry where username matches the username from Step 3's creation result
3. Extract that complete org object (it will include: alias, username, orgId, instanceUrl, loginUrl, isDefaultUsername, orgEdition, status, expirationDate, devHubUsername, and other fields the CLI returns).
4. Report to the user:
Created scratch org.
Alias: [alias from the org list entry]
Username: [username]
Org ID: [orgId]
5. If an output directory is available (per the output artifacts rule above), write that extracted org object to <output dir /scratch org result.json as is — this skill is a pass through wrapper . Write every field the CLI returns for that org; do NOT curate, whitelist, or drop non secret fields (e.g. instanceName , createdOrgInstance , signupUsername , orgName , edition are non secret metadata the CLI returns freely — keep them). The one thing you never emit is a live secret: accessToken and sfdxAuthUrl — and the CLI already redacts these in json output (they arrive as "[REDACTED] …" ), so simply preserve that redaction and never un redact or re derive the real value.
Example: If sf org list json returns {"result": {"scratchOrgs": [{"alias": "feature dev", "username": "test@example.com", "orgId": "00D...", ...}]}} , write the inner org object {"alias": "feature dev", "username": "test@example.com", "orgId": "00D...", ...} — the full object for that org — to the file.
Write the extracted org list entry (the resolved org record), NOT the raw creation command response. Do NOT suggest verification steps to the user.
Error handling (Step 3 create failed — no org was created): Surface the CLI's error output to the user verbatim (no rewriting, no retry, no editing the definition file). Do NOT run Step 4 (there is no org to list/extract). If an output directory is available, write the create command's raw error JSON as is to <output dir /scratch org result.json — this is the command's response and is the output artifact for the failed run. (For a batch, write the error to the artifact for the org that failed, and still write the success entries for any orgs that already succeeded before the failure.) Then, where the CLI's error matches one of these, add the corresponding pointer:
"Snapshot not found" → suggest sf org list snapshot target dev hub <alias
"No default Dev Hub" → advise sf org login web set default dev hub
When you need more detail:
For the complete creation workflow (AUTO MODE, STATE A/B, batch, definition file authoring) → load references/scratch org create.md ; for list/display/resume/delete → load references/scratch org operations.md
For available features, settings, and definition file structure → load references/definition file options.md
For edition selection guidance and comparison → load references/edition types.md
For snapshot workflow and post creation usage → load references/snapshot usage.md
Listing Scratch Orgs
Step 1. Execute:
Step 2. Report + write output: default view = active scratch orgs from result.scratchOrgs[] ; report alias / username / orgId / expiration per org. Document all (include expired/deleted) and clean as options, not the default. Write the result.scratchOrgs[] array to <output dir /scratch org list result.json (per the output artifacts rule).
Detail: references/scratch org operations.md .
Displaying an Org
Step 1. Execute:
Step 2. Report + write output: report alias / username / orgId / instanceUrl / status / expiration. Write the wrapped {status, result} JSON to <output dir /org display result.json — do NOT unwrap. In any committed example/gold, accessToken and sfdxAuthUrl must be redacted (value begins with [REDACTED] ).
verbose : never add it and never run it from this skill — it returns sfdxAuthUrl (a refresh token) into agent context. If the user needs the auth URL, tell them to run sf org display verbose themselves in their own terminal.
Detail: references/scratch org operations.md .
Resuming Scratch Org Creation
For a create that ran with async or timed out (exit code 69).
Step 1. Execute:
If the user gave an explicit job id , use it; otherwise default to use most recent . If there is no recent job, surface the CLI's not found result unchanged and point the user to sf org list — do not invent a job id.
Step 2. Write output: write the command's JSON as is to <output dir /scratch org resume result.json .
Detail: references/scratch org operations.md .
Deleting a Scratch Org
Destructive — no undo.
Step 1. Confirm before running. Ask "Delete scratch org X ?" and wait for confirmation, UNLESS the user already gave explicit deletion intent. If the target is the current default org, call that out in the confirmation (extra guard).
Step 2. Execute (only after confirmation):
no prompt is passed after the skill's own confirmation, so the agent isn't left waiting on the CLI's interactive prompt.
Step 3. Write output: write the command's JSON as is to <output dir /scratch org delete result.json .
Detail: references/scratch org operations.md .