@salesforce/afv-skills 1.18.0 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,161 @@
1
+ ---
2
+ name: managing-suite-assignments
3
+ description: "Manages all forms of test suite assignment for DevOps Center pipeline stages via the Connect API testSuiteStages endpoint. Covers three modes: (A) attaching a single suite to a stage as a one-off add, (B) bulk-mapping multiple suites to a stage as a testing strategy with a mandatory impact-preview table before any changes, and (C) adding or removing individual test classes within a suite assignment with governance rules that exclude rejected tests and re-present the final list before committing. TRIGGER when: a suite is found unlinked from a pipeline stage and the user wants to assign it; the user wants to configure suite-to-stage mappings across a pipeline or assign multiple suites to stages as part of a testing strategy; the user wants to add or remove tests in a suite, sync reviewed tests into a suite, or promote tests to a suite. DO NOT TRIGGER when: authoring new test classes (use generating-apex-test) or running tests directly (use running-apex-tests)."
4
+ metadata:
5
+ version: "1.0"
6
+ minApiVersion: "67.0"
7
+ ---
8
+
9
+ # Managing Suite Assignments
10
+
11
+ ## Prerequisites
12
+
13
+ Load `checking-devops-prerequisites` first — Prerequisites 1–4 AND Prerequisite 5 (stage). You need `doce-org-alias`, `pipelineId`, and `stageId` before proceeding in any mode.
14
+
15
+ | Variable | Description |
16
+ |---|---|
17
+ | `doce-org-alias` | Established in Prerequisite 1 |
18
+ | `pipelineId` | Identified in Prerequisite 4 (pipeline selection) |
19
+ | `stageId` | Identified in Prerequisite 5 (stage selection) |
20
+ | `event` | `Pre-Promote`, `Post-Promote`, or `Review` |
21
+
22
+ ---
23
+
24
+ ## Mode A — Assign a single suite to a stage
25
+
26
+ Use this mode when a relevant test suite already exists but is not yet linked to a pipeline stage and the user wants to add it as a single one-off assignment.
27
+
28
+ **Additional inputs required:**
29
+
30
+ | Variable | Description |
31
+ |---|---|
32
+ | `testSuiteId` | ID of the suite to assign |
33
+ | `testSuiteName` | Name of the suite (for display in confirmation) |
34
+
35
+ **Confirmation gate**
36
+
37
+ **Confirmation required before any API call is made.**
38
+
39
+ Present the following prompt to the user and wait for an affirmative response:
40
+
41
+ > "The suite `<testSuiteName>` is not currently assigned to the `<stageName>` stage (`<event>`). Would you like me to assign it now?"
42
+
43
+ Do not proceed until the user confirms.
44
+
45
+ **On success**
46
+
47
+ Report to the user:
48
+
49
+ > "Suite `<testSuiteName>` has been assigned to the `<stageName>` stage (`<event>`)."
50
+
51
+ ---
52
+
53
+ ## Mode B — Map multiple suites to a stage
54
+
55
+ Use this mode when configuring suite-to-stage mappings across a pipeline or assigning multiple suites to stages as part of a testing strategy.
56
+
57
+ **Additional inputs required:**
58
+
59
+ | Input | Description |
60
+ |---|---|
61
+ | `testSuiteOperations` | List of `{testSuiteId, action: "add"\|"remove"}` |
62
+
63
+ **MANDATORY IMPACT PREVIEW — Required Before Any Changes**
64
+
65
+ **Do not call the API until the user has confirmed the preview below.**
66
+
67
+ Present the full mapping summary and wait for explicit confirmation:
68
+
69
+ > "Here's the suite mapping I'll apply:
70
+ >
71
+ > | Suite | Stage | Event | Action |
72
+ > |---|---|---|---|
73
+ > | `<suiteName>` | `<stageName>` | `<event>` | Add |
74
+ > | `<suiteName2>` | `<stageName>` | `<event>` | Remove |
75
+ >
76
+ > Confirm to apply all changes?"
77
+
78
+ Only proceed after the user explicitly confirms.
79
+
80
+ **On success**
81
+
82
+ > "Suite mapping applied. `<N>` suite(s) updated for the `<stageName>` stage."
83
+
84
+ ---
85
+
86
+ ## Mode C — Add/remove test classes in a suite
87
+
88
+ Use this mode when the user wants to add or remove individual test classes within an existing suite assignment, sync reviewed tests into a suite, or promote tests to a suite.
89
+
90
+ **Additional inputs required:**
91
+
92
+ | Input | Source |
93
+ |---|---|
94
+ | `testSuiteOperations` | List of `{testSuiteId, action: "add"\|"remove"}` |
95
+
96
+ **Governance rules**
97
+
98
+ - **Never call this without explicit approval.** AI-reviewed or modified tests must be re-presented to the user before this call is made.
99
+ - Rejected tests must be EXCLUDED from the payload — do not include them even if they were previously in the suite.
100
+ - If tests were modified during review, re-present the final list of tests before requesting confirmation.
101
+
102
+ **Confirmation gate**
103
+
104
+ **REQUIRED — do not skip.** Show the user the full list of changes before calling:
105
+
106
+ > "I'm about to sync the following changes to the test suite:
107
+ > - **Add:** `<testSuiteName1>`, `<testSuiteName2>`
108
+ > - **Remove:** `<testSuiteName3>`
109
+ > - Stage: `<stageName>` | Event: `<event>`
110
+ >
111
+ > Confirm?"
112
+
113
+ Only proceed after receiving explicit confirmation.
114
+
115
+ **On success**
116
+
117
+ Confirm to the user:
118
+ > "Test suite updated successfully for the `<stageName>` stage."
119
+
120
+ ---
121
+
122
+ ## The system call
123
+
124
+ All three modes use the same endpoint. Substitute all `<placeholder>` values before executing.
125
+
126
+ ```bash
127
+ sf api request rest "/services/data/v67.0/connect/devopstesting/pipeline/<pipelineId>/testSuiteStages" --method POST --body '{"pipelineStageId":"<stageId>","event":"<event>","assignments":[{"testSuiteId":"<id>","action":"add|remove"}]}' --target-org <doce-org-alias>
128
+ ```
129
+
130
+ Full payload schema:
131
+
132
+ ```json
133
+ {
134
+ "pipelineStageId": "<stageId>",
135
+ "event": "<event>",
136
+ "assignments": [
137
+ {"testSuiteId": "<suiteId1>", "action": "add"},
138
+ {"testSuiteId": "<suiteId2>", "action": "remove"}
139
+ ]
140
+ }
141
+ ```
142
+
143
+ **Error handling**
144
+
145
+ Never expose raw API error messages to the user. Map response status codes to the following user-facing messages:
146
+
147
+ | Status | User-facing message |
148
+ |---|---|
149
+ | 400 | "The request was invalid. Check that all suite and stage IDs are correct and the event type is valid." |
150
+ | 403 | "You don't have permission to modify suite assignments on this pipeline." |
151
+ | 404 | "The pipeline or stage was not found." |
152
+ | 500 | "A server error occurred. Try again in a few minutes." |
153
+
154
+ ---
155
+
156
+ ## Related skills
157
+
158
+ - **`syncing-test-providers`** — use when the suite you want to assign doesn't appear yet; re-syncing the provider pulls in newly added suites.
159
+ - **`recommending-devops-tests`** — use when a suite has not yet been identified and you need a recommendation for which suite to assign.
160
+ - **`configuring-quality-gate`** — use to configure a quality gate on the stage after mapping suites.
161
+ - **`analyzing-test-failures`** — use for failure analysis and suggested improvements to the tests within a suite.
@@ -0,0 +1,111 @@
1
+ ---
2
+ name: platform-agentexchange-partner-offers-enable
3
+ description: "Enable or disable the org preference that controls whether a Salesforce org can receive partner offers from the Transactable Marketplace. Use this skill when the user wants to turn partner offer reception on or off for an org. TRIGGER when: user asks to enable or disable partner offers, configure TransactableMarketplaceReceivePartnerOffers, configure enableTransactableMarketplaceReceivePartnerOffers, set up marketplace partner offer reception, toggle the TM partner offers setting, edit a TransactableMarketplacePrivateOffer.settings file, or configure org preferences related to transactable marketplace. DO NOT TRIGGER when: user needs to create or manage the partner offer records themselves, configure marketplace listing settings, or work with SfdcPartnerOffer objects (use deploying-metadata or generating-apex instead)."
4
+ metadata:
5
+ version: "1.0"
6
+ minApiVersion: "67.0"
7
+ ---
8
+
9
+ # Enabling Transactable Marketplace Receive Partner Offers Org Preference
10
+
11
+ This skill configures the `enableTransactableMarketplaceReceivePartnerOffers` org preference via the `TransactableMarketplacePrivateOfferSettings` Metadata API type, which controls whether a Salesforce org is eligible to receive partner offers through the Transactable Marketplace. It is required for subscriber orgs that participate in the TM partner offer flow.
12
+
13
+ ## Scope
14
+
15
+ - **In scope**: Reading the current value of the pref, enabling or disabling it via Metadata API (`TransactableMarketplacePrivateOfferSettings`), and verifying the change took effect.
16
+ - **Out of scope**: Creating or managing partner offer records, configuring marketplace listings, or any Apex/trigger changes related to offer processing.
17
+
18
+ ---
19
+
20
+ ## Required Inputs
21
+
22
+ - **Target org alias or username**: The org where the pref should be set. Ask if not provided.
23
+ - **Desired state**: `true` (enable) or `false` (disable). Default: `true`.
24
+
25
+ ---
26
+
27
+ ## Workflow
28
+
29
+ ### Phase 1 — Check current state
30
+
31
+ 1. **Query the current preference value** by running:
32
+ ```bash
33
+ sf data query -q "SELECT Preference, Value FROM OrgPreference WHERE Preference = 'TransactableMarketplaceReceivePartnerOffers'" --target-org <alias> --use-tooling-api
34
+ ```
35
+ If the record exists and `Value = true`, the pref is already enabled — confirm with the user before proceeding.
36
+ If the query returns no rows, the pref is not yet set (defaults to `false`).
37
+
38
+ 2. **Resolve the org's package directory** to determine where to write metadata. Run this and use its output as `<packageDir>`:
39
+ ```bash
40
+ jq -r '.packageDirectories[0].path // "force-app/main/default"' sfdx-project.json
41
+ ```
42
+
43
+ ### Phase 2 — Apply the preference
44
+
45
+ 3. **Write the TransactableMarketplacePrivateOfferSettings metadata file** — load `assets/org-pref-template.md` for the exact XML structure, then write the file at:
46
+ ```text
47
+ <packageDir>/settings/TransactableMarketplacePrivateOffer.settings
48
+ ```
49
+ Set `<enableTransactableMarketplaceReceivePartnerOffers>true</enableTransactableMarketplaceReceivePartnerOffers>` (or `false` if disabling).
50
+
51
+ 4. **Deploy the metadata** to the target org. Before running the deploy, confirm with the user:
52
+ - [ ] Confirmed the target org alias with the user (deploying to the wrong org is not easily reversible)
53
+ - [ ] Confirmed the desired state (`true`/`false`) matches the user's intent
54
+ ```bash
55
+ sf project deploy start --metadata TransactableMarketplacePrivateOfferSettings --target-org <alias>
56
+ ```
57
+
58
+ ### Phase 3 — Verify
59
+
60
+ 5. **Confirm the change** by re-running the Tooling API query from step 1 and verifying the `Value` column matches the desired state.
61
+
62
+ 6. **Report to the user** — see Output Expectations below.
63
+
64
+ ---
65
+
66
+ ## Rules / Constraints
67
+
68
+ | Rule | Rationale |
69
+ |------|-----------|
70
+ | Always query the current value before writing metadata | Avoids unnecessary deploys and detects conflicting changes |
71
+ | Use `TransactableMarketplacePrivateOfferSettings` as the metadata type | This is the concrete type registered in the platform for this pref, not the generic `OrgPreferenceSettings` |
72
+ | The settings file must be named `TransactableMarketplacePrivateOffer.settings` | Metadata API requires the filename to match the settings node name |
73
+ | Do not hardcode `force-app/main/default/` | Always read `sfdx-project.json` for the actual package directory |
74
+ | Never deploy without confirming the org alias with the user | Deploying to the wrong org is not easily reversible |
75
+
76
+ ---
77
+
78
+ ## Gotchas
79
+
80
+ | Issue | Resolution |
81
+ |-------|------------|
82
+ | Tooling API query returns no rows | Pref is unset (defaults to `false`). Safe to create a new settings file. |
83
+ | Deploy fails with `INVALID_TYPE` | The metadata type name is `TransactableMarketplacePrivateOfferSettings` — check the `--metadata` flag value. |
84
+ | Deploy succeeds but value doesn't change | Another settings file in the project may be overriding this one. Search for other `TransactableMarketplacePrivateOffer.settings` files in the project. |
85
+ | `INSUFFICIENT_ACCESS_OR_READONLY` on deploy | User running the deploy must have the "Modify All Data" or org preference admin permission in the target org. |
86
+ | Pref not visible in UI | `enableTransactableMarketplaceReceivePartnerOffers` is not surfaced in Setup UI — the Tooling API query is the only way to verify it. |
87
+ | Available from API version 67.0+ only | The type is available from API v67.0 — deploying against an older API version will fail. |
88
+
89
+ ---
90
+
91
+ ## Output Expectations
92
+
93
+ After completing all phases, report:
94
+
95
+ ```text
96
+ Org: <alias>
97
+ Preference: enableTransactableMarketplaceReceivePartnerOffers
98
+ Previous value: <true|false|unset>
99
+ New value: <true|false>
100
+ File written: <packageDir>/settings/TransactableMarketplacePrivateOffer.settings
101
+ Deploy status: Success
102
+ ```
103
+
104
+ ---
105
+
106
+ ## Reference File Index
107
+
108
+ | File | When to read |
109
+ |------|-------------|
110
+ | `assets/org-pref-template.md` | Phase 2, step 3 — use as the exact XML structure for the settings file |
111
+ | `examples/org-preference-settings.xml` | To verify the generated file matches expected format |
@@ -0,0 +1,27 @@
1
+ # TransactableMarketplacePrivateOfferSettings XML Template
2
+
3
+ Use this exact structure when writing the settings metadata file.
4
+
5
+ ## File path
6
+
7
+ ```text
8
+ <packageDir>/settings/TransactableMarketplacePrivateOffer.settings
9
+ ```
10
+
11
+ ## Template
12
+
13
+ ```xml
14
+ <?xml version="1.0" encoding="UTF-8"?>
15
+ <TransactableMarketplacePrivateOfferSettings xmlns="http://soap.sforce.com/2006/04/metadata">
16
+ <enableTransactableMarketplaceReceivePartnerOffers>true</enableTransactableMarketplaceReceivePartnerOffers>
17
+ </TransactableMarketplacePrivateOfferSettings>
18
+ ```
19
+
20
+ Replace `true` with `false` to disable.
21
+
22
+ ## Notes
23
+
24
+ - The metadata type is `TransactableMarketplacePrivateOfferSettings`, available from API version 67.0+.
25
+ - This type is registered with `apiCreateAllowed="false"` and `apiDeleteAllowed="false"` — it can only be updated, not created or deleted via the API. This does NOT mean you should skip writing the file: the preference always exists in the org with a default value, so writing a new local settings file and deploying it is treated as an update by the Metadata API and is always valid.
26
+ - The `xmlns` attribute is required; omitting it causes a deploy parse error.
27
+ - The field name is `enableTransactableMarketplaceReceivePartnerOffers` (note the `enable` prefix).
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <TransactableMarketplacePrivateOfferSettings xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <enableTransactableMarketplaceReceivePartnerOffers>true</enableTransactableMarketplaceReceivePartnerOffers>
4
+ </TransactableMarketplacePrivateOfferSettings>
@@ -0,0 +1,72 @@
1
+ ---
2
+ name: polling-test-results
3
+ description: "Polls a DevOps Center async test execution by runId until it completes, fails, or times out — using read-only SOQL on the execution record at provider-specific intervals (Apex 15s/5m, Code Analyzer 10s/3m, Provar UI 60s/20m, Flow 20s/8m) — then surfaces results. Use this skill when a test suite run is in progress and the user is waiting on results, or immediately after running a suite. TRIGGER when: a test suite run is in progress and the user is waiting on results, or immediately after running a suite and a runId is available. DO NOT TRIGGER when: there is no active runId."
4
+ metadata:
5
+ version: "1.0"
6
+ minApiVersion: "67.0"
7
+ ---
8
+
9
+ # polling-test-results
10
+
11
+ **Confirmation required:** No — polling is automatic and read-only. No user confirmation gate is needed.
12
+
13
+ **What it does:** Polls the DevOps Center org for the status of an async test execution until it completes, times out, or fails.
14
+
15
+ ---
16
+
17
+ ## Prerequisites
18
+
19
+ You need an active `runId` (returned by the `running-devops-test-suite` skill) and the confirmed `doce-org-alias`. If org context is not yet established, load `checking-devops-prerequisites` first (Prerequisites 1–3).
20
+
21
+ ---
22
+
23
+ ## Inputs required
24
+
25
+ | Input | Source |
26
+ |---|---|
27
+ | `runId` | Returned by the `running-devops-test-suite` skill |
28
+ | `testType` | Derived from the suite's test provider (Apex, Code Analyzer, UI/Provar, Flow) |
29
+ | `doce-org-alias` | Established via `checking-devops-prerequisites` |
30
+
31
+ ## Polling configuration
32
+
33
+ | Test type | Poll interval | Max wait | Timeout action |
34
+ |---|---|---|---|
35
+ | Apex unit tests | 15 seconds | 5 minutes | Surface runId, offer retry |
36
+ | Code Analyzer | 10 seconds | 3 minutes | Surface runId, offer retry |
37
+ | UI tests (Provar) | 60 seconds | 20 minutes | Surface runId, mark as pending |
38
+ | Flow tests | 20 seconds | 8 minutes | Surface runId, offer retry |
39
+
40
+ ## Poll query
41
+
42
+ Query the execution record by `runId` on each interval:
43
+
44
+ ```bash
45
+ sf data query \
46
+ --query "SELECT Id, Status, TestsRan, TestsPassed, TestsFailed, CoveragePercentage FROM DevopsTestExecution WHERE Id = '<runId>' LIMIT 1" \
47
+ --target-org <doce-org-alias> \
48
+ --json
49
+ ```
50
+
51
+ Check the `Status` field on each poll:
52
+ - `Queued` / `Running` → wait and poll again
53
+ - `Completed` → proceed to result analysis
54
+ - `Failed` → surface error and offer retry or skip
55
+
56
+ ## On timeout
57
+
58
+ Surface the `runId` to the user:
59
+ > "The test run is taking longer than expected. Your run ID is `<runId>`. You can check the status manually in DevOps Center, or I can keep waiting — what would you prefer?"
60
+
61
+ Do not automatically retry after timeout. Wait for user instruction.
62
+
63
+ ## On completion
64
+
65
+ Pass the full result payload to the `analyzing-test-failures` skill for reasoning. Surface `Coverage`, `SuccessCount`, `FailureCount`, and `QualityGateStatus` inline. Do not surface raw JSON to the user.
66
+
67
+ ---
68
+
69
+ ## Related skills
70
+
71
+ - Runs are started by `running-devops-test-suite` (including its retrigger mode)
72
+ - Failure analysis is handled by `analyzing-test-failures`
@@ -0,0 +1,137 @@
1
+ ---
2
+ name: recommending-devops-tests
3
+ description: "Analyzes a commit diff and available DevOps Center test suite metadata to recommend the most relevant existing test suites, then flags coverage gaps where no suite covers a new method — via pure reasoning, no system calls beyond the prerequisite queries. Use this skill when a developer wants to know which test suites to run for a specific commit or diff, what tests cover their changes, or wants suite recommendations at commit time. TRIGGER when: the user asks which test suites to run for a commit/diff, asks what tests cover their changes, or asks for suite recommendations before promoting. DO NOT TRIGGER when: authoring new tests (use generating-apex-test) or running sf apex run test directly (use running-apex-tests)."
4
+ metadata:
5
+ version: "1.0"
6
+ minApiVersion: "67.0"
7
+ ---
8
+
9
+ # Recommending DevOps Tests
10
+
11
+ **Type:** Pure reasoning — no system calls beyond the prerequisite data-fetch queries documented below.
12
+
13
+ **What it does:** Analyzes the commit diff and available suite metadata to recommend the most relevant existing test suites assigned to the Review pipeline stage. Flags coverage gaps where no suite covers a new method.
14
+
15
+ ---
16
+
17
+ ## Prerequisites
18
+
19
+ Load and follow the `checking-devops-prerequisites` skill first (Prerequisites 1–4). This skill needs a confirmed DevOps Center org alias and pipeline Id before it can proceed.
20
+
21
+ ---
22
+
23
+ ## Step 1 — Fetch suite metadata
24
+
25
+ Before reasoning can begin, fetch the test suite metadata assigned to the Review pipeline stage. This requires two queries.
26
+
27
+ **1a — Find the Review pipeline stage trigger:**
28
+
29
+ ```bash
30
+ sf data query \
31
+ --query "SELECT Id FROM DevopsPipelineStageTrigger WHERE TriggerType = 'Review' AND RelatedRecordId = '<pipelineId>'" \
32
+ --target-org <doce-org-alias> \
33
+ --json
34
+ ```
35
+
36
+ Record the `Id` returned as `<reviewTriggerId>`.
37
+
38
+ **1b — Fetch suites assigned to that trigger:**
39
+
40
+ ```bash
41
+ sf data query \
42
+ --query "SELECT Id, TestSuiteId, TestSuite.Name, IsQualityGateEnabled, DevopsQualityGateId FROM DevopsTestSuiteStage WHERE DevopsPipelineStageTriggerId = '<reviewTriggerId>'" \
43
+ --target-org <doce-org-alias> \
44
+ --json
45
+ ```
46
+
47
+ Each row provides: `TestSuiteId`, `TestSuite.Name`, `IsQualityGateEnabled`, and `DevopsQualityGateId` (when a gate is configured).
48
+
49
+ > Note: Do NOT use the beta `/connect/devops/.../testSuites` endpoint — it returns empty results. Query `DevopsTestSuiteStage` directly as shown above.
50
+
51
+ Never expose raw API errors or raw JSON to the user. If a query fails, report the problem in plain language and stop.
52
+
53
+ The commit diff comes from the user or surrounding context.
54
+
55
+ ---
56
+
57
+ ## Reasoning steps
58
+
59
+ ### 1 — Classify the diff by change type
60
+
61
+ Parse the diff file extensions and paths to determine what types of changes were made:
62
+
63
+ | File pattern | Change type |
64
+ |---|---|
65
+ | `*.cls`, `*.trigger` | Apex |
66
+ | `*.flow-meta.xml`, `*.flow` | Flow |
67
+ | `*.java` | Java |
68
+ | `*.js`, `*.html` (LWC paths) | LWC / JavaScript |
69
+
70
+ A single commit may contain multiple change types. Identify all of them.
71
+
72
+ ### 2 — Map change types to test providers
73
+
74
+ For each change type identified, match against the `testProviderName` of the fetched suites:
75
+
76
+ | Change type | Match suites whose `testProviderName` contains |
77
+ |---|---|
78
+ | Apex | `Apex` |
79
+ | Flow | `Flow` |
80
+ | Java | `Java` |
81
+ | LWC / JavaScript | `LWC` or `JavaScript` |
82
+ | Code Analyzer (any) | `Code Analyzer` — then sub-filter by suite name convention: `recommended` → Apex/general rules (suggest for Apex and Java changes), `html` → suggest for HTML/LWC template changes, `css` → suggest for CSS changes. If no suite name matches the convention, suggest all Code Analyzer suites and note the ambiguity. |
83
+
84
+ Only recommend suites whose provider matches at least one change type in the diff. Suites from non-matching providers are excluded from the recommendation.
85
+
86
+ ### 3 — Rank matched suites
87
+
88
+ Within each matched provider group, rank suites by:
89
+ 1. `triggerType` alignment — `Pre-Promote` suites first for commit-time checks
90
+ 2. Quality gate presence — suites with a `qualityGateRuleName` are higher priority (they gate promotion)
91
+ 3. Suite name relevance — if the suite name contains a term from the modified file names, boost it
92
+
93
+ ### 4 — Flag new methods with no suite coverage
94
+
95
+ For any new method added in the diff, flag it as a gap regardless of provider matching:
96
+ > "⚠ `processRefund()` in `OrderService.cls` is a new method. No existing suite can confirm it's covered until tests are authored and linked."
97
+
98
+ ### 5 — Return the recommendation list
99
+
100
+ Group recommendations by change type so it's clear why each suite was suggested.
101
+
102
+ ---
103
+
104
+ ## Output format
105
+
106
+ ```text
107
+ Recommended suite(s) for this commit:
108
+
109
+ Apex changes detected (OrderService.cls, InvoiceService.cls):
110
+ 1. <SuiteName> — Apex Test Provider | Trigger: Pre-Promote | Gate: <gateName or none>
111
+ 2. <SuiteName2> — Apex Test Provider | Trigger: Post-Promote | Gate: <gateName or none>
112
+
113
+ Flow changes detected (OrderApproval.flow):
114
+ 1. <SuiteName3> — Flow Test Provider | Trigger: Pre-Promote | Gate: <gateName or none>
115
+
116
+ Code Analyzer — Apex rules:
117
+ 1. <SuiteName4> — Code Analyzer | Trigger: Pre-Promote | Gate: <gateName or none>
118
+
119
+ No matching suite found for:
120
+ - LWC changes — no LWC test suite is assigned to this stage
121
+
122
+ Coverage gaps (new methods — manual authoring required):
123
+ - `processRefund()` in `OrderService.cls` — new method, not yet covered by any suite
124
+ ```
125
+
126
+ ---
127
+
128
+ ## v1 constraint
129
+
130
+ Only recommend existing suites. Never suggest generating new tests. If gaps exist, direct the developer to author tests manually and explain exactly which methods need coverage.
131
+
132
+ ---
133
+
134
+ ## Related skills
135
+
136
+ - To analyze failures from a run, use `analyzing-test-failures`.
137
+ - To actually execute a recommended suite, use `running-devops-test-suite`.
@@ -0,0 +1,144 @@
1
+ ---
2
+ name: running-devops-test-suite
3
+ description: "Triggers async execution of one or more DevOps Center test suites on a pipeline stage (Pre-Promote, Post-Promote, or Review event) via the Connect API, after an explicit user confirmation gate, then hands off to result polling via the `polling-test-results` skill. Also re-runs (retriggers) a quality gate after fixes — but only once validation confirms the coverage threshold is now met. TRIGGER when: the user wants to run, kick off, or launch test suites on a pipeline stage; execute tests before or after a promotion; trigger a Pre-Promote, Post-Promote, or Review-event run; re-run a quality gate after fixing failures; retry a failed gate once coverage is met; or unblock a blocked promotion after adding tests. DO NOT TRIGGER when: running sf apex run test directly (use running-apex-tests); or configuring a NEW gate or threshold (use configuring-quality-gate)."
4
+ metadata:
5
+ version: "1.0"
6
+ minApiVersion: "67.0"
7
+ ---
8
+
9
+ # Running a DevOps Center Test Suite
10
+
11
+ ## Prerequisites
12
+
13
+ Load and follow `checking-devops-prerequisites` first — run Prerequisites 1–4 AND Prerequisite 5 (pipeline stage), since this skill operates on a specific stage. You need the confirmed `doce-org-alias`, `pipelineId`, and `stageId` before proceeding.
14
+
15
+ ## Inputs required before calling this skill
16
+
17
+ | Input | How to obtain |
18
+ |---|---|
19
+ | `pipelineId` | From Prerequisite 4 (pipeline selection) |
20
+ | `stageId` | From Prerequisite 5 (pipeline stage confirmation) |
21
+ | `event` | Confirm with user: `Pre-Promote` or `Post-Promote` (or `Review` if the context is a review environment) |
22
+ | `testSuiteIds` | Confirmed suite IDs from the suite selection or recommendation step |
23
+ | `doce-org-alias` | Established in Prerequisite 1 |
24
+
25
+ ## Confirmation gate
26
+
27
+ **This call mutates org state — do not proceed without explicit user confirmation.**
28
+
29
+ Before calling the API, show the user:
30
+
31
+ > "I'm about to run tests with the following configuration:
32
+ > - Pipeline: `<pipelineName>`
33
+ > - Stage: `<stageName>`
34
+ > - Event: `<event>`
35
+ > - Suite(s): `<suiteName(s)>`
36
+ > - Org: `<doce-org-alias>`
37
+ >
38
+ > Shall I proceed?"
39
+
40
+ Do not make the API call until the user confirms.
41
+
42
+ ## API call
43
+
44
+ ```bash
45
+ sf api request rest \
46
+ "/services/data/v67.0/connect/devopstesting/pipeline/<pipelineId>/stage/execute" \
47
+ --method POST \
48
+ --body '{
49
+ "stageId": "<stageId>",
50
+ "event": "<event>",
51
+ "testSuiteIds": ["<suiteId1>", "<suiteId2>"]
52
+ }' \
53
+ --target-org <doce-org-alias>
54
+ ```
55
+
56
+ ### Body schema
57
+
58
+ | Field | Type | Description |
59
+ |---|---|---|
60
+ | `stageId` | string | The ID of the pipeline stage to execute tests on |
61
+ | `event` | string | `Pre-Promote`, `Post-Promote`, or `Review` |
62
+ | `testSuiteIds` | string[] | One or more test suite IDs to execute |
63
+
64
+ ## On success
65
+
66
+ Extract the `runId` (or execution ID) from the response. Inform the user:
67
+
68
+ > "Tests are running in `<doce-org-alias>`. I'll update you when results are ready."
69
+
70
+ Immediately hand off the `runId` to the `polling-test-results` skill to begin the polling loop.
71
+
72
+ ## On error
73
+
74
+ | Status | Message to user |
75
+ |---|---|
76
+ | 400 | "The test execution request was invalid. Check that the stage and suite IDs are correct." |
77
+ | 403 | "You don't have permission to run tests on this pipeline. Check your DevOps Testing API access." |
78
+ | 404 | "The pipeline or stage was not found. It may have been deleted." |
79
+ | 500 | "The DevOps Center org returned a server error. Try again in a few minutes." |
80
+
81
+ Never expose raw API errors to the user.
82
+
83
+ ---
84
+
85
+ ## Retrigger mode (re-running a quality gate)
86
+
87
+ Use this mode when a promotion was blocked by a quality gate failure and the coverage gap has since been addressed.
88
+
89
+ ### Extra preconditions — all must be true before proceeding
90
+
91
+ 1. The `Coverage` field on the latest `DevopsTestSuiteExecution` meets or exceeds the threshold defined in the `DevopsQualityGateRule`
92
+ 2. The user has explicitly asked to retrigger the gate
93
+ 3. The same `pipelineId`, `stageId`, and `event` from the blocked promotion are known
94
+
95
+ If coverage is still below threshold, do **not** retrigger. Instead, respond:
96
+
97
+ > "Coverage is still at `<X>%`, below the `<threshold>%` gate. The gate cannot be retriggered until the threshold is met. Here are the remaining uncovered methods: `<list>`."
98
+
99
+ Do not retry. Explain what must be resolved first and stop.
100
+
101
+ ### Inputs required for retrigger
102
+
103
+ | Input | Source |
104
+ |---|---|
105
+ | `pipelineId` | From the blocked promotion context |
106
+ | `stageId` | From the blocked promotion context |
107
+ | `event` | Same event type that originally blocked (`Pre-Promote` or `Post-Promote`) |
108
+ | `suiteIds` | Same suites that were originally run |
109
+ | `doce-org-alias` | Established in Prerequisite 1 |
110
+
111
+ ### Confirmation gate (retrigger)
112
+
113
+ Before executing the API call, present this confirmation prompt and wait for explicit user approval:
114
+
115
+ > "Coverage is confirmed at `<X>%`, which meets the `<threshold>%` gate. I'll retrigger the quality gate check for the `<stageName>` stage (`<event>`). Confirm?"
116
+
117
+ Only proceed after the user confirms. If the user declines, stop without making any API call.
118
+
119
+ ### API call (retrigger)
120
+
121
+ Uses the same Connect API stage/execute endpoint:
122
+
123
+ ```bash
124
+ sf api request rest "/services/data/v67.0/connect/devopstesting/pipeline/<pipelineId>/stage/execute" --method POST --body '{"stageId":"<stageId>","event":"<event>","testSuiteIds":["<suiteId1>"]}' --target-org <doce-org-alias>
125
+ ```
126
+
127
+ After the call returns a `runId`, hand off to the `polling-test-results` skill with the new `runId` to monitor the execution result.
128
+
129
+ ### Error handling (retrigger)
130
+
131
+ If the API returns an error indicating the gate cannot be retriggered, respond with:
132
+
133
+ > "The quality gate cannot be retriggered right now. Reason: `<plain-language summary>`. Here's what needs to be resolved first: `<list>`."
134
+
135
+ Never expose raw API error details to the user.
136
+
137
+ ---
138
+
139
+ ## Related skills
140
+
141
+ - **`polling-test-results`** — poll for async run results after receiving the `runId`
142
+ - **`recommending-devops-tests`** — recommend which suites to run first before triggering execution
143
+ - **`managing-suite-assignments`** — assign or map a suite to a pipeline stage if it isn't linked yet
144
+ - **`configuring-quality-gate`** — configure a new gate or threshold