@salesforce/afv-skills 1.62.0 → 1.64.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.
- package/package.json +1 -1
- package/skills/agentforce-offline-experimentation-run/SKILL.md +253 -0
- package/skills/agentforce-offline-experimentation-run/scripts/build_report.py +796 -0
- package/skills/agentforce-offline-experimentation-run/scripts/resolve-token.sh +111 -0
- package/skills/agentforce-offline-experimentation-run/scripts/sfap_replay.py +1053 -0
- package/skills/automation-sandbox-post-copy-config-generate/SKILL.md +21 -11
- package/skills/automation-sandbox-post-copy-config-generate/assets/config_template.json +10 -0
- package/skills/automation-sandbox-post-copy-config-generate/assets/json_schema.json +33 -1
- package/skills/automation-sandbox-post-copy-config-generate/references/configuration_catalog.md +44 -1
- package/skills/automation-sandbox-post-copy-configure/SKILL.md +132 -124
- package/skills/automation-sandbox-post-copy-configure/references/flow_activation_path.md +151 -0
- package/skills/automation-sandbox-post-copy-configure/references/scheduled_apex_path.md +55 -9
- package/skills/consumer-goods-promotion-bo-api-deploy/SKILL.md +54 -107
- package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/payloads/copy.json +1 -1
- package/skills/consumer-goods-promotion-bo-api-deploy/references/conventions-and-payload-rules.md +82 -5
- package/skills/consumer-goods-promotion-bo-api-deploy/references/generate-and-wire.md +35 -2
- package/skills/consumer-goods-promotion-bo-api-deploy/references/preflight-and-seed-queries.md +149 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/references/smoke-and-verify.md +17 -1
- package/skills/dx-devops-conflict-resolve/SKILL.md +1 -5
- package/skills/dx-devops-pipeline-manage/SKILL.md +1 -5
- package/skills/dx-devops-project-manage/SKILL.md +1 -5
- package/skills/dx-devops-promote/SKILL.md +1 -5
- package/skills/dx-devops-request-status/SKILL.md +1 -5
- package/skills/dx-lifecycle-center/SKILL.md +120 -0
- package/skills/dx-lifecycle-center/examples/workflows.md +175 -0
- package/skills/dx-lifecycle-center/references/connect-api.md +123 -0
- package/skills/dx-lifecycle-center/references/connect-org.md +184 -0
- package/skills/dx-lifecycle-center/references/deploy.md +153 -0
- package/skills/dx-lifecycle-center/references/error-handling.md +21 -0
- package/skills/dx-lifecycle-center/references/hub-org.md +37 -0
- package/skills/dx-lifecycle-center/references/list-orgs.md +99 -0
- package/skills/dx-lifecycle-center/references/request-body.md +75 -0
- package/skills/dx-lifecycle-center/references/troubleshooting.md +31 -0
- package/skills/dx-lifecycle-center/scripts/poll-deploy-status.sh +200 -0
- package/skills/dx-lifecycle-center/scripts/resolve-environment.sh +120 -0
- package/skills/dx-org-devhub-configure/SKILL.md +1 -3
- package/skills/dx-org-shape-manage/SKILL.md +1 -5
- package/skills/dx-org-snapshot-manage/SKILL.md +1 -3
- package/skills/education-cloud-academic-calendar-generate/SKILL.md +1 -3
- package/skills/education-cloud-course-catalog-migrate/SKILL.md +1 -3
- package/skills/education-cloud-domain-configure/SKILL.md +1 -3
- package/skills/education-cloud-multi-campus-configure/SKILL.md +1 -3
- package/skills/education-cloud-student-recruitment-agent-configure/SKILL.md +1 -5
- package/skills/experience-ui-bundle-2gp-deploy/SKILL.md +1 -3
- package/skills/experience-ui-bundle-features-generate/SKILL.md +1 -5
- package/skills/experience-ui-bundle-mfa-configure/SKILL.md +1 -3
- package/skills/field-service-data-capture-migrate/SKILL.md +1 -3
- package/skills/insurance-brokerage-agency-billing-configure/SKILL.md +1 -3
- package/skills/marketing-message-test/SKILL.md +1 -3
- package/skills/nonprofit-fundraising-configure/SKILL.md +240 -0
- package/skills/nonprofit-fundraising-configure/references/gotchas.md +26 -0
- package/skills/nonprofit-fundraising-configure/references/mcp-invocation.md +678 -0
- package/skills/nonprofit-fundraising-configure/references/permission-targeting.md +35 -0
- package/skills/nonprofit-volunteer-management-model-get/SKILL.md +166 -0
- package/skills/nonprofit-volunteer-management-model-get/references/entities.md +315 -0
- package/skills/nonprofit-volunteer-management-model-get/references/relationships.md +175 -0
- package/skills/nonprofit-volunteer-management-model-get/references/themes.md +143 -0
- package/skills/nonprofit-volunteer-management-records-create/SKILL.md +121 -0
- package/skills/nonprofit-volunteer-management-records-create/references/field-guide.md +284 -0
- package/skills/nonprofit-volunteer-management-records-create/references/mcp-invocation.md +248 -0
- package/skills/nonprofit-volunteer-management-records-create/references/review-format.md +140 -0
- package/skills/nonprofit-volunteer-management-records-create/scripts/expand-series.py +632 -0
- package/skills/nonprofit-volunteer-management-records-create/scripts/render-review-table.py +419 -0
- package/skills/nonprofit-volunteer-management-records-create/scripts/tests/test_expand_series.py +690 -0
- package/skills/nonprofit-volunteer-management-records-create/scripts/tests/test_render_review_table.py +421 -0
- package/skills/nonprofit-volunteer-management-structure-generate/SKILL.md +119 -0
- package/skills/nonprofit-volunteer-management-structure-generate/references/configuration-decisions.md +159 -0
- package/skills/nonprofit-volunteer-management-structure-generate/references/discovery-interview.md +137 -0
- package/skills/nonprofit-volunteer-management-structure-generate/references/edge-cases.md +48 -0
- package/skills/nonprofit-volunteer-management-structure-generate/references/mcp-invocation.md +75 -0
- package/skills/nonprofit-volunteer-management-structure-generate/references/plan-output.md +141 -0
- package/skills/platform-custom-field-generate/SKILL.md +1 -0
- package/skills/platform-custom-field-generate/references/advanced-picklists.md +5 -5
- package/skills/platform-custom-metadata-type-generate/SKILL.md +3 -0
- package/skills/platform-custom-object-generate/SKILL.md +4 -0
- package/skills/platform-custom-setting-generate/SKILL.md +3 -0
- package/skills/platform-datamask-run/SKILL.md +1 -5
- package/skills/platform-permission-set-generate/SKILL.md +3 -0
- package/skills/platform-salesforce-connect-adapter-generate/SKILL.md +1 -3
- package/skills/platform-sandbox-configure/SKILL.md +1 -3
- package/skills/platform-value-set-generate/SKILL.md +3 -0
- package/skills/sales-call-scoring-configure/SKILL.md +1 -5
- package/skills/service-agentforce-channel-configure/SKILL.md +1 -3
- package/skills/service-agentforce-human-escalation-configure/SKILL.md +1 -3
- package/skills/service-catalog-template-coordinate/SKILL.md +1 -3
- package/skills/service-concierge-portal-generate/SKILL.md +1 -3
- package/skills/service-email-to-case-configure/SKILL.md +1 -5
- package/skills/service-itsm-agentic-setup-agent-runtime-access-assign/SKILL.md +1 -3
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +1 -3
- package/skills/service-itsm-agentic-setup-agentforce-studio-configure/SKILL.md +1 -3
- package/skills/service-itsm-agentic-setup-agentforce-studio-validate/SKILL.md +1 -3
- package/skills/service-itsm-agentic-setup-cmdb-access-assign/SKILL.md +1 -3
- package/skills/service-itsm-agentic-setup-cmdb-bundle-deploy/SKILL.md +1 -5
- package/skills/service-itsm-agentic-setup-cmdb-configure/SKILL.md +1 -3
- package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +1 -3
- package/skills/service-itsm-agentic-setup-cmdb-discovery-configure/SKILL.md +1 -3
- package/skills/service-itsm-agentic-setup-employee-agent-configure/SKILL.md +1 -3
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/SKILL.md +1 -3
- package/skills/service-itsm-agentic-setup-incident-management/SKILL.md +1 -0
- package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +1 -0
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/SKILL.md +1 -3
- package/skills/service-itsm-agentic-setup-uel-user-create/SKILL.md +1 -9
- package/skills/service-itsm-incident-mgmt-configure/SKILL.md +1 -5
- package/skills/service-itsm-incident-priority-configure/SKILL.md +1 -3
- package/skills/service-itsm-slack-itservice-configure/SKILL.md +1 -3
- package/skills/service-itsm-swarming-configure/SKILL.md +1 -3
- package/skills/service-itsm-teams-configure/SKILL.md +1 -3
- package/skills/service-itsm-teams-debug/SKILL.md +1 -3
- package/skills/service-itsm-teams-employee-agent-configure/SKILL.md +1 -3
- package/skills/service-itsm-teams-itdesk-configure/SKILL.md +1 -3
- package/skills/service-itsm-teams-itservice-configure/SKILL.md +1 -3
- package/skills/service-native-voice-recording-transcription-configure/SKILL.md +1 -3
- package/skills/service-omni-agent-users-create/SKILL.md +1 -3
- package/skills/service-omni-agent-work-sharing-configure/SKILL.md +1 -3
- package/skills/service-omni-attribute-routing-configure/SKILL.md +1 -3
- package/skills/service-omni-base-settings-configure/SKILL.md +1 -3
- package/skills/service-omni-channel-inventory-analyze/SKILL.md +1 -3
- package/skills/service-omni-channel-limits-analyze/SKILL.md +1 -3
- package/skills/service-omni-channel-setup-coordinate/SKILL.md +1 -3
- package/skills/service-omni-command-center-analyze/SKILL.md +1 -3
- package/skills/service-omni-command-center-configure/SKILL.md +1 -3
- package/skills/service-omni-permission-set-assign/SKILL.md +1 -3
- package/skills/service-omni-presence-status-deploy/SKILL.md +1 -3
- package/skills/service-omni-presence-user-config-deploy/SKILL.md +1 -3
- package/skills/service-omni-queue-deploy/SKILL.md +1 -3
- package/skills/service-omni-queue-members-assign/SKILL.md +1 -3
- package/skills/service-omni-queue-routing-config-deploy/SKILL.md +1 -3
- package/skills/service-omni-routing-flow-deploy/SKILL.md +1 -3
- package/skills/service-omni-service-channel-configure/SKILL.md +1 -3
- package/skills/service-omni-sidebar-configure/SKILL.md +1 -3
- package/skills/service-omni-skills-based-routing-configure/SKILL.md +1 -3
- package/skills/service-omni-supervisor-config-deploy/SKILL.md +1 -3
- package/skills/service-omni-supervisor-permset-assign/SKILL.md +1 -3
- package/skills/service-omni-supervisor-surface-deploy/SKILL.md +1 -3
- package/skills/service-omni-supervisor-users-create/SKILL.md +1 -3
- package/skills/service-omni-work-skill-routing-configure/SKILL.md +1 -3
- package/skills/field-service-setup-orchestrator-get/SKILL.md +0 -47
- package/skills/tableau-next-asset-create/README.md +0 -65
package/skills/consumer-goods-promotion-bo-api-deploy/references/conventions-and-payload-rules.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Conventions & payload rules (Promotion BO API)
|
|
2
2
|
|
|
3
|
-
Load-bearing conventions and the
|
|
3
|
+
Load-bearing conventions and the nine cross-workflow payload rules the
|
|
4
4
|
`BO_API_Step_Input_Structure__c` schema alone cannot express. The main
|
|
5
5
|
`SKILL.md` references this file from Phase 5b (registering input paths) and
|
|
6
6
|
Phase 6 (composing/validating smoke payloads).
|
|
@@ -33,8 +33,8 @@ subscriber orgs, or the dev-package prefix).
|
|
|
33
33
|
| `PromotionTemplate` | `<prefix>__Promotion_Template__c` | `Name = <val> AND <prefix>__Sales_Org__c = <sales-org>` |
|
|
34
34
|
| `Tactics[*].TacticTemplate` | `<prefix>__Tactic_Template__c` | `Name = <val> AND <prefix>__Sales_Org__c = <sales-org>` (and linked to the chosen PromotionTemplate via `<prefix>__Promotion_Template_Tactic_Template__c`) |
|
|
35
35
|
| `AnchorAccount` | `Account` | `<prefix>__ExternalId__c = <val> AND <prefix>__Sales_Org__c = <sales-org>` |
|
|
36
|
-
| `ProductFilter.Criteria.Brand[*]`, `.Category[*]`, `.Subcategory[*]`, `.Flavor[*]`, `.Package[*]` | `<prefix>__Product_Attribute__c` (or Category equivalents) |
|
|
37
|
-
| `ProductFilter.{Included,Excluded}Products[*]` | `Product2` |
|
|
36
|
+
| `ProductFilter.Criteria.Brand[*]`, `.Category[*]`, `.Subcategory[*]`, `.Flavor[*]`, `.Package[*]` | `<prefix>__Product_Attribute__c` (or Category equivalents) | `<prefix>__Consumer_Goods_External_Product_Id__c = <val> AND <prefix>__Sales_Org__c = <sales-org>` — resolve against external id, NOT `Name`/label (see R3b). |
|
|
37
|
+
| `ProductFilter.{Included,Excluded}Products[*]` | `Product2` | `<prefix>__Consumer_Goods_External_Product_Id__c = <val> AND <prefix>__Sales_Org__c = <sales-org>` |
|
|
38
38
|
| `PromotionAccountSet` / `AnchorAccountSet` | `<prefix>__Account_Set__c` | `Name = <val> AND <prefix>__Sales_Org__c = <sales-org>` |
|
|
39
39
|
|
|
40
40
|
Fail-fast — before any REST call — if any user-supplied reference does not
|
|
@@ -81,7 +81,7 @@ required columns).
|
|
|
81
81
|
## Promotion payload — cross-workflow rules the schema cannot express
|
|
82
82
|
|
|
83
83
|
The `BO_API_Step_Input_Structure__c` contract declares WHICH keys the workflow
|
|
84
|
-
accepts and which are `Required__c=true`, but
|
|
84
|
+
accepts and which are `Required__c=true`, but nine additional constraints govern
|
|
85
85
|
whether a create/update/copy/derive call will actually succeed. Enforce them
|
|
86
86
|
BEFORE the REST call — otherwise the request 202s, then dies asynchronously
|
|
87
87
|
inside a workflow step with a `BO_API_Transaction_Log__c.Status__c = 'Error'`.
|
|
@@ -124,10 +124,45 @@ translate. Sending a Product2 field API name (e.g. `<prefix>__Criterion_1_Produc
|
|
|
124
124
|
as a key fails schema validation with `"Properties other than those defined were
|
|
125
125
|
not expected at #.ProductFilter.Criteria.<key>"`.
|
|
126
126
|
|
|
127
|
+
Two placement/identifier constraints the schema alone cannot express:
|
|
128
|
+
|
|
129
|
+
**R3a. `ProductFilter` is a top-level promotion field, NOT nested under `Tactics[]`.**
|
|
130
|
+
Every entry in `promotions[]` may carry a `ProductFilter` sibling to
|
|
131
|
+
`Slogan`/`DateFrom`/`Tactics`. Nesting the block under `Tactics[i]` is
|
|
132
|
+
schema-valid at ingest but fails downstream with
|
|
133
|
+
`"You must select at least one Category to the Promotion"` — the same error a
|
|
134
|
+
missing block produces. Trial-and-error empirically discovers this;
|
|
135
|
+
document once here so the skill never emits the wrong shape:
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
"promotions": [{
|
|
139
|
+
"PromotionTemplate": "Customer Promotion",
|
|
140
|
+
"DateFrom": "2026-08-01",
|
|
141
|
+
"DateThru": "2026-08-31",
|
|
142
|
+
"Slogan": "...",
|
|
143
|
+
"ProductFilter": {
|
|
144
|
+
"Criteria": { "Category": ["<external-id>"] }
|
|
145
|
+
},
|
|
146
|
+
"Tactics": [ /* no ProductFilter here */ ]
|
|
147
|
+
}]
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**R3b. Criteria values are `<prefix>__Consumer_Goods_External_Product_Id__c` external ids, NOT `Name`/label.**
|
|
151
|
+
Every value inside `ProductFilter.Criteria.<level>[]` is resolved against the
|
|
152
|
+
category/attribute record's *external id* — the packaged
|
|
153
|
+
`<prefix>__Consumer_Goods_External_Product_Id__c` field — NOT the display
|
|
154
|
+
`Name` or label. Passing a Name (e.g. `"Chips (Canada Food)"`) yields
|
|
155
|
+
`TransformationError: Could not find Products: <Name>` at ingest, and the
|
|
156
|
+
misleading message suggests the underlying products are inactive when the real
|
|
157
|
+
defect is the identifier field. The correct value for the same record is its
|
|
158
|
+
external id (e.g. `Chips_Canada_Food`). Resolve every criteria value against
|
|
159
|
+
external ids in the sales org before emitting the payload; if the user typed a
|
|
160
|
+
Name, offer the external-id match(es) and ask to confirm.
|
|
161
|
+
|
|
127
162
|
```json
|
|
128
163
|
"ProductFilter": {
|
|
129
164
|
"Criteria": {
|
|
130
|
-
"Category": ["
|
|
165
|
+
"Category": ["Chips_Canada_Food"],
|
|
131
166
|
"Brand": ["YetiBar"]
|
|
132
167
|
}
|
|
133
168
|
}
|
|
@@ -216,6 +251,12 @@ then layer the Apex-only preconditions:
|
|
|
216
251
|
**Copy:**
|
|
217
252
|
- Schema-required: `.Id` (source promotion).
|
|
218
253
|
- Apex-only: source promotion's template must have `Is_Copyable__c = true`; template `Promotion_Type__c` must equal `'Promotion'`; if template `Anchor_Type__c = 'Customer'`, `.AnchorAccount` must resolve in the sales org; if `'CustomerSet'`, `.AnchorAccountSet` must resolve.
|
|
254
|
+
- Apex-only: **the running `User.Sales_Org__c` MUST equal the source PromotionTemplate's `Sales_Org__c`.** `Promotion2BoApiCoreCommon.loadPromotion` (invoked with `Operation.Copy`; the legacy shim `PromotionBoApiCopyCoreWorkflowSteps.loadPromotionBOForCopy2` delegates into the same method) throws `TransformationError: The User and the Promotion Template must have the same Sales org` when they differ, with no hint that the running user is the fix path. Create/update do not enforce this specific check, but they still resolve the operating sales org from the running user's `Sales_Org__c` via `SalesOrganizationUtil.getUserSalesOrganizationName` — a blank or mismatched value there fails every workflow, just less loudly (with `SOU0003` or misleading "not found" errors). SKILL.md Phase 1 step 7 gates the whole invocation on this match before any workflow runs; also verify at Phase 6 immediately before every ingest in case the user's `Sales_Org__c` drifted between phases. Zero-cost SOQL:
|
|
255
|
+
```sql
|
|
256
|
+
SELECT Id, Username, ${PREFIX_UNDER}Sales_Org__c FROM User WHERE Username = '<running-user-name>' LIMIT 1
|
|
257
|
+
```
|
|
258
|
+
If it does not match, do not silently mutate the user record — refuse and print the fix options.
|
|
259
|
+
- **Copy ignores per-child input values on `Tactics[]`.** On `copy`, the framework sources per-child values from the source record's children — the payload's `Tactics[i].<field>` is accepted by the schema but has no effect on the cloned children. Custom step `outputWrites` still fire, but their input values come from the source child, not the copy payload. Only top-level promotion fields (e.g. `Slogan`) propagate from the copy payload. This is intentional and documented; the skill's confirm banner in SKILL.md Phase 5.5 must call this out so users do not expect a `create`-style customization to apply.
|
|
219
260
|
|
|
220
261
|
**Derive:**
|
|
221
262
|
- Schema-required: `.Id`, `.PromotionTemplate`, `.AnchorAccount` — all at the derive input root (`currentInput`), not nested (`PBACWS_REQUIRED_PROP_MISSING` fires against `Path__c` verbatim).
|
|
@@ -266,6 +307,42 @@ SELECT Id, Name, <prefix>__Promotion_Type__c
|
|
|
266
307
|
Reject any row where `Promotion_Type__c != 'Promotion'` with:
|
|
267
308
|
`"Promotion template <name> has Promotion_Type__c='<type>'; this workflow only supports templates with Promotion_Type__c='Promotion'. Sellable Promotions belong to the retail path."`
|
|
268
309
|
|
|
310
|
+
### R9. Running user must hold `Product_Category_Share__c` ReadWrite on every referenced category
|
|
311
|
+
|
|
312
|
+
`Promotion2BoApiCoreCommon.setPromotionAnchor` (invoked by every workflow that
|
|
313
|
+
resolves a promotion anchor) calls `ProductCategoryShareService.getCategoryAccessBySalesOrgUserAnchorCategory`
|
|
314
|
+
and hard-fails when the running user does not have a `<prefix>__Product_Category_Share__c`
|
|
315
|
+
row with `<prefix>__Access_Level__c = 'ReadWrite'` for each category the payload
|
|
316
|
+
references — either via the promotion template's anchor category, via
|
|
317
|
+
`ProductFilter.Criteria.Category`, or via `Included/ExcludedProducts` whose
|
|
318
|
+
category rolls up to a share-guarded category in the sales org. The error surfaces
|
|
319
|
+
at ingest as `Access Denied` / `TransformationError: You do not have access to
|
|
320
|
+
the category '<name>'` and does not identify the missing share row.
|
|
321
|
+
|
|
322
|
+
Fail-fast before any REST call:
|
|
323
|
+
|
|
324
|
+
`<userId>` comes from `sf org display --target-org <alias> --json` (`result.userId`); `<id1>`, `<id2>`, … are the category record ids resolved from the payload's criteria values in-sales-org.
|
|
325
|
+
|
|
326
|
+
```sql
|
|
327
|
+
SELECT <prefix>__Category__c, <prefix>__Access_Level__c
|
|
328
|
+
FROM <prefix>__Product_Category_Share__c
|
|
329
|
+
WHERE <prefix>__Sales_Org__c = '<salesOrg>'
|
|
330
|
+
AND <prefix>__User__c = '<userId>'
|
|
331
|
+
AND <prefix>__Category__c IN ('<id1>','<id2>')
|
|
332
|
+
AND <prefix>__Access_Level__c = 'ReadWrite'
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
`categoryIds` is the union of:
|
|
336
|
+
1. The chosen `PromotionTemplate`'s `<prefix>__Anchor_Category__c` (if any).
|
|
337
|
+
2. Every category external id in the payload's `ProductFilter.Criteria.Category`, resolved to `<prefix>__Product_Attribute__c.Id` (or the tenant's Category equivalent) in the sales org.
|
|
338
|
+
|
|
339
|
+
Any missing row → stop and print:
|
|
340
|
+
`"Running user <username> lacks ReadWrite Product_Category_Share on category <name> (<external-id>) in sales org <salesOrg>. Grant a Product_Category_Share__c row with Access_Level__c='ReadWrite', or re-run as a user who already has this access. Do not proceed."`
|
|
341
|
+
|
|
342
|
+
Never silently insert share rows on behalf of the running user — that mutates
|
|
343
|
+
sharing configuration invisibly and can leak read/write access to other
|
|
344
|
+
categories via the same user in future runs.
|
|
345
|
+
|
|
269
346
|
## Wire-format quirks
|
|
270
347
|
|
|
271
348
|
- `POST /promotions/initialize` deserializes lowercase `salesorg` / `nrofitems`. Always emit lowercase.
|
|
@@ -50,6 +50,20 @@ Both phases run only on a green Phase 4 and a confirmed Phase 5 interview.
|
|
|
50
50
|
<stepName>.cls-meta.xml
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
+
**Deploy-directory hygiene — clean stale `.cls` files before writing the new
|
|
54
|
+
step.** When the skill is invoked more than once against the same working
|
|
55
|
+
tree (a second custom step, an interview re-run), any prior step's `.cls` /
|
|
56
|
+
`.cls-meta.xml` left behind in `force-app/main/default/classes/` is picked
|
|
57
|
+
up by `sf project deploy start` in step 5 below. If that stale file is no
|
|
58
|
+
longer known to the source-tracking manifest, MDAPI evaluates the deploy
|
|
59
|
+
with `rollbackOnError: true` and rolls back the *entire* batch — including
|
|
60
|
+
the new class — while the CLI still surfaces `"created": true` for the
|
|
61
|
+
intended component. The user sees an apparent success; the class is not
|
|
62
|
+
actually in the org. Before writing the new step, delete every
|
|
63
|
+
`*.cls`/`*.cls-meta.xml` under `./.promotion-bo-api-deploy/force-app/main/default/classes/`
|
|
64
|
+
that is not the class about to be generated. Do NOT wipe `setup-data/`
|
|
65
|
+
(Phase 3a's retrieved read-only static resource lives there).
|
|
66
|
+
|
|
53
67
|
`sfdx-project.json`:
|
|
54
68
|
```json
|
|
55
69
|
{
|
|
@@ -188,6 +202,15 @@ for (String wf : workflows) {
|
|
|
188
202
|
// pre-check. SIS uses RecordType to declare the JSON type (String, Array,
|
|
189
203
|
// Boolean, Number, Object) — a missing RecordTypeId defaults to Array,
|
|
190
204
|
// which produces "Expected List<Object>" at runtime.
|
|
205
|
+
//
|
|
206
|
+
// `Required__c` MUST be set explicitly. The field defaults to `true` at
|
|
207
|
+
// the platform level, so omitting it silently promotes every optional
|
|
208
|
+
// input path to mandatory org-wide for that workflow — every subsequent
|
|
209
|
+
// ingest of a promotion that does not carry the path fails with
|
|
210
|
+
// `Required property missing at #.<path>`. Default the SIS insert to
|
|
211
|
+
// `false`; only set `true` for paths the interview explicitly flagged
|
|
212
|
+
// as required (interview field `inputPathRequired`, defaults to `false`).
|
|
213
|
+
Boolean inputPathRequired = <inputPathRequired>; // interview answer; defaults to false
|
|
191
214
|
Id sisRecordTypeId = [
|
|
192
215
|
SELECT Id FROM RecordType
|
|
193
216
|
WHERE SobjectType = '${PREFIX_UNDER}BO_API_Step_Input_Structure__c'
|
|
@@ -203,11 +226,21 @@ for (${PREFIX_DOT}BO_API_Step_Input_Structure__c s : [
|
|
|
203
226
|
}
|
|
204
227
|
List<${PREFIX_DOT}BO_API_Step_Input_Structure__c> sisRows =
|
|
205
228
|
new List<${PREFIX_DOT}BO_API_Step_Input_Structure__c>();
|
|
229
|
+
// `Path__c` carries a packaged validation rule requiring JSON-path form
|
|
230
|
+
// (leading `.` or `$`). Interview values from the user typically omit the
|
|
231
|
+
// leading dot (e.g. `Comment`); normalize before insert or the row rejects
|
|
232
|
+
// with `FIELD_CUSTOM_VALIDATION_EXCEPTION: The Path must represent a
|
|
233
|
+
// valid JSON path.: [${PREFIX_UNDER}Path__c]`. Existing-path comparison
|
|
234
|
+
// also uses the normalized value so a re-run does not double-insert.
|
|
206
235
|
for (String inputPath : inputPaths) {
|
|
207
|
-
|
|
236
|
+
String normalizedPath = (inputPath.startsWith('.') || inputPath.startsWith('$'))
|
|
237
|
+
? inputPath
|
|
238
|
+
: '.' + inputPath;
|
|
239
|
+
if (existingPaths.contains(normalizedPath)) continue;
|
|
208
240
|
sisRows.add(new ${PREFIX_DOT}BO_API_Step_Input_Structure__c(
|
|
209
241
|
${PREFIX_DOT}BO_API_Workflow_Step__c = step.Id,
|
|
210
|
-
${PREFIX_DOT}Path__c =
|
|
242
|
+
${PREFIX_DOT}Path__c = normalizedPath,
|
|
243
|
+
${PREFIX_DOT}Required__c = inputPathRequired,
|
|
211
244
|
RecordTypeId = sisRecordTypeId
|
|
212
245
|
));
|
|
213
246
|
}
|
package/skills/consumer-goods-promotion-bo-api-deploy/references/preflight-and-seed-queries.md
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Preflight + seed queries (Phases 1–3b)
|
|
2
|
+
|
|
3
|
+
Load-bearing SOQL and shell recipes that `SKILL.md` Phases 1–3b hand off to.
|
|
4
|
+
`PREFIX_DOT` / `PREFIX_UNDER` / `URL_NS` come from `SKILL.md` "Find the
|
|
5
|
+
namespace first". Every query is **sales-org-scoped** where the underlying
|
|
6
|
+
object is partitioned.
|
|
7
|
+
|
|
8
|
+
## Phase 1 — Preflight queries
|
|
9
|
+
|
|
10
|
+
### Step 4: TPM entitlement (Permission Set License)
|
|
11
|
+
|
|
12
|
+
TPM is licensed via the `CGCRetailAndTPMMgmtPsl` PSL (no `TPM App`
|
|
13
|
+
UserLicense):
|
|
14
|
+
|
|
15
|
+
```sql
|
|
16
|
+
SELECT Id FROM PermissionSetLicenseAssign
|
|
17
|
+
WHERE Assignee.Username = '<running-user-name>'
|
|
18
|
+
AND PermissionSetLicense.DeveloperName = 'CGCRetailAndTPMMgmtPsl'
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Empty + `OrganizationType = 'Developer Edition'` or `IsSandbox = true` →
|
|
22
|
+
**warn** (the permset gate below is the real check); any other org shape +
|
|
23
|
+
empty → **stop**.
|
|
24
|
+
|
|
25
|
+
### Step 5: Running-user permission set (TPM Admin persona)
|
|
26
|
+
|
|
27
|
+
Need a permset granting the *TPM Master Data Admin* persona. The shipped name
|
|
28
|
+
is `TPM_Master_Data_Admin` (bare, non-namespaced), but customers frequently
|
|
29
|
+
clone it; treat a miss as "ask", not "fail":
|
|
30
|
+
|
|
31
|
+
```sql
|
|
32
|
+
SELECT PermissionSet.Name, PermissionSet.Label FROM PermissionSetAssignment
|
|
33
|
+
WHERE Assignee.Username = '<running-user-name>'
|
|
34
|
+
AND (PermissionSet.Name = 'TPM_Master_Data_Admin'
|
|
35
|
+
OR PermissionSet.Label LIKE '%TPM%Master Data Admin%')
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Match → proceed. No match → offer
|
|
39
|
+
`sf org assign permset --name TPM_Master_Data_Admin --target-org <alias>` AND
|
|
40
|
+
ask if the user holds an equivalent (cloned/renamed) permset; wait for
|
|
41
|
+
confirmation or assignment, then re-query. Proceed only once admin access is
|
|
42
|
+
confirmed.
|
|
43
|
+
|
|
44
|
+
### Step 7: Running user's `Sales_Org__c` matches `<salesOrg>`
|
|
45
|
+
|
|
46
|
+
```sql
|
|
47
|
+
SELECT Id, Username, ${PREFIX_UNDER}Sales_Org__c FROM User WHERE Username = '<running-user-name>'
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Blank or `!= '<salesOrg>'` → stop; fix on the user record (confirm before
|
|
51
|
+
mutating). This gate is R6 of `conventions-and-payload-rules.md` — blank
|
|
52
|
+
throws `SOU0003`, mismatch surfaces as "not found" (create/update) or
|
|
53
|
+
`TransformationError` (copy). Category access is preflighted in Phase 6 per
|
|
54
|
+
R9.
|
|
55
|
+
|
|
56
|
+
## Phase 2 — Verify BO API framework state
|
|
57
|
+
|
|
58
|
+
Read-only. All three counts MUST be scoped to `<salesOrg>` — the framework
|
|
59
|
+
rows are sales-org-partitioned.
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# 1. Workflow rows for this sales org (expect 4: create/update/copy/derive)
|
|
63
|
+
sf data query --target-org <alias> --json --query "
|
|
64
|
+
SELECT Name FROM ${PREFIX_UNDER}BO_API_Workflow__c
|
|
65
|
+
WHERE ${PREFIX_UNDER}BO_API__r.Name = 'Promotion'
|
|
66
|
+
AND ${PREFIX_UNDER}BO_API__r.${PREFIX_UNDER}Sales_Org__c = '<salesOrg>'"
|
|
67
|
+
|
|
68
|
+
# 2. Step rows for this sales org
|
|
69
|
+
sf data query --target-org <alias> --json --query "
|
|
70
|
+
SELECT COUNT(Id) FROM ${PREFIX_UNDER}BO_API_Workflow_Step__c
|
|
71
|
+
WHERE ${PREFIX_UNDER}Sales_Org__c = '<salesOrg>'"
|
|
72
|
+
|
|
73
|
+
# 3. Junction rows whose parent workflow belongs to a Promotion BO API for this sales org
|
|
74
|
+
sf data query --target-org <alias> --json --query "
|
|
75
|
+
SELECT COUNT(Id) FROM ${PREFIX_UNDER}BO_API_Workflow_Workflow_Step__c
|
|
76
|
+
WHERE ${PREFIX_UNDER}BO_API_Workflow__r.${PREFIX_UNDER}BO_API__r.Name = 'Promotion'
|
|
77
|
+
AND ${PREFIX_UNDER}BO_API_Workflow__r.${PREFIX_UNDER}BO_API__r.${PREFIX_UNDER}Sales_Org__c = '<salesOrg>'"
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Outcome routing:
|
|
81
|
+
- Zero workflow rows → fresh for this sales org, Phase 3 will seed.
|
|
82
|
+
- Full state (4 workflow rows `create/update/copy/derive`; >0 step + junction
|
|
83
|
+
rows) → Phase 3 is a no-op for this sales org (still run for idempotency;
|
|
84
|
+
3a shows zero net-new).
|
|
85
|
+
- Partial state → **error**; stop, report which rows are missing. A human
|
|
86
|
+
inspects first.
|
|
87
|
+
|
|
88
|
+
## Phase 3a — Retrieve the packaged seed
|
|
89
|
+
|
|
90
|
+
Fetch the `TPMSetupData` static resource into a dedicated `setup-data/`
|
|
91
|
+
subproject (keeps the read-only managed resource out of the Phase-5a deploy
|
|
92
|
+
tree at `./.promotion-bo-api-deploy/force-app`).
|
|
93
|
+
|
|
94
|
+
1. Locate the resource:
|
|
95
|
+
```bash
|
|
96
|
+
sf data query --target-org <alias> --json --query "
|
|
97
|
+
SELECT Id, Name, NamespacePrefix, SystemModStamp, BodyLength
|
|
98
|
+
FROM StaticResource WHERE Name = 'TPMSetupData'"
|
|
99
|
+
```
|
|
100
|
+
Zero rows → stop ("TPMSetupData static resource not found — is the CGCloud
|
|
101
|
+
package installed?"). Multiple rows → prefer the one whose
|
|
102
|
+
`NamespacePrefix` matches Phase 1; if prefixes disagree, stop and ask.
|
|
103
|
+
2. Retrieve into the dedicated subproject:
|
|
104
|
+
```bash
|
|
105
|
+
mkdir -p ./.promotion-bo-api-deploy/setup-data/force-app/main/default
|
|
106
|
+
printf '{ "packageDirectories": [{ "path": "force-app", "default": true }], "sourceApiVersion": "60.0" }' \
|
|
107
|
+
> ./.promotion-bo-api-deploy/setup-data/sfdx-project.json
|
|
108
|
+
( cd ./.promotion-bo-api-deploy/setup-data && sf project retrieve start \
|
|
109
|
+
--metadata "StaticResource:${PREFIX_UNDER}TPMSetupData" --target-org <alias> --json )
|
|
110
|
+
```
|
|
111
|
+
Non-success → stop, print `result` errors. (`sf project retrieve` works
|
|
112
|
+
cross-platform; no `unzip` needed.)
|
|
113
|
+
3. SFDX expands the zip to
|
|
114
|
+
`./.promotion-bo-api-deploy/setup-data/force-app/main/default/staticresources/${PREFIX_UNDER}TPMSetupData/BOApi/`.
|
|
115
|
+
Expected 8 CSVs — `0_BO_API__c.csv`, `0_BO_API_Entity__c.csv`,
|
|
116
|
+
`0_BO_API_Output_Entity__c.csv`, `0_BO_API_Workflow__c.csv`,
|
|
117
|
+
`0_BO_API_Workflow_Entity__c.csv`, `0_BO_API_Workflow_Step__c.csv`,
|
|
118
|
+
`0_BO_API_Workflow_Workflow_Step__c.csv`,
|
|
119
|
+
`0_BO_API_Step_Input_Structure__c.csv` — plus `import.json`. Any missing →
|
|
120
|
+
stop, print the delta.
|
|
121
|
+
4. Confirm each target sObject exists:
|
|
122
|
+
`sf sobject describe --sobject '${PREFIX_UNDER}BO_API_Workflow__c' --target-org <alias> > /dev/null`
|
|
123
|
+
(etc.). Any describe failure → stop (package partially installed).
|
|
124
|
+
|
|
125
|
+
## Phase 3b — Poll the batch chain
|
|
126
|
+
|
|
127
|
+
`GenericDemoSetupDataBatch` self-chains via `finish()`, so poll by class (not
|
|
128
|
+
by a single job id):
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
sf data query --target-org <alias> --json --query "
|
|
132
|
+
SELECT COUNT() FROM AsyncApexJob
|
|
133
|
+
WHERE ApexClass.Name = 'GenericDemoSetupDataBatch'
|
|
134
|
+
AND CreatedDate >= ${PHASE3_START}
|
|
135
|
+
AND Status NOT IN ('Completed','Failed','Aborted')"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Sleep 5s between polls; break when count is zero for **two consecutive** polls
|
|
139
|
+
(covers the gap between a parent's `finish()` and a child's `AsyncApexJob` row
|
|
140
|
+
appearing).
|
|
141
|
+
|
|
142
|
+
Final check — every child succeeded:
|
|
143
|
+
|
|
144
|
+
```sql
|
|
145
|
+
SELECT Id, Status, NumberOfErrors, ExtendedStatus FROM AsyncApexJob
|
|
146
|
+
WHERE ApexClass.Name = 'GenericDemoSetupDataBatch' AND CreatedDate >= ${PHASE3_START}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Any `Failed`/`Aborted`/`NumberOfErrors > 0` → stop, print `ExtendedStatus`.
|
|
@@ -20,7 +20,7 @@ accepted paths — read them, don't guess. See
|
|
|
20
20
|
for the canonical SOQL; run it once per invoked workflow (`create`, `update`,
|
|
21
21
|
`copy`), producing three contracts.
|
|
22
22
|
|
|
23
|
-
**Additionally**, apply the
|
|
23
|
+
**Additionally**, apply the nine cross-workflow rules (R1..R9) in
|
|
24
24
|
`references/conventions-and-payload-rules.md` ("Promotion payload — cross-workflow
|
|
25
25
|
rules"). These are the constraints the schema alone cannot express and every one
|
|
26
26
|
has caused a smoke-test failure historically. Summary of what the skill MUST do
|
|
@@ -34,6 +34,7 @@ on top of the derived contract:
|
|
|
34
34
|
- **R6** — for `copy`, derive requireds the same way, then layer the Apex-only preconditions (`Is_Copyable__c`, template type, anchor).
|
|
35
35
|
- **R7** — reject any `Tactics[*].TacticTemplate` not linked to the chosen `PromotionTemplate` in this sales org.
|
|
36
36
|
- **R8** — reject any `PromotionTemplate` whose `Promotion_Type__c != 'Promotion'` (fail-fast before ingest — otherwise it surfaces as a misleading `/productfilter` error).
|
|
37
|
+
- **R9** — verify running user holds `Product_Category_Share__c` with `Access_Level__c='ReadWrite'` for every category referenced by the payload (template anchor category + `ProductFilter.Criteria.Category`). Missing rows → stop; do not insert shares.
|
|
37
38
|
|
|
38
39
|
For each derived contract, compute:
|
|
39
40
|
- `requiredPaths` = union of `Path__c` where `Required__c = true`.
|
|
@@ -94,6 +95,21 @@ credential exposure (S1). Do **not** add `--json` to `sf api request rest` — t
|
|
|
94
95
|
raw stdout body is already JSON. `${URL_NS}` is the namespace segment from
|
|
95
96
|
Phase 1 (`/cgcloud` / `/cgcloud_dev` / empty); the endpoint is instance-relative.
|
|
96
97
|
|
|
98
|
+
**Smoke-time re-check of running user's `${PREFIX_UNDER}Sales_Org__c`.** Phase 1
|
|
99
|
+
step 7 gated the whole invocation on this, but Phase 6 can be minutes/hours later
|
|
100
|
+
and the user record may have drifted (a parallel admin edit, a session on a
|
|
101
|
+
different browser tab that re-ran with `--yes`). Re-run the same SOQL before the
|
|
102
|
+
first REST call in each of 6a/6b/6c:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
sf data query --target-org <alias> --json --query "
|
|
106
|
+
SELECT ${PREFIX_UNDER}Sales_Org__c FROM User WHERE Username = '<running-user-name>'
|
|
107
|
+
" > ./out/smoke/user-so-check.json
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
If the value is blank or `!= <salesOrg>`, stop with the same fix options as
|
|
111
|
+
Phase 1 step 7 — do NOT auto-mutate the user record.
|
|
112
|
+
|
|
97
113
|
```bash
|
|
98
114
|
BASE="/services/apexrest${URL_NS}/promotions"
|
|
99
115
|
```
|
|
@@ -15,11 +15,7 @@ metadata:
|
|
|
15
15
|
semver: ">=1.6"
|
|
16
16
|
- tool: ["sf"]
|
|
17
17
|
semver: ">=2.0.0"
|
|
18
|
-
accessCheck:
|
|
19
|
-
- type: "orgPref"
|
|
20
|
-
value: "ALMDevopsCorePref"
|
|
21
|
-
- type: "userPerm"
|
|
22
|
-
value: "UserHasDevOpsCore"
|
|
18
|
+
accessCheck: "(OrgPreferences.ALMDevopsCorePref) && (UserPermissions.UserHasDevOpsCore)"
|
|
23
19
|
---
|
|
24
20
|
|
|
25
21
|
# DevOps Center Conflict & Deploy-Failure Resolution
|
|
@@ -7,11 +7,7 @@ metadata:
|
|
|
7
7
|
minApiVersion: "58.0"
|
|
8
8
|
relatedSkills:
|
|
9
9
|
- "dx-devops-work-item-manage"
|
|
10
|
-
accessCheck:
|
|
11
|
-
- type: "orgPref"
|
|
12
|
-
value: "ALMDevopsCorePref"
|
|
13
|
-
- type: "userPerm"
|
|
14
|
-
value: "UserHasDevOpsCore"
|
|
10
|
+
accessCheck: "(OrgPreferences.ALMDevopsCorePref) && (UserPermissions.UserHasDevOpsCore)"
|
|
15
11
|
cliTools:
|
|
16
12
|
- tool: ["jq"]
|
|
17
13
|
semver: ">=1.6"
|
|
@@ -9,11 +9,7 @@ metadata:
|
|
|
9
9
|
- "dx-devops-pipeline-manage"
|
|
10
10
|
- "dx-devops-promote"
|
|
11
11
|
- "dx-devops-work-item-manage"
|
|
12
|
-
accessCheck:
|
|
13
|
-
- type: "orgPref"
|
|
14
|
-
value: "ALMDevopsCorePref"
|
|
15
|
-
- type: "userPerm"
|
|
16
|
-
value: "UserHasDevOpsCore"
|
|
12
|
+
accessCheck: "(OrgPreferences.ALMDevopsCorePref) && (UserPermissions.UserHasDevOpsCore)"
|
|
17
13
|
cliTools:
|
|
18
14
|
- tool: ["jq"]
|
|
19
15
|
semver: ">=1.6"
|
|
@@ -12,11 +12,7 @@ metadata:
|
|
|
12
12
|
semver: ">=1.6"
|
|
13
13
|
- tool: ["sf"]
|
|
14
14
|
semver: ">=2.0.0"
|
|
15
|
-
accessCheck:
|
|
16
|
-
- type: "orgPref"
|
|
17
|
-
value: "ALMDevopsCorePref"
|
|
18
|
-
- type: "userPerm"
|
|
19
|
-
value: "UserHasDevOpsCore"
|
|
15
|
+
accessCheck: "(OrgPreferences.ALMDevopsCorePref) && (UserPermissions.UserHasDevOpsCore)"
|
|
20
16
|
---
|
|
21
17
|
|
|
22
18
|
# DevOps Center Promotion
|
|
@@ -13,11 +13,7 @@ metadata:
|
|
|
13
13
|
semver: ">=1.6"
|
|
14
14
|
- tool: ["sf"]
|
|
15
15
|
semver: ">=2.0.0"
|
|
16
|
-
accessCheck:
|
|
17
|
-
- type: "orgPref"
|
|
18
|
-
value: "ALMDevopsCorePref"
|
|
19
|
-
- type: "userPerm"
|
|
20
|
-
value: "UserHasDevOpsCore"
|
|
16
|
+
accessCheck: "(OrgPreferences.ALMDevopsCorePref) && (UserPermissions.UserHasDevOpsCore)"
|
|
21
17
|
---
|
|
22
18
|
|
|
23
19
|
# DevOps Center Request Status
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dx-lifecycle-center
|
|
3
|
+
description: "Lifecycle Center for DX Inspector and Builder Central. Use this skill first for four jobs: (A) list the orgs connected to DX Inspector; (B) connect a new org (sandbox or scratch, production, OrgFarm) as a deploy target; (C) connect or check the Lifecycle Center org, also written LifecycleCenter org, lifecycle-center, ALMDevOpsCenterHub, DevOps Center hub, or Hub org; (D) deploy, validate, or quick-deploy components that already exist in the user's org to a connected org, and poll a simple-deploy requestId. TRIGGER on: show, list, or pick connected orgs or environments; connect, add, log in to, or repair an org; connect the Lifecycle Center org; deploy, validate, or push components to another org, URL, org id, alias, or environment name. Short asks like \"connect a new org\", \"which orgs can I deploy to\", or \"deploy to my sandbox\" match. These deploys move components from the connected source org to another org, not local project files."
|
|
4
|
+
metadata:
|
|
5
|
+
version: "1.0"
|
|
6
|
+
domains: ["Developer Experience"]
|
|
7
|
+
minApiVersion: "67.0"
|
|
8
|
+
cliTools:
|
|
9
|
+
- tool: ["jq"]
|
|
10
|
+
semver: ">=1.6"
|
|
11
|
+
- tool: ["sf"]
|
|
12
|
+
semver: ">=2.67.0"
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Lifecycle Center: Connect Orgs and Deploy Metadata
|
|
16
|
+
|
|
17
|
+
This skill manages which orgs a user can deploy to, and deploys to them. Everything runs from the **source org**: the org the user built in, where DX Inspector runs. All connections and environments are stored there.
|
|
18
|
+
|
|
19
|
+
## Operations
|
|
20
|
+
|
|
21
|
+
| Op | Name | What it does | Details |
|
|
22
|
+
|---|---|---|---|
|
|
23
|
+
| **A** | List orgs | Shows the orgs connected to DX Inspector (the deploy targets), or the current org's details. Also resolves a target the user names. | `references/list-orgs.md` |
|
|
24
|
+
| **B** | Connect an org | Connects a new sandbox or scratch, production, or OrgFarm org as a deploy target, or repairs a half-finished connection. The user signs in through a link. | `references/connect-org.md` |
|
|
25
|
+
| **C** | Lifecycle Center org | Connects, repairs, or checks the Lifecycle Center org (credential `ALMDevOpsCenterHub`). | `references/hub-org.md` |
|
|
26
|
+
| **D** | Deploy | Deploys, validates, or quick-deploys components from the source org to a connected target, then polls to the end. | `references/deploy.md` |
|
|
27
|
+
|
|
28
|
+
Connect (B) and deploy or quick deploy (D) change an org, so they wait for the user's confirmation first. Listing, status checks, validate runs, and polling do not change a target org.
|
|
29
|
+
|
|
30
|
+
## Key terms
|
|
31
|
+
|
|
32
|
+
| Term | Meaning |
|
|
33
|
+
|---|---|
|
|
34
|
+
| Source org | The org the user built in. Use the alias they name, else the default org from `sf org display --json`. Components must already exist in it. |
|
|
35
|
+
| DX Inspector environment | A `DevopsEnvironment` record in the source org with a Named Credential. The deploy targets are exactly these records. |
|
|
36
|
+
| Deploy target | An environment in state `selectable`. An `expired` or `unauthenticated` environment is not a target. |
|
|
37
|
+
| Lifecycle Center org | The Lifecycle Center hub. A separate connection that is never a deploy target. |
|
|
38
|
+
|
|
39
|
+
## Routing (deterministic)
|
|
40
|
+
|
|
41
|
+
Scripts and references are paths inside this skill's folder (the folder that holds this file). This skill owns every request below. Pick the operation by these rules **in order; the first match wins**. Do not hand these requests to another skill, and do not answer them from general knowledge.
|
|
42
|
+
|
|
43
|
+
| # | The request | Operation |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| 1 | Names the Lifecycle Center org, in any request, however it is spelled: "Lifecycle Center", "lifecyclecenter", "lifecycle-center", "lifecycle_center" (matching rules in `references/hub-org.md`) | **C** |
|
|
46
|
+
| 2 | Deploy, validate, quick deploy, or push components to an org, URL, org id, alias, or environment name; or gives a `requestId` or validation id | **D** |
|
|
47
|
+
| 3 | Show, list, or pick connected orgs or environments; "which orgs can I deploy to"; the current org's details | **A** |
|
|
48
|
+
| 4 | Connect, add, log in to, reconnect, or repair an org or its credential | **B** |
|
|
49
|
+
| 5 | Anything else about connected orgs or DX Inspector environments | **A** |
|
|
50
|
+
|
|
51
|
+
The Lifecycle Center org rule (1) has two exclusions: "Dev Hub" is never the Lifecycle Center org, and plural phrases such as "DevOps Center orgs", "DX Inspector orgs", "environments", or "orgs connected to DX Inspector" are not the Lifecycle Center org; route them by rules 2 to 5. Details: `references/hub-org.md`.
|
|
52
|
+
|
|
53
|
+
**Reading the wording.** Before applying the rules, normalize the request: lowercase it, treat hyphens, underscores, and extra spaces as single spaces, and ignore punctuation, one-letter typos in words of five or more letters, and filler such as "please", "can you", "I want to". (Rule 1 also uses the two forms described in `references/hub-org.md`.) Then match on any word in the groups below; the exact phrase does not matter.
|
|
54
|
+
|
|
55
|
+
| Operation | Action words (any form: "deploy", "deploying", "deployment") | Object words |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| **D** | deploy, deployment, validate, validation, check only, dry run, quick deploy, quickdeploy, push, send, ship, move, copy, release, add or install (when the object is a component) | components, metadata, classes, flows, objects, or a named org as the destination ("to", "into", "onto") |
|
|
58
|
+
| **B** | connect, connection, add, link, hook up, hookup, authorize, authenticate, log in, login, sign in, set up, setup, register, onboard, reconnect, repair, fix, refresh | org, environment, env, sandbox, scratch, production, prod, orgfarm, org farm |
|
|
59
|
+
| **A** | show, list, see, view, display, which, what, pick, choose, available | orgs, environments, envs, targets, connections, "where can I deploy" |
|
|
60
|
+
|
|
61
|
+
A request with a **D** action word and a destination, or that names a component and a destination whatever the verb ("add AccountService to my QA sandbox"), is **D**, even when it also contains a **B** word. A **B** action word whose object is an org or environment makes the request **B**, even when words like "connected" or "linked" also appear ("reconnect my sandbox, it shows not connected"). A request with only **B** words is **B**. A request with only **A** words, or a question about what is connected, is **A**. A bare `requestId` or "status of my deploy" is **D**. If no group matches, use the vague-prompt table below.
|
|
62
|
+
|
|
63
|
+
A request that mixes jobs (for example "connect my sandbox and deploy AccountService to it") takes the lowest-numbered match, here **D**, which runs **B** itself when the target is not connected.
|
|
64
|
+
|
|
65
|
+
**Vague prompts.** If the message is only "deploy", "push my changes", "connect an org", or similar, do not guess and do not call any API. Ask exactly one question that fixes the first missing input:
|
|
66
|
+
|
|
67
|
+
| Intent | Ask, in this order |
|
|
68
|
+
|---|---|
|
|
69
|
+
| Deploy | 1. Which components? (`references/deploy.md`, Step 1) 2. Which target org? |
|
|
70
|
+
| Connect | 1. "Is it a sandbox or scratch org, a production org, or an OrgFarm org?" 2. What short name (letters only) should the environment have? |
|
|
71
|
+
| Not clear which | "Do you want to connect an org or deploy components?" |
|
|
72
|
+
|
|
73
|
+
A bare "deploy" with no DX Inspector context is a question, not a deploy.
|
|
74
|
+
|
|
75
|
+
## Rules that always apply
|
|
76
|
+
|
|
77
|
+
- Targets come from the DX Inspector environments in the source org, never from `sf org list` or local aliases.
|
|
78
|
+
- Never deploy to a target that is not `selectable`, never to the source org, and never to the Lifecycle Center org.
|
|
79
|
+
- The Lifecycle Center org never appears in a list and is not mentioned while listing. It is discussed only when the user asks about it.
|
|
80
|
+
- Confirm before every call that changes an org: connect (`connect-org.md`, Step 1) and deploy (`deploy.md`, Step 4). `validate` is the only mode that needs no confirmation.
|
|
81
|
+
- When a connect started from a deploy and finishes, tell the user the org is connected and that you are continuing the deploy, then ask for the deploy confirmation. Connecting never deploys by itself.
|
|
82
|
+
- A sandbox and a scratch org are the same type (`SANDBOX`). Treat their URLs alike.
|
|
83
|
+
- Make one attempt per API call. Never retry in a loop, resubmit after a timeout, or invent an id, credential name, or status.
|
|
84
|
+
- Never ask for, print, or pass an access token. Never show row ids or credential names.
|
|
85
|
+
- Never say a browser was opened. Give the login link and wait for the user to reply **done**.
|
|
86
|
+
- Do not guess a missing input. Ask one question for the first missing input.
|
|
87
|
+
- Ask the user to confirm an org type that the URL host does not decide. Never infer it from an environment name.
|
|
88
|
+
|
|
89
|
+
## What the user sees
|
|
90
|
+
|
|
91
|
+
| After | Reply with |
|
|
92
|
+
|---|---|
|
|
93
|
+
| **A** list | Only the table and the closing sentence (`list-orgs.md`, section 4). No raw JSON, no extra offers. |
|
|
94
|
+
| **A** not enabled | The one-sentence message in `list-orgs.md`, section 2. Nothing else. |
|
|
95
|
+
| **B** connect | The sign-in layout with a button-style link (`connect-org.md`, Step 2), then after **done** the connected layout: environment name, org host, type, and status (`connect-org.md`, Step 5). |
|
|
96
|
+
| **C** | The exact sentences in `hub-org.md`. When connecting, the same sign-in and connected layouts as B, in hub form. |
|
|
97
|
+
| **D** | A plain-language report: what was deployed, from where, to where, and the outcome (`deploy.md`, Step 7). No raw JSON. If the deploy is still running after about 2 minutes: the `requestId`, a note that it is in progress, and a request to send the id back to get the status (`deploy.md`, Step 6). |
|
|
98
|
+
|
|
99
|
+
## If something fails
|
|
100
|
+
|
|
101
|
+
| Failure | Where to look |
|
|
102
|
+
|---|---|
|
|
103
|
+
| The list or target lookup fails | `references/list-orgs.md`, section 2 |
|
|
104
|
+
| A connect step fails | `references/troubleshooting.md` |
|
|
105
|
+
| A deploy or validate fails | `references/error-handling.md` |
|
|
106
|
+
| The target login is stale | Reconnect that environment (`references/connect-org.md`, repair path), then ask before retrying |
|
|
107
|
+
|
|
108
|
+
## References
|
|
109
|
+
|
|
110
|
+
- `references/list-orgs.md`: Operation A. The resolver script, match statuses, the list table, and the not-enabled handling.
|
|
111
|
+
- `references/connect-org.md`: Operation B. Modes, Steps 0 to 5, and rules for connecting an org.
|
|
112
|
+
- `references/hub-org.md`: Operation C. The Lifecycle Center org: hub names, replies, and rules.
|
|
113
|
+
- `references/deploy.md`: Operation D. Steps 1 to 7 for deploy, validate, quick deploy, and polling.
|
|
114
|
+
- `references/request-body.md`: deploy, validate, and quick-deploy request bodies and test levels.
|
|
115
|
+
- `references/connect-api.md`: Environment API and `setupNamedCredential` request and response shapes, status checks.
|
|
116
|
+
- `references/troubleshooting.md`: connect error codes and recovery.
|
|
117
|
+
- `references/error-handling.md`: deploy error codes.
|
|
118
|
+
- `examples/workflows.md`: worked prompts for each operation.
|
|
119
|
+
- `scripts/resolve-environment.sh`: read-only list and identifier resolver.
|
|
120
|
+
- `scripts/poll-deploy-status.sh`: read-only status poller. Reads the Simple Deploy endpoint and `DevopsRequestInfo`, and reports component errors on failure.
|