@salesforce/afv-skills 1.66.0 → 1.68.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/README.md +55 -5
- package/package.json +2 -4
- package/skills/agentforce-offline-experimentation-run/SKILL.md +26 -49
- package/skills/agentforce-offline-experimentation-run/scripts/bt_compare.py +81 -0
- package/skills/agentforce-offline-experimentation-run/scripts/bt_fetch.py +358 -0
- package/skills/agentforce-offline-experimentation-run/scripts/bt_patch_agent.py +110 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/__init__.py +34 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/agentpatch.py +483 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/agentsrc.py +565 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/cache.py +95 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/compare.py +617 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/fetch.py +1012 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/judge.py +148 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/messages.py +92 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/patch.py +327 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/redact.py +40 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/results.py +288 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/scoring.py +340 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/sfap.py +238 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/splits.py +136 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/stdm.py +98 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/tokens.py +173 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/units.py +199 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/versions.py +194 -0
- package/skills/agentforce-offline-experimentation-run/scripts/build_report.py +366 -378
- package/skills/agentforce-offline-experimentation-run/scripts/resolve-token.sh +14 -4
- package/skills/agentforce-offline-experimentation-run/scripts/sfap_replay.py +472 -796
- package/skills/commerce-react-storefront-create/SKILL.md +350 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/SKILL.md +2 -2
- package/skills/consumer-goods-promotion-bo-api-deploy/references/generate-and-wire.md +28 -16
- package/skills/consumer-goods-promotion-bo-api-deploy/references/smoke-and-verify.md +18 -1
- package/skills/dx-lifecycle-center/SKILL.md +5 -2
- package/skills/dx-lifecycle-center/assets/widgets/connect-connected/connect-connected.json +65 -0
- package/skills/dx-lifecycle-center/assets/widgets/connect-connected/schema.json +32 -0
- package/skills/dx-lifecycle-center/assets/widgets/connect-sign-in/connect-sign-in.json +57 -0
- package/skills/dx-lifecycle-center/assets/widgets/connect-sign-in/schema.json +21 -0
- package/skills/dx-lifecycle-center/examples/workflows.md +20 -6
- package/skills/dx-lifecycle-center/references/connect-org.md +21 -2
- package/skills/dx-lifecycle-center/references/deploy.md +2 -2
- package/skills/dx-lifecycle-center/references/list-orgs.md +1 -1
- package/skills/dx-lifecycle-center/scripts/card-policy.jq +71 -0
- package/skills/dx-lifecycle-center/scripts/fill-widget.jq +29 -0
- package/skills/dx-lifecycle-center/scripts/widget.sh +28 -0
- package/skills/dx-org-devhub-configure/SKILL.md +85 -84
- package/skills/dx-org-devhub-configure/examples/status-output.md +25 -2
- package/skills/dx-org-devhub-configure/scripts/devhub.sh +265 -140
- package/skills/dx-org-devhub-configure/scripts/test-devhub.sh +100 -15
- package/skills/dx-packaging-move-to-2gp-migrate/SKILL.md +89 -0
- package/skills/dx-packaging-move-to-2gp-migrate/references/api-operations.md +164 -0
- package/skills/dx-scratch-def-configure/SKILL.md +163 -0
- package/skills/dx-scratch-def-configure/examples/confirm-card.md +53 -0
- package/skills/dx-scratch-def-configure/examples/report-recipes.md +100 -0
- package/skills/dx-scratch-def-configure/references/features.json +3270 -0
- package/skills/dx-scratch-def-configure/references/project-scratch-def.schema.json +1841 -0
- package/skills/dx-scratch-def-configure/references/settings-map.json +682 -0
- package/skills/dx-scratch-def-configure/scripts/lib_scratch_def.py +1306 -0
- package/skills/dx-scratch-def-configure/scripts/requirements.txt +3 -0
- package/skills/dx-scratch-def-configure/scripts/scrape_config_values.py +848 -0
- package/skills/education-cloud-domain-configure/SKILL.md +22 -24
- package/skills/education-cloud-domain-configure/references/dependent-features.md +9 -0
- package/skills/education-cloud-domain-configure/references/domain-features.md +15 -0
- package/skills/education-cloud-domain-configure/references/gotchas-extended.md +8 -0
- package/skills/education-cloud-domain-configure/references/setup-widgets.md +123 -0
- package/skills/education-cloud-multi-campus-configure/SKILL.md +1 -1
- package/skills/education-cloud-student-recruitment-agent-configure/SKILL.md +1 -1
- package/skills/experience-design-validate/SKILL.md +1 -1
- package/skills/experience-search-coordinate/SKILL.md +19 -13
- package/skills/experience-search-coordinate/references/content-route.md +79 -1
- package/skills/experience-search-coordinate/references/media-route.md +30 -4
- package/skills/experience-ui-bundle-features-generate/SKILL.md +1 -1
- package/skills/experience-ui-bundle-mfa-configure/SKILL.md +1 -1
- package/skills/field-service-data-capture-migrate/SKILL.md +1 -1
- package/skills/platform-apex-generate/SKILL.md +14 -11
- package/skills/platform-apex-test-generate/SKILL.md +2 -1
- package/skills/platform-datamask-run/SKILL.md +52 -71
- package/skills/platform-datamask-run/references/api-surface.md +10 -4
- package/skills/platform-datamask-run/references/policy-authoring.md +56 -7
- package/skills/platform-datamask-run/references/run-and-abort.md +17 -10
- package/skills/platform-datamask-run/scripts/poll-job.sh +15 -25
- package/skills/platform-dataspace-access-configure/SKILL.md +19 -1
- package/skills/platform-metadata-deploy/README.md +1 -1
- package/skills/platform-metadata-deploy/SKILL.md +114 -15
- package/skills/platform-metadata-deploy/references/agent-deployment-guide.md +3 -4
- package/skills/platform-metadata-deploy/references/orchestration.md +2 -3
- package/skills/platform-metadata-discovery-get/SKILL.md +185 -0
- package/skills/platform-metadata-discovery-get/references/api-map.md +25 -0
- package/skills/platform-metadata-discovery-get/references/h360-routes.md +30 -0
- package/skills/platform-metadata-discovery-get/references/scoped-soql.md +52 -0
- package/skills/platform-metadata-grounding-get/SKILL.md +170 -0
- package/skills/platform-policy-rule-generate/SKILL.md +84 -232
- package/skills/platform-policy-rule-generate/references/condition-model.md +47 -0
- package/skills/platform-policy-rule-generate/references/condition-templates.md +89 -0
- package/skills/platform-policy-rule-generate/references/conjunction-compiler.md +25 -0
- package/skills/platform-policy-rule-generate/references/conjunction-expression.md +22 -0
- package/skills/platform-policy-rule-generate/references/consumer-all.md +9 -0
- package/skills/platform-policy-rule-generate/references/consumer-datacloud-ui.md +91 -0
- package/skills/platform-policy-rule-generate/references/deploy-errors.md +24 -36
- package/skills/platform-policy-rule-generate/references/examples/ExistsJoinRLS/package.xml +12 -0
- package/skills/platform-policy-rule-generate/references/examples/ExistsJoinRLS/policyRuleDefinitionSets/ExistsJoinRLS.policyRuleDefinitionSet +6 -0
- package/skills/platform-policy-rule-generate/references/examples/ExistsJoinRLS/policyRuleDefinitions/ExistsJoinRLS_Rule_1.policyRuleDefinition +91 -0
- package/skills/platform-policy-rule-generate/references/examples/FieldReadDeny/package.xml +12 -0
- package/skills/platform-policy-rule-generate/references/examples/FieldReadDeny/policyRuleDefinitionSets/FieldReadDeny.policyRuleDefinitionSet +6 -0
- package/skills/platform-policy-rule-generate/references/examples/FieldReadDeny/policyRuleDefinitions/FieldReadDeny_Rule_1.policyRuleDefinition +72 -0
- package/skills/platform-policy-rule-generate/references/examples/LastCharactersFieldMasking/package.xml +12 -0
- package/skills/platform-policy-rule-generate/references/examples/LastCharactersFieldMasking/policyRuleDefinitionSets/LastCharactersFieldMasking.policyRuleDefinitionSet +6 -0
- package/skills/platform-policy-rule-generate/references/examples/LastCharactersFieldMasking/policyRuleDefinitions/LastCharactersFieldMasking_Rule_1.policyRuleDefinition +77 -0
- package/skills/platform-policy-rule-generate/references/examples/PrincipalFieldMatchRLS/package.xml +12 -0
- package/skills/platform-policy-rule-generate/references/examples/PrincipalFieldMatchRLS/policyRuleDefinitionSets/PrincipalFieldMatchRLS.policyRuleDefinitionSet +6 -0
- package/skills/platform-policy-rule-generate/references/examples/PrincipalFieldMatchRLS/policyRuleDefinitions/PrincipalFieldMatchRLS_Rule_1.policyRuleDefinition +77 -0
- package/skills/platform-policy-rule-generate/references/examples/TaggedObjectAccess/package.xml +12 -0
- package/skills/platform-policy-rule-generate/references/examples/TaggedObjectAccess/policyRuleDefinitionSets/TaggedObjectAccess.policyRuleDefinitionSet +4 -0
- package/skills/platform-policy-rule-generate/references/examples/TaggedObjectAccess/policyRuleDefinitions/TaggedObjectAccess_Rule_1.policyRuleDefinition +65 -0
- package/skills/platform-policy-rule-generate/references/headless-transport.md +87 -0
- package/skills/platform-policy-rule-generate/references/policy-schema-full.md +17 -10
- package/skills/platform-policy-rule-generate/references/policy-shapes.md +74 -0
- package/skills/platform-policy-rule-generate/references/principal-expression.md +31 -0
- package/skills/platform-policy-rule-generate/references/reference-resolution.md +51 -0
- package/skills/platform-policy-rule-generate/references/resource-expression.md +48 -0
- package/skills/platform-policy-rule-generate/references/runtime-context.md +9 -0
- package/skills/platform-policy-rule-generate/references/templates-access.md +11 -9
- package/skills/platform-policy-rule-generate/references/templates-advanced.md +4 -2
- package/skills/platform-policy-rule-generate/references/templates-record.md +37 -22
- package/skills/platform-policy-rule-generate/references/templates-transform.md +10 -8
- package/skills/platform-policy-rule-generate/references/templates.md +2 -2
- package/skills/platform-policy-rule-generate/references/ui-compatibility.md +35 -17
- package/skills/platform-report-generate/SKILL.md +9 -4
- package/skills/platform-report-generate/references/chart-types.md +26 -2
- package/skills/platform-report-generate/references/column-names.md +43 -0
- package/skills/platform-report-generate/references/errors-and-troubleshooting.md +1 -1
- package/skills/platform-report-generate/references/verification-checklist.md +10 -2
- package/skills/platform-value-set-generate/SKILL.md +19 -19
- package/skills/platform-widget-generate/SKILL.md +25 -51
- package/skills/platform-widget-generate/examples/formulas.json +19 -2
- package/skills/platform-widget-generate/examples/localized-labels.json +57 -0
- package/skills/platform-widget-generate/references/widget-actions.md +29 -0
- package/skills/platform-widget-generate/references/widget-bundle-validation.md +1 -0
- package/skills/platform-widget-generate/references/widget-formulas.md +24 -7
- package/skills/platform-widget-generate/references/widget-gotchas.md +10 -0
- package/skills/platform-widget-generate/references/widget-labels.md +78 -0
- package/skills/platform-widget-generate/references/widget-styling.md +12 -0
- package/skills/sales-call-scoring-configure/SKILL.md +17 -10
- package/skills/sales-call-scoring-configure/scripts/enable-call-scoring.sh +55 -33
- package/skills/service-digital-engagement-channel-configure/SKILL.md +11 -7
- package/skills/service-digital-engagement-channel-configure/assets/messaging_channel_template.xml +33 -0
- package/skills/service-digital-engagement-channel-configure/references/channel_settings.md +123 -16
- package/skills/service-digital-engagement-deployment-configure/SKILL.md +37 -100
- package/skills/service-digital-engagement-deployment-configure/assets/esd_web_update_template.xml +83 -8
- package/skills/service-digital-engagement-deployment-configure/examples/esd_web_prechat_fields.xml +74 -0
- package/skills/service-digital-engagement-deployment-configure/references/connect_api_creation.md +13 -3
- package/skills/service-digital-engagement-deployment-configure/references/deployment_settings.md +13 -78
- package/skills/service-digital-engagement-deployment-configure/references/onboarding_contract.md +5 -6
- package/skills/service-digital-engagement-deployment-configure/references/prechat_forms.md +245 -0
- package/skills/service-itsm-agentic-setup-incident-management/SKILL.md +164 -120
- package/skills/service-itsm-agentic-setup-incident-management/examples/output-templates.md +61 -37
- package/skills/service-itsm-agentic-setup-incident-management/references/audit-tracking.md +42 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/broadcast-communications.md +23 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/email-to-incident.md +23 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/incident-dashboards.md +25 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/incident-persona-psg.md +30 -146
- package/skills/service-itsm-agentic-setup-incident-management/references/incident-preferences.md +32 -136
- package/skills/service-itsm-agentic-setup-incident-management/references/major-incident-management.md +32 -155
- package/skills/service-itsm-agentic-setup-incident-management/references/manage-incidents-with-ai.md +45 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/priority-matrix.md +32 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/service-mgmt-privilege.md +30 -140
- package/skills/service-itsm-agentic-setup-incident-management/references/sla-milestones.md +110 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: platform-dataspace-access-configure
|
|
3
|
-
description: "
|
|
3
|
+
description: "THE skill for granting Data Cloud data-space access and the PERMISSION-SET / RBAC way of granting object access. Grants data-space-level access via MDAPI PermissionSet XML with dataspaceScopes, grants object-level access to DMO/DLO/CIO objects via the Object Access Grants Connect API (RBAC object grants), and inspects existing scopes read-only. TRIGGER when the user needs to grant access to a data space / dataspace, create/update a permission set with DataSpace access, list/configure scopes, or add/list/remove RBAC object access grants — 'grant access to a data space' routes here. DO NOT TRIGGER for a generic permission set (use platform-permission-set-generate), data ingestion/streams, creating dataspaces themselves, or an access POLICY / policy rule / tag/classification-based access (use platform-policy-rule-generate). For a vague object-access ask, surface both skills and ASK the permission-set way vs the policy way; if unsure the object is Data Cloud, ask which first."
|
|
4
4
|
metadata:
|
|
5
5
|
relatedSkills:
|
|
6
6
|
- "platform-permission-set-generate"
|
|
7
|
+
- "platform-policy-rule-generate"
|
|
7
8
|
version: "1.0"
|
|
8
9
|
domains: ["Platform", "Data 360"]
|
|
9
10
|
minApiVersion: "67.0"
|
|
@@ -27,6 +28,23 @@ The MDAPI layer is required to establish the PermissionSet → DataSpace linkage
|
|
|
27
28
|
|
|
28
29
|
---
|
|
29
30
|
|
|
31
|
+
## When to use this skill (routing)
|
|
32
|
+
|
|
33
|
+
This is the **permission-set / RBAC** path to Data Cloud access:
|
|
34
|
+
|
|
35
|
+
- **"Grant access to a data space" / dataspace access** → this skill (Layer 1, `dataspaceScopes` on a permission set).
|
|
36
|
+
- **Grant object access via a permission set / RBAC object grant** → this skill (Layer 2, Object Access Grants Connect API).
|
|
37
|
+
|
|
38
|
+
Object access has a second, separate path — a **data-governance access policy** (a tag/OLS `PolicyRuleDefinition`), owned by **`platform-policy-rule-generate`**. Infer the mechanism from context; ask only when the request is vague:
|
|
39
|
+
|
|
40
|
+
- The user is **driving from a permission set** (mentions a permission set, RBAC, or an object grant on a permset) → object access grant → **this skill**, no need to ask.
|
|
41
|
+
- The user **frames it as a policy** (create a policy / access policy / policy rule, OLS/FLS/RLS, tag/classification-based) → route to **`platform-policy-rule-generate`**.
|
|
42
|
+
- The request is **genuinely vague** — "grant object access to X" with no mechanism and no clue → **ASK**: the **permission-set way** (this skill) or the **policy way** (`platform-policy-rule-generate`)? If it is also unclear whether the object is a Data Cloud object, ask which object first.
|
|
43
|
+
|
|
44
|
+
"Access to a **data space**" is always this skill (the permission-set / `dataspaceScopes` path) — no disambiguation needed.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
30
48
|
## Decide the Case First
|
|
31
49
|
|
|
32
50
|
Pick exactly one case from the table below before writing any files. Each case has a different output shape.
|
|
@@ -86,7 +86,7 @@ platform-custom-object-generate/automation-flow-generate → platform-metadata-d
|
|
|
86
86
|
|
|
87
87
|
| Related Skill | When to Use |
|
|
88
88
|
|---------------|-------------|
|
|
89
|
-
| platform-custom-object-generate
|
|
89
|
+
| platform-custom-object-generate | Create objects/fields BEFORE deploy |
|
|
90
90
|
| platform-apex-test-run | Run tests AFTER deployment |
|
|
91
91
|
| platform-data-manage | Create describe-validated test data AFTER deployment |
|
|
92
92
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: platform-metadata-deploy
|
|
3
|
-
description: "Salesforce DevOps automation using sf CLI v2. TRIGGER when: user deploys metadata, creates/manages scratch orgs or sandboxes, sets up CI/CD pipelines, or troubleshoots deployment errors with sf project deploy. DO NOT TRIGGER when: writing Apex code
|
|
3
|
+
description: "Salesforce DevOps automation using sf CLI v2. TRIGGER when: user deploys metadata, validates a deploy or does a dry-run, deploys to a Production org, quick-deploys a validated job ID, ships/promotes to prod, creates/manages scratch orgs or sandboxes, sets up CI/CD pipelines, or troubleshoots deployment errors with sf project deploy. DO NOT TRIGGER when: writing Apex code, building LWC components (use experience-lwc-generate), creating metadata definitions (use platform-custom-object-generate), deleting metadata from an org (use platform-destructive-deploy), or querying org data (use platform-data-manage)."
|
|
4
4
|
metadata:
|
|
5
|
-
version: "1.
|
|
5
|
+
version: "1.2"
|
|
6
6
|
domains: ["Platform", "Developer Experience"]
|
|
7
7
|
relatedSkills:
|
|
8
8
|
- "agentforce-generate"
|
|
@@ -11,9 +11,7 @@ metadata:
|
|
|
11
11
|
- "experience-lwc-generate"
|
|
12
12
|
- "integration-connectivity-connected-app-configure"
|
|
13
13
|
- "integration-connectivity-generate"
|
|
14
|
-
- "platform-apex-generate"
|
|
15
14
|
- "platform-apex-test-run"
|
|
16
|
-
- "platform-custom-field-generate"
|
|
17
15
|
- "platform-custom-object-generate"
|
|
18
16
|
- "platform-data-manage"
|
|
19
17
|
cliTools:
|
|
@@ -40,9 +38,9 @@ Use `platform-metadata-deploy` when the work involves:
|
|
|
40
38
|
- troubleshooting deployment failures and dependency ordering
|
|
41
39
|
|
|
42
40
|
Delegate elsewhere when the user is:
|
|
43
|
-
- authoring Apex code
|
|
41
|
+
- authoring Apex code (this skill only deploys it)
|
|
44
42
|
- authoring LWC components → [experience-lwc-generate](../experience-lwc-generate/SKILL.md)
|
|
45
|
-
- creating custom objects or fields → [platform-custom-object-generate](../platform-custom-object-generate/SKILL.md)
|
|
43
|
+
- creating custom objects or fields → [platform-custom-object-generate](../platform-custom-object-generate/SKILL.md)
|
|
46
44
|
- building Flows → [automation-flow-generate](../automation-flow-generate/SKILL.md)
|
|
47
45
|
- doing org data operations → [platform-data-manage](../platform-data-manage/SKILL.md)
|
|
48
46
|
- authoring or testing Agentforce agents → [agentforce-generate](../agentforce-generate/SKILL.md)
|
|
@@ -54,6 +52,7 @@ Delegate elsewhere when the user is:
|
|
|
54
52
|
- Use **`sf` CLI v2 only**.
|
|
55
53
|
- On non-source-tracking orgs, deploy/retrieve commands require an explicit scope such as `--source-dir`, `--metadata`, or `--manifest`.
|
|
56
54
|
- Prefer **`--dry-run` first** before real deploys.
|
|
55
|
+
- **Never run `sf project deploy start` against a production org.** Production goes through the validate → quick-deploy path below (server-side validation returns a 10-day job ID; quick-deploy promotes it without re-running tests, behind an explicit confirmation).
|
|
57
56
|
- For Flows, deploy safely and activate only after validation.
|
|
58
57
|
- Keep test-data creation guidance delegated to **`platform-data-manage`** after metadata is validated or deployed.
|
|
59
58
|
|
|
@@ -82,7 +81,7 @@ Ask for or infer:
|
|
|
82
81
|
Preflight checks:
|
|
83
82
|
```bash
|
|
84
83
|
sf --version
|
|
85
|
-
sf org list
|
|
84
|
+
sf org list --skip-connection-status
|
|
86
85
|
sf org display --target-org <alias> --json
|
|
87
86
|
test -f sfdx-project.json
|
|
88
87
|
```
|
|
@@ -94,7 +93,25 @@ test -f sfdx-project.json
|
|
|
94
93
|
### 1. Preflight
|
|
95
94
|
Confirm auth, repo shape, package directories, and target scope.
|
|
96
95
|
|
|
97
|
-
###
|
|
96
|
+
### 1a. Classify the target org (routes prod vs non-prod)
|
|
97
|
+
|
|
98
|
+
Before any deploy, classify the target from its `sf org list` record — the path forks on whether the org is **production**. Do NOT classify from `sf org display`: it reports only a plain My Domain and omits the sandbox/scratch/trial fields, so a Sandbox-or-Demo Org (SDO) is misclassified as production (forcedotcom/sf-skills#356). The `sf org list` record carries the real classification booleans. Pass `--skip-connection-status` so this stays a local read that does not refresh an OAuth token per authenticated org (forcedotcom/sf-skills#349):
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
sf org list --skip-connection-status --json
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Find the record whose `alias`, `username`, or `orgId` matches the target, then classify from that record (first match wins):
|
|
105
|
+
- **Scratch** — `isScratch` is `true`.
|
|
106
|
+
- **Sandbox** — `isSandbox` is `true`, or the `instanceUrl` contains `--` (the My Domain sandbox marker) or `test.salesforce.com`.
|
|
107
|
+
- **Trial / Developer Edition** — `trailExpirationDate` (the CLI's spelling; also accept `trialExpirationDate`) is a date in the **future**, or the `instanceUrl` host contains `orgfarm-`, `.develop.my.salesforce.com`, `.pc-rnd.`, or `.scratch.my.salesforce.com`. A past date does not count — the date is cached at login and never refreshed, so a converted trial keeps a stale past date and is not a trial.
|
|
108
|
+
|
|
109
|
+
Anything else is **production** — including a **Dev Hub** (`isDevHub` is `true`) that shows none of the above signals, since Dev Hub is normally enabled in the customer's own production org. If no record matches or the record has no usable info (no `instanceUrl` and none of the flags), treat it as **unknown** and ask the user before proceeding, rather than assuming production or non-production.
|
|
110
|
+
|
|
111
|
+
- **Non-production** → the dry-run + deploy path (steps 2–6).
|
|
112
|
+
- **Production** → the validate → quick-deploy path ([Production deploys](#production-deploys-validate--quick-deploy)). Never run `sf project deploy start` against production.
|
|
113
|
+
|
|
114
|
+
### 2. Validate first (non-production)
|
|
98
115
|
```bash
|
|
99
116
|
sf project deploy start --dry-run --source-dir force-app --target-org <alias> --wait 30 --json
|
|
100
117
|
```
|
|
@@ -118,9 +135,6 @@ sf project deploy start --manifest manifest/package.xml --target-org <alias> --t
|
|
|
118
135
|
|
|
119
136
|
# manifest deploy with Spring '26 relevant-test selection
|
|
120
137
|
sf project deploy start --manifest manifest/package.xml --target-org <alias> --test-level RunRelevantTests --wait 30 --json
|
|
121
|
-
|
|
122
|
-
# quick deploy after successful validation
|
|
123
|
-
sf project deploy quick --job-id <validation-job-id> --target-org <alias> --json
|
|
124
138
|
```
|
|
125
139
|
|
|
126
140
|
### 5. Verify
|
|
@@ -136,6 +150,93 @@ Output template: [references/deployment-report-template.md](references/deploymen
|
|
|
136
150
|
|
|
137
151
|
---
|
|
138
152
|
|
|
153
|
+
## Production deploys (validate → quick-deploy)
|
|
154
|
+
|
|
155
|
+
Production is never deployed with `sf project deploy start`. It is a two-step promotion: a **server-side validation** produces a job ID, then a **quick deploy** promotes that validated job without re-running tests, behind an explicit confirmation.
|
|
156
|
+
|
|
157
|
+
### P1. Validate against production
|
|
158
|
+
|
|
159
|
+
Production validations REQUIRE a test level. Use `RunLocalTests` by default; switch to `RunSpecifiedTests --tests <ClassName>...` only if the user has explicitly listed tests.
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
sf project deploy validate --target-org <alias> --json [scope flags] --test-level RunLocalTests
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Scope flags — use exactly one: `--source-dir <path>`, `--metadata <Type:Name>`, or `--manifest manifest/package.xml`.
|
|
166
|
+
|
|
167
|
+
The response returns a **job ID** (`result.id`) valid for **10 days**. Persist it **with the target's immutable identity** — the org ID and instance URL from `sf org display`, not just the alias — so the quick deploy can prove the validation belongs to the org it is about to promote to:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
mkdir -p .sfdx
|
|
171
|
+
ORG_JSON=$(sf org display --target-org <alias> --json)
|
|
172
|
+
ORG_ID=$(printf '%s' "$ORG_JSON" | jq -r '.result.id')
|
|
173
|
+
INSTANCE_URL=$(printf '%s' "$ORG_JSON" | jq -r '.result.instanceUrl')
|
|
174
|
+
printf '{"jobId":"%s","createdAt":"%s","targetOrg":"%s","orgId":"%s","instanceUrl":"%s","testLevel":"RunLocalTests"}\n' \
|
|
175
|
+
"<id>" "<iso8601>" "<alias>" "$ORG_ID" "$INSTANCE_URL" > .sfdx/last-validation.json
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
On validation failure, triage from `result.details.componentFailures` and `result.details.runTestResult.failures` — surface the top component errors and test failures with a scoped fix direction, then STOP. Never use `--ignore-errors`/`--ignore-warnings` during validation.
|
|
179
|
+
|
|
180
|
+
### P2. Gate the quick deploy strictly
|
|
181
|
+
|
|
182
|
+
Before promoting, verify all five:
|
|
183
|
+
1. **Target is production** — re-confirm via step 1a's classification.
|
|
184
|
+
2. **A validation exists** — read `.sfdx/last-validation.json`, or ask for the job ID, or fall back to `--use-most-recent`. Resolve `--use-most-recent` to a concrete job ID **now** (do not carry it forward as an unresolved flag), so the checks below run against a known job.
|
|
185
|
+
3. **Validation belongs to THIS target** — re-run `sf org display --target-org <alias> --json` and require the current `result.id` (org ID) to equal the `orgId` persisted in `.sfdx/last-validation.json`. This closes the stale-cache hazard: a cached job ID resolves its org from the deploy cache, so without this check the banner can show org B while the job promotes to org A. On any mismatch — or if the persisted record lacks an `orgId`/`instanceUrl` to compare — treat it as a **hard stop** and re-validate (P1) against the intended target. Never promote a validation whose target you cannot prove.
|
|
186
|
+
4. **Validation is fresh** — explicit `--job-id` ≤ 10 days; a `--use-most-recent` resolution ≤ 3 days. If stale, re-validate (P1) first.
|
|
187
|
+
5. **Explicit user confirmation** — print the banner below and require a literal "yes". Populate every banner field from the verified validation record and the just-fetched org data — never from unverified input. Never auto-confirm.
|
|
188
|
+
|
|
189
|
+
```text
|
|
190
|
+
┌─ PRODUCTION DEPLOY ─────────────────────────────┐
|
|
191
|
+
│ Org alias: <alias> │
|
|
192
|
+
│ Instance: <instanceUrl> │
|
|
193
|
+
│ Edition: <edition> │
|
|
194
|
+
│ Validation ID: <jobId> │
|
|
195
|
+
│ Validated: <createdAt> (X days ago) │
|
|
196
|
+
│ Components: <componentCount> queued │
|
|
197
|
+
│ Tests: <run>/<passed>/<failed> │
|
|
198
|
+
└─────────────────────────────────────────────────┘
|
|
199
|
+
Confirm deploy to PRODUCTION? (yes/no)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
`sf org display --json` does not return the edition. Read `<edition>` from the Organization object's `OrganizationType` (e.g. `Enterprise Edition`):
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
sf data query --query "SELECT OrganizationType FROM Organization" --target-org <alias> --json | jq -r '.result.records[0].OrganizationType'
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### P3. Promote and audit
|
|
209
|
+
|
|
210
|
+
The literal "yes" from P2's banner is the authorization. In the **Salesforce development plugin** context, a PreToolUse hook (`sf-deploy-gate`) blocks a bare production `deploy quick` and only permits it when the command carries the machine-readable confirmation marker `CONFIRM_PROD=1`. Emit that marker to transmit the confirmation the user just gave — it is **not** an independent bypass, so add it **only after** the explicit "yes", never before:
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
# plugin context: CONFIRM_PROD=1 relays P2's confirmation to the safety hook
|
|
214
|
+
CONFIRM_PROD=1 sf project deploy quick --job-id <validation-id> --target-org <alias> --wait 30 --json
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Outside the plugin (bare CLI, headless/MCP) there is no such hook — run the same command without the marker.
|
|
218
|
+
|
|
219
|
+
**Quick deploy starts a new deployment with its own job ID** — it does not reuse the validation ID. Capture the response, extract the new ID, and use *that* for polling, reporting, and the audit filename; keep the validation ID separately for traceability. Stop if the response carries no deployment ID:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
QUICK_RESULT=$(CONFIRM_PROD=1 sf project deploy quick --job-id <validation-id> --target-org <alias> --wait 30 --json)
|
|
223
|
+
QUICK_DEPLOY_ID=$(printf '%s' "$QUICK_RESULT" | jq -r '.result.id')
|
|
224
|
+
[ -n "$QUICK_DEPLOY_ID" ] && [ "$QUICK_DEPLOY_ID" != "null" ] || { echo "No quick-deploy ID returned — do not report the validation ID as the deploy; investigate."; exit 1; }
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Quick deploy promotes the validated components and does NOT re-run tests. Persist the report **for the quick-deploy operation** (not the validation) for the audit trail, then guide post-deploy verification (smoke-test critical paths, watch Setup → Deployment Status, prepare a rollback plan if anything regressed):
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
mkdir -p .sfdx/deploy-history
|
|
231
|
+
sf project deploy report --job-id "$QUICK_DEPLOY_ID" --target-org <alias> --json > ".sfdx/deploy-history/${QUICK_DEPLOY_ID}.json"
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
If quick deploy times out or stays in progress, poll with the **quick-deploy ID**, not the validation ID.
|
|
235
|
+
|
|
236
|
+
Adding `CONFIRM_PROD=1` after an explicit confirmation is the sanctioned path — it is not "working around" the gate. But never override a denial the user has **not** confirmed, and never override one raised for a different reason — a target mismatch (P2 check 3), a destructive deploy, or an unknown/unresolved org. Surface those denials and stop.
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
139
240
|
## High-Signal Failure Patterns
|
|
140
241
|
|
|
141
242
|
| Error / symptom | Likely cause | Default fix direction |
|
|
@@ -163,7 +264,7 @@ Default pipeline shape:
|
|
|
163
264
|
7. verify + notify
|
|
164
265
|
|
|
165
266
|
- When org policy and release risk allow it, consider `--test-level RunRelevantTests` for Apex-heavy deployments.
|
|
166
|
-
- Pair this with modern Apex test annotations such as `@IsTest(testFor=...)` and `@IsTest(isCritical=true)
|
|
267
|
+
- Pair this with modern Apex test annotations such as `@IsTest(testFor=...)` and `@IsTest(isCritical=true)`.
|
|
167
268
|
|
|
168
269
|
Static analysis now uses **Code Analyzer v5** (`sf code-analyzer`), not retired `sf scanner`.
|
|
169
270
|
|
|
@@ -185,9 +286,7 @@ For full agent DevOps details, including `Agent:` pseudo metadata, publish/activ
|
|
|
185
286
|
|
|
186
287
|
| Need | Delegate to | Reason |
|
|
187
288
|
|---|---|---|
|
|
188
|
-
| custom object creation | [platform-custom-object-generate](../platform-custom-object-generate/SKILL.md) | define objects before deploy |
|
|
189
|
-
| custom field creation | [platform-custom-field-generate](../platform-custom-field-generate/SKILL.md) | define fields before deploy |
|
|
190
|
-
| Apex authoring / fixes | [platform-apex-generate](../platform-apex-generate/SKILL.md) | code authoring and repair |
|
|
289
|
+
| custom object / field creation | [platform-custom-object-generate](../platform-custom-object-generate/SKILL.md) | define objects and fields before deploy |
|
|
191
290
|
| run tests after deployment | [platform-apex-test-run](../platform-apex-test-run/SKILL.md) | post-deploy test execution and coverage |
|
|
192
291
|
| Flow creation / repair | [automation-flow-generate](../automation-flow-generate/SKILL.md) | Flow authoring and activation guidance |
|
|
193
292
|
| test data or seed records | [platform-data-manage](../platform-data-manage/SKILL.md) | describe-first data setup and cleanup |
|
|
@@ -366,9 +366,9 @@ Pass the BotVersion number you intend to activate as the third argument.
|
|
|
366
366
|
**Critical:** Dependencies must be deployed BEFORE the agent.
|
|
367
367
|
|
|
368
368
|
```text
|
|
369
|
-
1. Custom Objects/Fields (platform-custom-object-generate
|
|
369
|
+
1. Custom Objects/Fields (platform-custom-object-generate)
|
|
370
370
|
↓
|
|
371
|
-
2. Apex Classes
|
|
371
|
+
2. Apex Classes
|
|
372
372
|
↓
|
|
373
373
|
3. Flows (automation-flow-generate)
|
|
374
374
|
↓
|
|
@@ -571,14 +571,13 @@ sf agent activate --api-name My_Agent --target-org myorg
|
|
|
571
571
|
| From Skill | To Skill | Purpose |
|
|
572
572
|
|------------|----------|---------|
|
|
573
573
|
| agentforce-generate | platform-metadata-deploy | Publish and activate agents |
|
|
574
|
-
| platform-apex-generate | platform-metadata-deploy | Deploy Apex before agent |
|
|
575
574
|
| automation-flow-generate | platform-metadata-deploy | Deploy Flows before agent |
|
|
576
575
|
| integration-connectivity-generate | platform-metadata-deploy | Deploy Named Credentials for external APIs |
|
|
577
576
|
|
|
578
577
|
### Integration Pattern
|
|
579
578
|
|
|
580
579
|
```bash
|
|
581
|
-
# 1.
|
|
580
|
+
# 1. An InvocableMethod class is authored
|
|
582
581
|
# 2. automation-flow-generate creates wrapper Flow
|
|
583
582
|
# 3. agentforce-generate creates agent with flow:// action
|
|
584
583
|
# 4. platform-metadata-deploy orchestrates deployment in correct order
|
|
@@ -11,7 +11,7 @@ This document details how platform-metadata-deploy fits into the multi-skill wor
|
|
|
11
11
|
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
12
12
|
│ STANDARD MULTI-SKILL ORCHESTRATION ORDER │
|
|
13
13
|
├─────────────────────────────────────────────────────────────────────────────┤
|
|
14
|
-
│ 1. platform-custom-object-generate
|
|
14
|
+
│ 1. platform-custom-object-generate │
|
|
15
15
|
│ └── Create object/field definitions (LOCAL files) │
|
|
16
16
|
│ │
|
|
17
17
|
│ 2. automation-flow-generate │
|
|
@@ -84,7 +84,7 @@ When deploying agents with external API integrations:
|
|
|
84
84
|
├─────────────────────────────────────────────────────────────────────────────┤
|
|
85
85
|
│ 1. integration-connectivity-connected-app-configure → Create OAuth Connected App │
|
|
86
86
|
│ 2. integration-connectivity-generate → Create Named Credential + External Service │
|
|
87
|
-
│ 3.
|
|
87
|
+
│ 3. Apex authoring → Create @InvocableMethod (if needed) │
|
|
88
88
|
│ 4. automation-flow-generate → Create Flow wrapper │
|
|
89
89
|
│ │
|
|
90
90
|
│ 5. platform-metadata-deploy ◀── FIRST DEPLOYMENT │
|
|
@@ -169,7 +169,6 @@ sf agent activate --api-name AgentName --version N --target-org alias --json
|
|
|
169
169
|
|------------|--------------|------|
|
|
170
170
|
| platform-custom-object-generate | → platform-metadata-deploy | "Deploy objects to [org]" |
|
|
171
171
|
| automation-flow-generate | → platform-metadata-deploy | "Deploy flow with --dry-run" |
|
|
172
|
-
| platform-apex-generate | → platform-metadata-deploy | "Deploy classes with RunLocalTests" |
|
|
173
172
|
| agentforce-generate | → platform-metadata-deploy | "Deploy and publish agent" |
|
|
174
173
|
|
|
175
174
|
---
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: platform-metadata-discovery-get
|
|
3
|
+
description: "Use before creating, changing, or writing code against Salesforce metadata, to find out what already exists in the org with the right tool. Routes each question to metadata grounding, scoped SOQL with sf data query, sf sobject list or describe, sf org list metadata, source retrieval, or local files, and covers orgs and setups where grounding is not available. Use to check whether an object, field, picklist, permission set, page, app, or flow already exists before creating one, confirm field names, types, and picklist values before writing Apex, LWC, SOQL, or Flow logic, list every field on an object or every member of a metadata type, find automation that runs on an object, or explain how something in the org is configured and who can access it. DO NOT TRIGGER for whole-org overviews, org comparison, or drift (use dx-org-analyze), metadata file structure or XML shape (platform-metadata-api-context-get), or Data Cloud DLO and DMO schema (data360-code-extension-generate)."
|
|
4
|
+
metadata:
|
|
5
|
+
relatedSkills:
|
|
6
|
+
- data360-code-extension-generate
|
|
7
|
+
- dx-org-analyze
|
|
8
|
+
- platform-metadata-api-context-get
|
|
9
|
+
- platform-metadata-grounding-get
|
|
10
|
+
- platform-metadata-retrieve
|
|
11
|
+
version: "1.3"
|
|
12
|
+
domains:
|
|
13
|
+
- "Platform"
|
|
14
|
+
cliTools:
|
|
15
|
+
- tool:
|
|
16
|
+
- "sf"
|
|
17
|
+
semver: ">=2.0.0"
|
|
18
|
+
mcpTools:
|
|
19
|
+
metadata-grounding:
|
|
20
|
+
tools:
|
|
21
|
+
- "search_metadata"
|
|
22
|
+
- "query_metadata"
|
|
23
|
+
- "describe_metadata"
|
|
24
|
+
semver: ">=1.0.0"
|
|
25
|
+
headless-360:
|
|
26
|
+
tools:
|
|
27
|
+
- "describe"
|
|
28
|
+
- "dispatch"
|
|
29
|
+
- "dispatch_readonly"
|
|
30
|
+
semver: ">=1.0.0"
|
|
31
|
+
id: "platform-metadata-discovery-get"
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
# Salesforce Metadata Discovery
|
|
35
|
+
|
|
36
|
+
Before you create metadata, change it, or write code that references it, know what already exists in the org. This skill picks the tool for each question. Metadata grounding finds metadata by meaning when you do not know its name. It needs Salesforce Catalog and a connected grounding server, and many orgs and setups have neither. Every other route works with the `sf` CLI alone.
|
|
37
|
+
|
|
38
|
+
Skip discovery when the request only changes local files and adds no new references to org metadata.
|
|
39
|
+
|
|
40
|
+
## Check What You Have
|
|
41
|
+
|
|
42
|
+
Do this once per session, before the first lookup.
|
|
43
|
+
|
|
44
|
+
1. **The CLI and its org.** Run `sf org display --json` to see the default org and its id. If no org is authenticated, ask the user to run `sf org login web` and wait. If you cannot run commands at all, read `references/h360-routes.md`.
|
|
45
|
+
2. **Grounding servers.** Note whether the Metadata Grounding MCP (tools `search_metadata`, `query_metadata`, `describe_metadata`) or the Salesforce MCP is connected. The Salesforce MCP is shown in Setup today as the Headless360 (H360) MCP Server. Its tools are `describe`, `dispatch`, and `dispatch_readonly`, which are different from the Metadata Grounding MCP tools.
|
|
46
|
+
3. **One org.** Grounding identifiers start with the 18-character org id. If it differs from the id in `sf org display`, tell the user and ask which org to use before you combine results.
|
|
47
|
+
|
|
48
|
+
## Route by Intent
|
|
49
|
+
|
|
50
|
+
| Intent | Use | If that is not available |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| Find metadata by meaning, check a name you are guessing, or check for something to reuse | Metadata grounding search. Load `platform-metadata-grounding-get`, which picks the server. | Name and label fallback, below. Notify. |
|
|
53
|
+
| Explain how something is configured, or who can access it | Metadata grounding query | Scoped SOQL on `EntityParticle`, `FieldPermissions`, `ObjectPermissions`, or Tooling `ValidationRule`. Notify. |
|
|
54
|
+
| Check names, types, or picklist values you know. Every field on one object. Data records | Scoped SOQL with `sf data query`. If it returns nothing, search by meaning. | See the note below the table. |
|
|
55
|
+
| Full shape of one object, including relationships | `sf sobject describe --sobject <Type>`, only when you need all of it. It is very large. | Same |
|
|
56
|
+
| Every object in the org | `sf sobject list --sobject all` or `--sobject custom` | Same |
|
|
57
|
+
| Every member of a type, or a count ("all flows", "how many flows") | `sf org list metadata --metadata-type <Type>` | Same |
|
|
58
|
+
| Source to edit or deploy, including changes to existing metadata | Load `platform-metadata-retrieve`. Grounding never returns source. | Tell the user this needs the `sf` CLI. |
|
|
59
|
+
| Metadata you are already editing locally | Local files | |
|
|
60
|
+
| Compare orgs, find drift, or an overview of a whole org when the user asks for one | `dx-org-analyze`. It takes minutes and returns names and counts. | Tell the user this needs the `sf` CLI. |
|
|
61
|
+
| Where is this used, what depends on it, what breaks if I change it, or is it safe to delete | Comprehensive analysis is not available yet. State that boundary before offering explicitly labeled partial checks. | |
|
|
62
|
+
|
|
63
|
+
**Without the CLI.** If you cannot run commands but the Salesforce MCP is connected, use `references/h360-routes.md` for rows 3 to 6. If neither is available, tell the user the lookup needs the `sf` CLI or the Salesforce MCP.
|
|
64
|
+
|
|
65
|
+
These routes apply even when a connected server says to use it first for every Salesforce task. Use the CLI for rows 3 to 7 when you can run commands.
|
|
66
|
+
|
|
67
|
+
A question about a topic or purpose ("what do we have for loyalty") is discovery, not an overview. Do not run an org analysis for it, even when grounding is not available.
|
|
68
|
+
|
|
69
|
+
This skill covers core platform metadata. For Data Cloud DLO and DMO schema, use `data360-code-extension-generate`.
|
|
70
|
+
|
|
71
|
+
When a request mixes intents, use the right tool for each part. "Add a tier discount step to our order flow" means finding the flow and the field, then retrieving the flow to edit.
|
|
72
|
+
|
|
73
|
+
## Scoped SOQL
|
|
74
|
+
|
|
75
|
+
Scoped SOQL is a targeted query on setup objects, filtered to what you need. It is exact, real time, and far smaller than a describe. It never returns source.
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
sf data query --json --query "SELECT QualifiedApiName, Label, DataType FROM EntityParticle WHERE EntityDefinition.QualifiedApiName = 'Contact'"
|
|
79
|
+
sf data query --json --query "SELECT Value, Label, IsDefaultValue, IsActive FROM PicklistValueInfo WHERE EntityParticle.EntityDefinition.QualifiedApiName = 'Contact' AND EntityParticle.QualifiedApiName = 'Loyalty_Tier__c'"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
- To check specific fields, add `AND QualifiedApiName IN ('Loyalty_Tier__c', 'Lifetime_Orders__c')`. For custom fields only, add `AND QualifiedApiName LIKE '%__c'`.
|
|
83
|
+
- `EntityParticle` includes parts of compound fields, such as `MailingCity`.
|
|
84
|
+
- Add `--use-tooling-api` for `CustomField` and `ValidationRule`.
|
|
85
|
+
- `EntityDefinition`, `EntityParticle`, and `FieldDefinition` do not accept `OR`. Run one scoped query per condition instead of broadening the query or removing its object/type filters.
|
|
86
|
+
|
|
87
|
+
More patterns, including access and automation, are in `references/scoped-soql.md`.
|
|
88
|
+
|
|
89
|
+
## When Grounding Is Not Available
|
|
90
|
+
|
|
91
|
+
Say the line below once per session, in your answer, next to the results of the name and label search. Do not announce the fallback before you search, and do not repeat it later in the session. Use the line that matches the cause, word for word, including the last sentence. Do not shorten or rephrase it. If you stop before you can report results, say it in that message instead.
|
|
92
|
+
|
|
93
|
+
| Cause | Say |
|
|
94
|
+
|---|---|
|
|
95
|
+
| No grounding server connected | "Metadata Grounding isn't connected, so I matched by name and label, which can miss metadata named differently. Connect the Metadata Grounding MCP to search by meaning." |
|
|
96
|
+
| Catalog not enabled | "Salesforce Catalog isn't turned on in this org, so I matched by name and label, which can miss metadata named differently. An admin can turn on Salesforce Catalog through Feature Manager in Data Cloud Setup." |
|
|
97
|
+
| Permission missing | "Catalog search needs the Customize Application permission, so I matched by name and label, which can miss metadata named differently." |
|
|
98
|
+
|
|
99
|
+
Then search names and labels. Try two or three likely words, one `LIKE` per query.
|
|
100
|
+
|
|
101
|
+
```text
|
|
102
|
+
sf data query --json --query "SELECT QualifiedApiName, Label FROM EntityDefinition WHERE Label LIKE '%loyalty%'"
|
|
103
|
+
sf data query --json --query "SELECT QualifiedApiName, Label, DataType FROM EntityParticle WHERE EntityDefinition.QualifiedApiName = 'Contact' AND Label LIKE '%tier%'"
|
|
104
|
+
sf data query --json --use-tooling-api --query "SELECT DeveloperName, EntityDefinition.QualifiedApiName FROM CustomField WHERE DeveloperName LIKE '%tier%' AND NamespacePrefix = null"
|
|
105
|
+
sf data query --json --query "SELECT ApiName, Label, ProcessType, IsActive FROM FlowDefinitionView WHERE Label LIKE '%order%'"
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
- The `CustomField` query searches custom fields on every object. `DeveloperName` has no `__c`. Drop rows with no object name. They are Data Cloud fields.
|
|
109
|
+
- For other types, and for types the catalog does not cover, list names with `sf org list metadata` and scan them.
|
|
110
|
+
- Name matching misses metadata labeled differently. A search for "status" will not find a field labeled Loyalty Tier. Say "no name match found," never "does not exist."
|
|
111
|
+
|
|
112
|
+
Everything else in this skill still applies.
|
|
113
|
+
|
|
114
|
+
## Reuse Before You Create
|
|
115
|
+
|
|
116
|
+
Before you create an object, field, picklist, permission set, page, app, or flow:
|
|
117
|
+
|
|
118
|
+
1. Search by business meaning for existing metadata that stores the same data or does the same job. For a field, first search `SObject` for the exact object API name, then pass that result's returned `identifier` as `parentIdentifier` to the `SObjectField` search. Never pass the raw object API name as `parentIdentifier`. A proposed API name or label is only an exact collision check and does not prove that equivalent metadata is absent. Similar words alone are not enough to declare a match.
|
|
119
|
+
2. **If you find matches:** show up to 3, best first, with API name, label, description, and type. Do not accept or reject an ambiguous match from its name alone. Offer to reuse, extend, or create new in one consolidated reuse checkpoint covering every type you plan to create, then wait. Do not combine this checkpoint with values or other generation-specific questions.
|
|
120
|
+
3. **After the user decides:** preserve the decision for the request and do not ask again unless the scope changes or new conflicting evidence appears. For reuse, stop creation and inspect configuration only if needed. For extension, inspect the existing component before asking for changes. For new metadata, collect the required configuration and continue with the generation guidance.
|
|
121
|
+
4. **If nothing matches:** say so in one line and continue.
|
|
122
|
+
5. **If the user gave an exact API name:** check it with scoped SOQL and say if it already exists.
|
|
123
|
+
6. **If the user asked for new metadata or said not to reuse:** mention close matches in one line at most and continue.
|
|
124
|
+
|
|
125
|
+
Treat namespaced items, such as `force__` permission sets or managed package components, as references, not things to edit. Say so when a match is managed.
|
|
126
|
+
|
|
127
|
+
## Ground Code in Real Org Names
|
|
128
|
+
|
|
129
|
+
Before you write Apex, LWC, SOQL, or Flow logic, confirm every object, field, and picklist value it references.
|
|
130
|
+
|
|
131
|
+
- Skip references already in the local project, already confirmed in this conversation, or standard fields every org has (such as `Account.Name` or `Contact.Email`).
|
|
132
|
+
- Always look up picklist values, including on standard fields. Never invent values.
|
|
133
|
+
- Values shown only as examples in a skill, tool description, or prior assistant response are not user-approved values. If the user has not explicitly supplied or approved the values or an existing value set, ask once and wait before creating the picklist.
|
|
134
|
+
- If the request depends on an order or meaning the values do not state ("the top tier"), list the values and ask.
|
|
135
|
+
- Look up all references for a request together.
|
|
136
|
+
|
|
137
|
+
## Existing Automation
|
|
138
|
+
|
|
139
|
+
- **To find automation by what it does,** search `Flow` or `ApexClass` by meaning. A grounding query on a flow shows its trigger object, trigger type, and active status.
|
|
140
|
+
- **To list everything that runs on an object** before adding automation:
|
|
141
|
+
|
|
142
|
+
```text
|
|
143
|
+
sf data query --json --query "SELECT Name, Status FROM ApexTrigger WHERE TableEnumOrId = 'Contact'"
|
|
144
|
+
sf data query --json --query "SELECT ApiName, Label, TriggerType, IsActive FROM FlowDefinitionView WHERE TriggerObjectOrEventId = 'Contact'"
|
|
145
|
+
```
|
|
146
|
+
- **To understand what a flow or trigger does,** retrieve its source and read it.
|
|
147
|
+
|
|
148
|
+
## What You Can Explain
|
|
149
|
+
|
|
150
|
+
| Question | Answer with |
|
|
151
|
+
|---|---|
|
|
152
|
+
| What exists that does X | Grounding search |
|
|
153
|
+
| How a field, object, or validation rule is configured | Grounding query, or `EntityParticle` and Tooling `ValidationRule` |
|
|
154
|
+
| Who can read or edit a field or object | Grounding on `FieldPermissions`, or SOQL on `FieldPermissions` and `ObjectPermissions` for a complete list. These records prove configured access, not actual use; a permission container's name does not prove an integration or dependency is active. |
|
|
155
|
+
| Sharing rules, roles, groups, and which package a component came from | Grounding |
|
|
156
|
+
| What a flow is | Grounding gives the header only (type, trigger, active). For its steps, retrieve the source. |
|
|
157
|
+
| What an Apex class does | Grounding gives signatures only. Retrieve the source. |
|
|
158
|
+
| Why a save failed | A partial answer. Check validation rules on the object, then retrieve the automation that runs on it. |
|
|
159
|
+
| Page layouts, reports, custom metadata types, custom settings | Not in the catalog. Use `sf org list metadata` and retrieve. |
|
|
160
|
+
| Where something is used, what depends on it, what breaks if it changes, or whether it is safe to delete | Comprehensive analysis is not available yet. Say so before any checks. You may offer narrow checks, but label each one as partial and never present their union as complete or conclude that the change is safe. |
|
|
161
|
+
|
|
162
|
+
## Working With Skills
|
|
163
|
+
|
|
164
|
+
- This skill decides what already exists. Build skills decide how to create it. Run discovery before any skill writes files.
|
|
165
|
+
- If a loaded skill has its own equivalent semantic reuse check, use it instead of the matching step here. Do not run both. An exact-name or exact-label collision check is not equivalent and does not replace semantic reuse discovery.
|
|
166
|
+
- Two exceptions, even when a skill says otherwise: always look up picklist values, and check names, types, or picklist values you know with scoped SOQL instead of a full object describe.
|
|
167
|
+
- If a skill's discovery step fails or its tool is not available, use the routes in this skill and tell the user once.
|
|
168
|
+
|
|
169
|
+
## Freshness and Local Files
|
|
170
|
+
|
|
171
|
+
- Reuse discovery results for the rest of the conversation unless that item has changed.
|
|
172
|
+
- The catalog can take several minutes to reflect deploys and other org changes. For anything changed in this session, trust the local source and deploy results, and confirm with SOQL, which is real time. If the user reports a change SOQL does not show, ask them to confirm the name and org before you write code that uses it.
|
|
173
|
+
- When the metadata you need is not in the local project, retrieve it before editing, and tell the user you did.
|
|
174
|
+
- If you learn the org version differs from local in ways you did not make, for example from a retrieve or a deploy conflict, show the difference and ask before you overwrite either one.
|
|
175
|
+
- When scanning local source for references, read the package directories from `sfdx-project.json` and search those directories. Exclude response exports, logs, generated output, caches, and agent configuration unless the user explicitly asks to inspect them.
|
|
176
|
+
- Searching local files finds exact text only. Do not use it to find org metadata by meaning.
|
|
177
|
+
|
|
178
|
+
## Never
|
|
179
|
+
|
|
180
|
+
- Write or deploy files built from grounding query output. It returns properties, not source.
|
|
181
|
+
- Treat grounding results as a complete list. They are ranked and capped.
|
|
182
|
+
- Say metadata does not exist because a search or a name match found nothing.
|
|
183
|
+
- Combine results from two different orgs.
|
|
184
|
+
- Present partial dependency or reference checks as a complete impact analysis, or conclude from them that metadata is safe to change or delete.
|
|
185
|
+
- Treat illustrative values from examples, skills, or tool descriptions as user-approved metadata.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# What Each Route Calls
|
|
2
|
+
|
|
3
|
+
For engineers and reviewers. The skill names tools, not APIs, because the agent picks tools. Read from sf CLI 2.150.6 and jsforce source, and checked live on 2026-10-07.
|
|
4
|
+
|
|
5
|
+
| Route | API call |
|
|
6
|
+
|---|---|
|
|
7
|
+
| `sf sobject list` | REST `describeGlobal` (`GET /services/data/vXX.0/sobjects`), filtered to custom or all on the client |
|
|
8
|
+
| `sf sobject describe` | REST describe SObject (`GET /services/data/vXX.0/sobjects/<Type>/describe`). Tooling describe with `--use-tooling-api` |
|
|
9
|
+
| `sf org list metadata` | Metadata API `listMetadata` (SOAP) |
|
|
10
|
+
| `sf data query` | REST query resource (`GET /services/data/vXX.0/query`). Tooling query resource with `--use-tooling-api` |
|
|
11
|
+
| `sf project retrieve start` | Metadata API `retrieve` (SOAP) |
|
|
12
|
+
| Metadata grounding search | `GET /services/data/vXX.0/metadata-grounding/search` |
|
|
13
|
+
| Metadata grounding describe | `POST /services/data/vXX.0/metadata-grounding/schema` |
|
|
14
|
+
| Metadata grounding query | `POST /services/data/vXX.0/metadata-grounding/query` |
|
|
15
|
+
|
|
16
|
+
## Which Surface Reaches Which Call
|
|
17
|
+
|
|
18
|
+
| Call | `sf` CLI | Metadata Grounding MCP | Salesforce MCP |
|
|
19
|
+
|---|---|---|---|
|
|
20
|
+
| REST and Tooling query | Yes | No | Yes, `dispatch_readonly` |
|
|
21
|
+
| REST describe and object list | Yes | No | Yes, `dispatch_readonly` |
|
|
22
|
+
| Metadata API `listMetadata` and `retrieve` | Yes | No | No |
|
|
23
|
+
| Metadata grounding | No. The grounding paths are reachable only through an MCP server, so a direct REST call returns not found | Yes | Yes, after `describe` on the operation id |
|
|
24
|
+
|
|
25
|
+
The skills do not use the Enterprise API, the SOAP API with the org-specific WSDL. None of these tools call it.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Routes Through the Salesforce MCP
|
|
2
|
+
|
|
3
|
+
Use this file when you reach the org through the Salesforce MCP. If you are in a terminal or IDE and can run the `sf` CLI, the CLI routes work as well.
|
|
4
|
+
|
|
5
|
+
Grounding itself is covered in `platform-metadata-grounding-get`. This file covers the routes the skill body sends to the CLI.
|
|
6
|
+
|
|
7
|
+
## How to Call
|
|
8
|
+
|
|
9
|
+
Use `dispatch_readonly` with `method: GET`. Pass the path as `url` and the SOQL as the `q` query parameter, not appended to the URL.
|
|
10
|
+
|
|
11
|
+
| Route | `url` | Query parameters |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| Standard SOQL | `/services/data/v66.0/query` | `q`: the SOQL |
|
|
14
|
+
| Tooling SOQL | `/services/data/v66.0/tooling/query` | `q`: the SOQL |
|
|
15
|
+
| Describe one object | `/services/data/v66.0/sobjects/<Type>/describe` | None |
|
|
16
|
+
|
|
17
|
+
The rows are in `body.records`. For a `COUNT()` query the number is in `body.totalSize` and `records` is empty. Every pattern in `scoped-soql.md` works through these paths.
|
|
18
|
+
|
|
19
|
+
## Route by Intent
|
|
20
|
+
|
|
21
|
+
| Intent | Through this server |
|
|
22
|
+
|---|---|
|
|
23
|
+
| Check names, types, or picklist values you know. Every field on one object. Data records | Standard SOQL. Use Tooling SOQL for `CustomField` and `ValidationRule`. |
|
|
24
|
+
| Full shape of one object, only when you need all of it | Describe one object. It is very large. |
|
|
25
|
+
| Every object in the org | Standard SOQL on `EntityDefinition`, for example `SELECT QualifiedApiName, Label FROM EntityDefinition WHERE QualifiedApiName LIKE '%__c'` for custom objects. Never call `/sobjects` for the full object list. It returned about 1.8 million characters in one test org. |
|
|
26
|
+
| Every member of a type, or a count | Tooling SOQL for Tooling types, for example `SELECT COUNT() FROM FlowDefinition`, or `ApexClass` and `ValidationRule`. To list flows with labels, use Standard SOQL on `FlowDefinitionView`. Other types cannot be listed through this server. Tell the user it needs the `sf` CLI in a terminal or IDE. |
|
|
27
|
+
| Source to edit or deploy | Not available through this server. Load `platform-metadata-retrieve` if it is available. Otherwise tell the user it needs the `sf` CLI in a terminal or IDE. |
|
|
28
|
+
| Compare orgs, find drift, or a whole-org overview | Not available through this server. Tell the user it needs the `sf` CLI. |
|
|
29
|
+
|
|
30
|
+
If a call fails with an authentication or session error, tell the user to reconnect the Salesforce MCP. If it fails as not found or not allowed, say so, and tell the user the lookup may need the `sf` CLI in a terminal or IDE.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Scoped SOQL Patterns
|
|
2
|
+
|
|
3
|
+
Run each query through the Salesforce MCP with `dispatch_readonly`, as Standard or Tooling SOQL per the table. The paths are in `ref:platform-metadata-discovery-get/references/h360-routes`. In a terminal or IDE, `sf data query --json --query "<SOQL>"` works too. Add `--use-tooling-api` where the table says Tooling, and `--target-org <alias>` when the user named an org other than the default.
|
|
4
|
+
|
|
5
|
+
## Objects and Fields
|
|
6
|
+
|
|
7
|
+
| Need | Query | API |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| Does this object exist | `SELECT QualifiedApiName, Label FROM EntityDefinition WHERE QualifiedApiName = 'Loyalty_Transaction__c'` | Standard |
|
|
10
|
+
| Several objects at once | `SELECT QualifiedApiName, Label FROM EntityDefinition WHERE QualifiedApiName IN ('Menu__c', 'Promotion__c')` | Standard |
|
|
11
|
+
| Every field on one object | `SELECT QualifiedApiName, Label, DataType FROM EntityParticle WHERE EntityDefinition.QualifiedApiName = 'Contact'` | Standard |
|
|
12
|
+
| Custom fields only | Add `AND QualifiedApiName LIKE '%__c'` to the query above | Standard |
|
|
13
|
+
| Check specific fields | Add `AND QualifiedApiName IN ('Loyalty_Tier__c', 'Email')` | Standard |
|
|
14
|
+
| Picklist values | `SELECT Value, Label, IsDefaultValue, IsActive FROM PicklistValueInfo WHERE EntityParticle.EntityDefinition.QualifiedApiName = 'Contact' AND EntityParticle.QualifiedApiName = 'Loyalty_Tier__c'` | Standard |
|
|
15
|
+
| Record types on an object | `SELECT Name, DeveloperName, IsActive FROM RecordType WHERE SobjectType = 'Contact'` | Standard |
|
|
16
|
+
|
|
17
|
+
`EntityParticle` includes parts of compound fields, such as `MailingCity`. A full field list for Contact is about a tenth the size of a describe.
|
|
18
|
+
|
|
19
|
+
## Name and Label Fallback
|
|
20
|
+
|
|
21
|
+
Use these only when grounding is not available. Try two or three likely words.
|
|
22
|
+
|
|
23
|
+
| Need | Query | API |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| Objects by label | `SELECT QualifiedApiName, Label FROM EntityDefinition WHERE Label LIKE '%loyalty%'` | Standard |
|
|
26
|
+
| Fields on one object by label | `SELECT QualifiedApiName, Label, DataType FROM EntityParticle WHERE EntityDefinition.QualifiedApiName = 'Contact' AND Label LIKE '%tier%'` | Standard |
|
|
27
|
+
| Custom fields on every object by name | `SELECT DeveloperName, EntityDefinition.QualifiedApiName FROM CustomField WHERE DeveloperName LIKE '%tier%' AND NamespacePrefix = null` | Tooling |
|
|
28
|
+
| Flows by label | `SELECT ApiName, Label, ProcessType, IsActive FROM FlowDefinitionView WHERE Label LIKE '%order%'` | Standard |
|
|
29
|
+
| Permission sets by label | `SELECT Name, Label FROM PermissionSet WHERE IsOwnedByProfile = false AND Label LIKE '%loyalty%'` | Standard |
|
|
30
|
+
|
|
31
|
+
- `EntityDefinition`, `EntityParticle`, and `FieldDefinition` do not accept `OR`. The query fails with "Disjunctions not supported." Run one query per word.
|
|
32
|
+
- `CustomField` accepts `OR`. `DeveloperName` has no `__c`. Drop rows with no object name. They are Data Cloud fields.
|
|
33
|
+
|
|
34
|
+
## Access
|
|
35
|
+
|
|
36
|
+
| Need | Query | API |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| Who can read or edit a field | `SELECT Parent.Label, Parent.IsOwnedByProfile, Parent.Profile.Name, PermissionsRead, PermissionsEdit FROM FieldPermissions WHERE SobjectType = 'Contact' AND Field = 'Contact.Loyalty_Tier__c'` | Standard |
|
|
39
|
+
| Who can use an object | `SELECT Parent.Label, Parent.IsOwnedByProfile, Parent.Profile.Name, PermissionsRead, PermissionsCreate, PermissionsEdit, PermissionsDelete FROM ObjectPermissions WHERE SobjectType = 'Loyalty_Transaction__c'` | Standard |
|
|
40
|
+
|
|
41
|
+
When `Parent.IsOwnedByProfile` is true, the row belongs to a profile. Read the name from `Parent.Profile.Name`, because `Parent.Label` is an id for those rows. A field or object with no row for a profile or permission set has no access through it.
|
|
42
|
+
|
|
43
|
+
## Automation and Rules
|
|
44
|
+
|
|
45
|
+
| Need | Query | API |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| Triggers on an object | `SELECT Name, Status FROM ApexTrigger WHERE TableEnumOrId = 'Contact'` | Standard |
|
|
48
|
+
| Flows that run on an object | `SELECT ApiName, Label, TriggerType, IsActive FROM FlowDefinitionView WHERE TriggerObjectOrEventId = 'Contact'` | Standard |
|
|
49
|
+
| Validation rules on an object | `SELECT ValidationName, Active, ErrorMessage FROM ValidationRule WHERE EntityDefinition.QualifiedApiName = 'Contact'` | Tooling |
|
|
50
|
+
| Count of flows | `SELECT COUNT() FROM FlowDefinition` | Tooling |
|
|
51
|
+
|
|
52
|
+
These return names and status, not logic. To read what a flow, trigger, or rule does, retrieve its source.
|