Skip to content

Commit 652aaeb

Browse files
committed
Merge: ADR 0002 naming convention, docs refresh, single-branch model (#14)
Renames every action and workflow to the ADR 0002 convention, relocates the Docker workflow to sf-docker-images, deletes AI-session residue from docs/, and adds the L3 Salesforce dispatch chain plus the 2GP package release pipeline. Retires develop: the twenty absolute self-references now pin the floating @v2 tag rather than a branch, since a deleted branch makes every one unresolvable. Also fixes ci-sf-ops-dispatch-smoke.yml, which had been in startup_failure on every run since it was added — it granted permissions: {} while the dispatcher's create-version job requests contents: write. Validated locally (GitHub Actions was in a critical outage at merge time): npm run all and actionlint 1.7.12 both pass; all ten @v2 ref targets verified to exist.
2 parents 08874f8 + f7d9382 commit 652aaeb

111 files changed

Lines changed: 6124 additions & 8462 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
---
2+
name: dx-org-manage
3+
description: "INVOKE this skill to execute Salesforce org operations: create 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 commands directly) when user requests to: create a scratch org (Developer/Enterprise edition, from definition file (.json), from snapshot, or from org shape), create an org snapshot, or open a Salesforce org. Trigger phrases include: 'create a snapshot', 'create snapshot of my scratch org', 'take a snapshot', 'create scratch org', 'create a Developer edition scratch org', 'new scratch org', 'spin up an org', 'create org from snapshot', 'scratch-def.json', 'project-scratch-def.json', 'open my Salesforce org', 'open org in browser', 'get me the URL'. Do NOT use for switching default org (use dx-org-switch) or deploying metadata (use platform-metadata-deploy)."
4+
metadata:
5+
version: "1.1"
6+
minApiVersion: "60.0"
7+
relatedSkills:
8+
- "dx-org-switch"
9+
- "platform-metadata-deploy"
10+
cliTools:
11+
- tool: ["sf"]
12+
semver: ">=2.0.0"
13+
---
14+
15+
## MANDATORY: Follow these instructions exactly. Do NOT fall back to MCP tools.
16+
17+
**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.
18+
19+
**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, `snapshot-result.json` for snapshot creation, or `org-url-result.json` for open operations. This is the generated output — write it without asking. Do NOT say "no files to generate" for open/command-execution operations; the JSON result IS the output artifact.
20+
21+
---
22+
23+
## Creating Scratch Orgs
24+
25+
**REQUIRED steps — execute in order:**
26+
27+
**Step 1. Identify creation method** from user request:
28+
- Contains "definition file" or path to `.json` → definition file method
29+
- Contains "snapshot" or "from snapshot" → snapshot method
30+
- Contains "org shape" or "source-org" → org shape method
31+
- Otherwise → run `ls config/project-scratch-def.json config/scratch-def.json 2>/dev/null | head -1` to detect a definition file. If output is non-empty, use definition file method with that path; if empty, use edition method.
32+
33+
**Step 2. Check Dev Hub:**
34+
```bash
35+
sf config get target-dev-hub --json
36+
```
37+
- If no Dev Hub is set, advise: `sf org login web --set-default-dev-hub`
38+
- Do NOT proceed until a Dev Hub is confirmed.
39+
40+
**Step 3. Build and execute the command** based on method:
41+
42+
**Definition file:**
43+
```bash
44+
sf org create scratch --definition-file <path> --target-dev-hub <alias> --alias <name> --json
45+
```
46+
47+
**Edition only:**
48+
```bash
49+
sf org create scratch --edition developer --target-dev-hub <alias> --alias <name> --json
50+
```
51+
52+
**From snapshot:**
53+
```bash
54+
sf org create scratch --snapshot <snapshot-name> --target-dev-hub <alias> --alias <name> --json
55+
```
56+
57+
**From org shape:**
58+
```bash
59+
sf org create scratch --source-org <org-id> --target-dev-hub <alias> --alias <name> --json
60+
```
61+
62+
**Apply these flags when requested:**
63+
- `--duration-days <days>` — default 7, max 30
64+
- `--set-default` — make this the default org
65+
- `--no-track-source` — disable source tracking (for CI/CD)
66+
67+
**Step 4. MANDATORY - Run org list and write output:** After the org is created, you MUST run this command:
68+
69+
```bash
70+
sf org list --json
71+
```
72+
73+
Then:
74+
1. Parse the JSON result and find the `scratchOrgs` array
75+
2. Find the entry where `username` matches the username from Step 3's creation result
76+
3. Extract that complete org object (it will include: alias, username, orgId, instanceUrl, loginUrl, isDefaultUsername, connectedStatus, lastUsed, etc.)
77+
4. Report to the user:
78+
- Created scratch org.
79+
- Alias: [alias from the org list entry]
80+
- Username: [username]
81+
- Org ID: [orgId]
82+
83+
5. If an output directory is available (per the output artifacts rule above), write ONLY that extracted org object (NOT the full creation result) to `<output-dir>/scratch-org-result.json`
84+
85+
Example: If `sf org list --json` returns `{"result": {"scratchOrgs": [{"alias": "feature-dev", "username": "test@example.com", "orgId": "00D...", ...}]}}`, write just the inner org object `{"alias": "feature-dev", "username": "test@example.com", "orgId": "00D...", ...}` to the file.
86+
87+
Do NOT write the creation command's output. Do NOT suggest verification steps to the user.
88+
89+
**Error handling:**
90+
- "Snapshot not found" → suggest `sf org list snapshot --target-dev-hub <alias>`
91+
- "No default Dev Hub" → advise `sf org login web --set-default-dev-hub`
92+
93+
**When you need more detail:**
94+
- For available features, settings, and definition file structure → load `references/definition_file_options.md`
95+
- For edition selection guidance and comparison → load `references/edition_types.md`
96+
- For snapshot workflow and post-creation usage → load `references/snapshot_usage.md`
97+
- For complete scratch org creation workflow → load `references/creating-scratch-org.md`
98+
99+
---
100+
101+
## Creating Snapshots
102+
103+
**REQUIRED steps — execute in order:**
104+
105+
**Step 1. Get inputs:**
106+
- Source org: scratch org ID or alias (from user)
107+
- Snapshot name: unique name (from user)
108+
- Description: optional (from user)
109+
110+
**Step 2. Determine Dev Hub:**
111+
- If user specifies a Dev Hub (alias or username) → use that value
112+
- Otherwise, check for default:
113+
```bash
114+
sf config get target-dev-hub --json
115+
```
116+
- If no default Dev Hub is set, advise: `sf org login web --set-default-dev-hub`
117+
118+
**Step 3. Execute:**
119+
```bash
120+
sf org create snapshot --source-org <orgId-or-alias> --name <SnapshotName> --target-dev-hub <devHub> --json
121+
```
122+
123+
With description:
124+
```bash
125+
sf org create snapshot --source-org <orgId-or-alias> --name <SnapshotName> --description "<desc>" --target-dev-hub <devHub> --json
126+
```
127+
128+
**Step 4. Report result:** Returns JSON with SnapshotId and Status. If an output directory is available (per the output artifacts rule above), write the JSON response to `<output-dir>/snapshot-result.json`.
129+
130+
**Error handling:**
131+
- "NOT_FOUND" → Dev Hub doesn't have snapshot feature enabled
132+
- "Snapshot name already exists" → use a different unique name
133+
134+
**When you need more detail:**
135+
- For complete snapshot creation workflow and flag reference → load `references/creating-snapshot.md`
136+
- For CLI flag reference → load `references/cli_flags.md`
137+
138+
---
139+
140+
## Opening Orgs
141+
142+
**REQUIRED steps — execute in order:**
143+
144+
**Step 1. Match user request to command:**
145+
146+
| User wants | Command |
147+
|-----------|---------|
148+
| Open default org | `sf org open --json` |
149+
| Open specific org | `sf org open --target-org <alias> --json` |
150+
| Specific browser | `sf org open --browser chrome --json` |
151+
| Incognito mode | `sf org open --private --json` |
152+
| Navigate to path | `sf org open --path '<path>' --json` |
153+
| URL only (don't open) | `sf org open --url-only --json` |
154+
| Open metadata file | `sf org open --source-file <file-path> --json` |
155+
156+
**Step 2. Execute the matching command using the Bash tool.**
157+
158+
**Step 3. Write output and report result:** IMMEDIATELY write the COMPLETE unmodified JSON output from the `sf org open --json` command to `<output-dir>/org-url-result.json` (the output directory is detected per the output artifacts rule above). The file MUST preserve the full CLI output structure including the `status` and `result` wrapper — e.g. `{"status": 0, "result": {"orgId": "...", "url": "...", "username": "..."}}`. Do NOT unwrap or flatten the JSON. Do NOT ask permission, do NOT say "no files to generate." Then report the URL and org details to the user.
159+
160+
**Error handling:**
161+
- "no target org" → advise `sf config set target-org <alias>`
162+
- "auth error" → advise `sf org login web --alias <alias>`
163+
164+
**When you need more detail:**
165+
- For complete opening org workflow and all available flags → load `references/opening-org.md`
166+
167+
---
168+
169+
## Reference File Index
170+
171+
Load these reference files for detailed guidance:
172+
173+
| File | When to read |
174+
|------|-------------|
175+
| `references/definition_file_options.md` | User needs to configure org features, settings, or advanced definition file options beyond basic org creation |
176+
| `references/edition_types.md` | User asks which edition to choose or needs to understand edition differences |
177+
| `references/snapshot_usage.md` | User wants to use snapshots in definition files or needs post-snapshot workflow guidance |
178+
| `references/creating-scratch-org.md` | Troubleshooting scratch org creation failures or need complete workflow with all options |
179+
| `references/cli_flags.md` | User needs complete snapshot CLI flag reference |
180+
| `references/creating-snapshot.md` | Troubleshooting snapshot creation failures or need detailed snapshot workflow |
181+
| `references/opening-org.md` | User needs to navigate to specific setup paths, open metadata files, or use advanced open flags |
182+
183+
## Example Files
184+
185+
Example command outputs for testing and troubleshooting:
186+
187+
| File | Purpose |
188+
|------|---------|
189+
| `examples/scratch-orgs/success_definition_file.json` | Successful scratch org creation using `--definition-file` |
190+
| `examples/scratch-orgs/success_edition.json` | Successful scratch org creation using `--edition developer` |
191+
| `examples/scratch-orgs/success_snapshot.json` | Successful scratch org creation using `--snapshot` |
192+
| `examples/scratch-orgs/error_no_devhub.json` | Error when Dev Hub not authenticated |
193+
| `examples/scratch-orgs/error_timeout.json` | Timeout error during org creation (exit code 69) |
194+
| `examples/snapshots/success_output.json` | Successful snapshot creation |
195+
| `examples/snapshots/error_output.json` | Common snapshot error scenarios |
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Examples Directory
2+
3+
This directory contains example outputs for the three workflows supported by the `dx-org-manage` skill.
4+
5+
## Structure
6+
7+
```text
8+
examples/
9+
├── README.md # This file
10+
├── scratch-orgs/ # Scratch org creation examples
11+
│ ├── success_definition_file.json
12+
│ ├── success_edition.json
13+
│ ├── error_no_devhub.json
14+
│ └── error_timeout.json
15+
└── snapshots/ # Snapshot creation examples
16+
├── success_output.json
17+
└── error_output.json
18+
```
19+
20+
## scratch-orgs/
21+
22+
Examples of `sf org create scratch` command outputs for all four creation methods.
23+
24+
- **success_definition_file.json** - Successful creation using `--definition-file`
25+
- **success_edition.json** - Successful creation using `--edition developer`
26+
- **success_snapshot.json** - Successful creation using `--snapshot`
27+
- **error_no_devhub.json** - Error when Dev Hub not authenticated
28+
- **error_timeout.json** - Timeout error (exit code 69)
29+
30+
## snapshots/
31+
32+
Examples of `sf org create snapshot` command outputs.
33+
34+
- **success_output.json** - Successful snapshot creation
35+
- **error_output.json** - Common error scenarios (NOT_FOUND, duplicate name, etc.)
36+
37+
## Usage
38+
39+
These examples help illustrate:
40+
1. Expected JSON/text response formats
41+
2. Common error patterns
42+
3. How to parse success indicators (`username`, `orgId`, etc.)
43+
4. Async operation handling (snapshot creation, timeout scenarios)
44+
45+
Reference these when building eval datasets or troubleshooting command outputs.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"status": 1,
3+
"name": "NoDefaultEnvFound",
4+
"message": "No default Dev Hub org found. Set a default Dev Hub org using 'sf config set target-dev-hub <username|alias>'.",
5+
"exitCode": 1,
6+
"context": "ScratchOrgCreateCommand",
7+
"stack": "NoDefaultEnvFound: No default Dev Hub org found...",
8+
"warnings": []
9+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"status": 69,
3+
"name": "ScratchOrgCreateTimeoutError",
4+
"message": "The scratch org did not complete within your wait time (2 minutes).",
5+
"exitCode": 69,
6+
"context": "ScratchOrgCreateCommand",
7+
"data": {
8+
"requestId": "2SR5g000000BlYjGAK",
9+
"resumeCommand": "sf org resume scratch --job-id 2SR5g000000BlYjGAK --json"
10+
},
11+
"stack": "ScratchOrgCreateTimeoutError: The scratch org did not complete...",
12+
"warnings": []
13+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"status": 0,
3+
"result": {
4+
"username": "test-abcd1234@example.com",
5+
"orgId": "00D5g000008xYZ1EAM",
6+
"scratchOrgInfo": {
7+
"Id": "2SR5g000000BlYjGAK",
8+
"Edition": "Developer",
9+
"Status": "Active",
10+
"SignupUsername": "test-abcd1234@example.com",
11+
"AdminEmail": "admin@example.com",
12+
"Namespace": null,
13+
"OrgName": "My Company",
14+
"ConnectedAppConsumerKey": "3MVG9...",
15+
"ScratchOrg": "00D5g000008xYZ1EAM",
16+
"CreatedDate": "2026-06-12T15:10:00.000+0000",
17+
"ExpirationDate": "2026-06-19"
18+
},
19+
"authFields": {
20+
"accessToken": "00D5g...",
21+
"instanceUrl": "https://...-dev-ed.develop.my.salesforce.com",
22+
"username": "test-abcd1234@example.com",
23+
"orgId": "00D5g000008xYZ1EAM",
24+
"loginUrl": "https://test.salesforce.com"
25+
},
26+
"warnings": []
27+
}
28+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"status": 0,
3+
"result": {
4+
"username": "test-xyz5678@example.com",
5+
"orgId": "00D5g000009aBC2EAM",
6+
"scratchOrgInfo": {
7+
"Id": "2SR5g000000CdEfGHI",
8+
"Edition": "Developer",
9+
"Status": "Active",
10+
"SignupUsername": "test-xyz5678@example.com",
11+
"AdminEmail": "dev@example.com",
12+
"Namespace": null,
13+
"OrgName": "Company",
14+
"ScratchOrg": "00D5g000009aBC2EAM",
15+
"CreatedDate": "2026-06-12T15:15:00.000+0000",
16+
"ExpirationDate": "2026-06-19"
17+
},
18+
"authFields": {
19+
"accessToken": "00D5g...",
20+
"instanceUrl": "https://...-dev-ed.develop.my.salesforce.com",
21+
"username": "test-xyz5678@example.com",
22+
"orgId": "00D5g000009aBC2EAM"
23+
},
24+
"warnings": []
25+
}
26+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"status": 0,
3+
"result": {
4+
"username": "test-snap9012@example.com",
5+
"orgId": "00D5g00000aDEF3EAM",
6+
"scratchOrgInfo": {
7+
"Id": "2SR5g000000EfGhIJK",
8+
"Edition": "Developer",
9+
"Status": "Active",
10+
"SignupUsername": "test-snap9012@example.com",
11+
"AdminEmail": "dev@example.com",
12+
"Namespace": null,
13+
"OrgName": "Company",
14+
"ScratchOrg": "00D5g00000aDEF3EAM",
15+
"SnapshotName": "MySnapshot",
16+
"CreatedDate": "2026-06-12T15:20:00.000+0000",
17+
"ExpirationDate": "2026-06-19"
18+
},
19+
"authFields": {
20+
"accessToken": "00D5g...",
21+
"instanceUrl": "https://...-dev-ed.develop.my.salesforce.com",
22+
"username": "test-snap9012@example.com",
23+
"orgId": "00D5g00000aDEF3EAM"
24+
},
25+
"warnings": []
26+
}
27+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"status": 1,
3+
"name": "NOT_FOUND",
4+
"message": "Org snapshots are not enabled in this org. Contact Salesforce to enable org snapshots.",
5+
"exitCode": 1,
6+
"commandName": "SnapshotCreate",
7+
"stack": "NOT_FOUND: Org snapshots are not enabled in this org...",
8+
"warnings": []
9+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"status": 0,
3+
"result": {
4+
"Id": "0Oo5g00000001ABCAA",
5+
"Status": "Pending",
6+
"SourceOrg": "00D5g00000001XyEAI",
7+
"SnapshotName": "MySnapshot",
8+
"Description": "Baseline configuration with Package v1.2.0",
9+
"Content": "metadatadata",
10+
"CreatedDate": "2026-06-04T20:00:00.000+0000",
11+
"CreatedBy": "0055g00000001UserEAA",
12+
"LastModifiedDate": "2026-06-04T20:00:00.000+0000",
13+
"LastModifiedBy": "0055g00000001UserEAA"
14+
}
15+
}

0 commit comments

Comments
 (0)