@salesforce/afv-skills 1.41.0 → 1.43.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 +2 -6
- package/skills/automation-sandbox-post-copy-config-generate/SKILL.md +3 -0
- package/skills/automation-sandbox-post-copy-configure/SKILL.md +4 -0
- package/skills/design-systems-slds-validate/SKILL.md +2 -2
- package/skills/dx-app-analytics-query/SKILL.md +1 -3
- package/skills/dx-devops-conflict-resolve/SKILL.md +205 -0
- package/skills/dx-devops-conflict-resolve/examples/conflict-workflows.md +165 -0
- package/skills/dx-devops-conflict-resolve/references/deploy-failure-resolution.md +75 -0
- package/skills/dx-devops-conflict-resolve/references/git-conflict-resolution.md +124 -0
- package/skills/dx-devops-conflict-resolve/scripts/detect-conflicts.sh +91 -0
- package/skills/dx-devops-conflict-resolve/scripts/diagnose-deploy-failure.sh +156 -0
- package/skills/dx-devops-request-status/SKILL.md +160 -0
- package/skills/dx-devops-request-status/examples/polling-workflows.md +101 -0
- package/skills/dx-devops-request-status/references/cli-commands.md +176 -0
- package/skills/dx-devops-request-status/scripts/poll-status.sh +134 -0
- package/skills/dx-devops-test-failures-analyze/SKILL.md +6 -6
- package/skills/dx-devops-test-pipeline-configure/SKILL.md +7 -7
- package/skills/dx-devops-test-suite-assignments-configure/SKILL.md +6 -6
- package/skills/dx-devops-test-suite-run/SKILL.md +6 -6
- package/skills/dx-devops-work-item-manage/SKILL.md +2 -0
- package/skills/dx-org-manage/references/creating-scratch-org.md +5 -2
- package/skills/dx-org-manage/references/creating-snapshot.md +1 -0
- package/skills/dx-org-shape-manage/SKILL.md +152 -0
- package/skills/dx-org-shape-manage/examples/create_error_output.json +9 -0
- package/skills/dx-org-shape-manage/examples/create_success_output.json +9 -0
- package/skills/dx-org-shape-manage/examples/delete_output.json +11 -0
- package/skills/dx-org-shape-manage/examples/list_inactive_output.json +32 -0
- package/skills/dx-org-shape-manage/examples/list_output.json +24 -0
- package/skills/dx-org-shape-manage/references/cli_flags.md +135 -0
- package/skills/dx-org-switch/SKILL.md +2 -2
- package/skills/dx-org-trial-expiration-check/SKILL.md +2 -0
- package/skills/dx-pkg-post-install-configure/SKILL.md +3 -0
- package/skills/education-cloud-multi-campus-configure/SKILL.md +211 -0
- package/skills/education-cloud-multi-campus-configure/examples/hierarchy_visualization.md +174 -0
- package/skills/education-cloud-multi-campus-configure/examples/output_examples.md +54 -0
- package/skills/education-cloud-multi-campus-configure/examples/sample_hierarchy_input.csv +29 -0
- package/skills/education-cloud-multi-campus-configure/examples/sample_hierarchy_input_edgecases.csv +16 -0
- package/skills/education-cloud-multi-campus-configure/references/account_recordtype_prerequisite.md +44 -0
- package/skills/education-cloud-multi-campus-configure/references/delta_computation.md +33 -0
- package/skills/education-cloud-multi-campus-configure/references/error_handling.md +198 -0
- package/skills/education-cloud-multi-campus-configure/references/foundation_prerequisites.md +54 -0
- package/skills/education-cloud-multi-campus-configure/references/gotchas.md +16 -0
- package/skills/education-cloud-multi-campus-configure/references/hierarchy_parsing_rules.md +133 -0
- package/skills/education-cloud-multi-campus-configure/references/mcp-invocation.md +75 -0
- package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/SKILL.md +1 -1
- package/skills/experience-cms-brand-apply/SKILL.md +4 -1
- package/skills/experience-cms-brand-create/SKILL.md +197 -0
- package/skills/experience-cms-brand-create/assets/brand-template.json +329 -0
- package/skills/experience-cms-brand-create/references/brand-anatomy.md +120 -0
- package/skills/experience-cms-brand-create/references/disk-contract.md +84 -0
- package/skills/experience-cms-content-generate/SKILL.md +190 -0
- package/skills/experience-cms-content-generate/assets/display-formats.md +84 -0
- package/skills/experience-cms-content-generate/assets/payloads/create-content-bulk.json +11 -0
- package/skills/experience-cms-content-generate/assets/payloads/create-content-single.json +11 -0
- package/skills/experience-cms-content-generate/assets/payloads/publish-content.json +4 -0
- package/skills/experience-cms-content-generate/assets/payloads/update-content.json +9 -0
- package/skills/experience-cms-content-generate/assets/questions.md +241 -0
- package/skills/experience-cms-content-generate/examples/create-content-call.md +81 -0
- package/skills/experience-cms-content-generate/references/bulk-batching.md +56 -0
- package/skills/experience-cms-content-generate/references/content-type-classification.md +88 -0
- package/skills/experience-cms-content-generate/references/content-write-tool.md +95 -0
- package/skills/experience-cms-content-generate/references/delegation-protocol.md +37 -0
- package/skills/experience-cms-content-generate/references/edit-publish-workflow.md +63 -0
- package/skills/experience-cms-content-generate/references/error-recovery.md +72 -0
- package/skills/experience-cms-content-generate/references/identifier-resolution.md +26 -0
- package/skills/experience-cms-content-generate/references/intent-routing.md +45 -0
- package/skills/experience-cms-content-generate/references/principles.md +19 -0
- package/skills/experience-cms-content-generate/references/ux-rules.md +68 -0
- package/skills/experience-cms-content-generate/references/workspace-resolution.md +33 -0
- package/skills/experience-cms-content-type-generate/SKILL.md +449 -0
- package/skills/experience-cms-content-type-generate/assets/discovery-prompts.md +79 -0
- package/skills/experience-cms-content-type-generate/assets/schema-example.json +70 -0
- package/skills/experience-cms-content-type-generate/references/agent-checklist.md +50 -0
- package/skills/experience-cms-content-type-generate/references/anti-patterns.md +39 -0
- package/skills/experience-cms-content-type-generate/references/deployment-errors.md +27 -0
- package/skills/experience-cms-content-type-generate/references/discovery-details.md +106 -0
- package/skills/experience-cms-content-type-generate/references/discovery-query-rules.md +85 -0
- package/skills/experience-cms-content-type-generate/references/edit-fields-loop.md +48 -0
- package/skills/experience-cms-content-type-generate/references/pre-deploy-checklist.md +21 -0
- package/skills/experience-cms-content-type-generate/references/retrieve-and-reconcile.md +105 -0
- package/skills/experience-cms-content-type-generate/references/schema-rules.md +51 -0
- package/skills/experience-cms-content-type-generate/references/schema-summary-format.md +60 -0
- package/skills/experience-lds-graphql-generate/SKILL.md +4 -0
- package/skills/experience-lwc-accessibility-jest-run/SKILL.md +79 -0
- package/skills/experience-lwc-accessibility-jest-run/references/running-sa11y-jest-tests.md +205 -0
- package/skills/experience-lwc-design-generate/SKILL.md +5 -4
- package/skills/experience-lwc-generate/SKILL.md +10 -9
- package/skills/experience-ui-bundle-deploy/references/dev-preview.md +21 -0
- package/skills/experience-ui-bundle-deploy/references/social-login.md +1 -0
- package/skills/experience-ui-bundle-file-upload-generate/SKILL.md +6 -6
- package/skills/experience-ui-bundle-localize/SKILL.md +30 -37
- package/skills/experience-ui-bundle-localize/references/gotchas.md +23 -7
- package/skills/experience-ui-bundle-localize/references/i18n-setup.md +48 -4
- package/skills/experience-ui-bundle-localize/references/label-xml.md +22 -8
- package/skills/experience-ui-bundle-localize/references/verifying.md +39 -11
- package/skills/experience-ui-bundle-localize/scripts/detect-bundle-type.sh +118 -15
- package/skills/experience-ui-bundle-localize/scripts/tests/test-detect-bundle-type.sh +187 -0
- package/skills/experience-ui-bundle-mfa-configure/SKILL.md +13 -2
- package/skills/experience-ui-bundle-mfa-configure/references/social-login.md +1 -0
- package/skills/experience-ui-bundle-project-generate/SKILL.md +2 -2
- package/skills/integration-connectivity-generate/SKILL.md +11 -10
- package/skills/integration-eventing-cdc-configure/SKILL.md +6 -6
- package/skills/integration-eventing-subscription-configure/SKILL.md +6 -5
- package/skills/mobile-platform-native-capabilities-integrate/SKILL.md +2 -2
- package/skills/mobile-platform-offline-validate/scripts/package.json +1 -1
- package/skills/platform-agentexchange-partner-offers-configure/SKILL.md +8 -8
- package/skills/platform-custom-application-generate/SKILL.md +2 -0
- package/skills/platform-custom-field-generate/SKILL.md +8 -6
- package/skills/platform-custom-metadata-type-generate/SKILL.md +460 -0
- package/skills/platform-custom-metadata-type-generate/references/cmdt-records.md +251 -0
- package/skills/platform-custom-metadata-type-generate/scripts/sanitize-developer-name.sh +46 -0
- package/skills/platform-custom-setting-generate/SKILL.md +419 -0
- package/skills/platform-dataspace-access-configure/SKILL.md +3 -3
- package/skills/platform-sharing-owd-configure/SKILL.md +3 -0
- package/skills/platform-value-set-generate/SKILL.md +2 -0
- package/skills/service-agentforce-channel-configure/SKILL.md +29 -20
- package/skills/service-agentforce-channel-configure/assets/BotEmailDefinition.botEmailDefinition-meta.xml +36 -0
- package/skills/service-agentforce-channel-configure/assets/email/unfiled$public/AgentforceForServiceEmailTemplate.email +17 -0
- package/skills/service-agentforce-channel-configure/assets/email/unfiled$public/AgentforceForServiceEmailTemplate.email-meta.xml +29 -0
- package/skills/service-agentforce-channel-configure/assets/mdapi-package.xml +25 -0
- package/skills/service-agentforce-channel-configure/assets/settings-mdapi-package.xml +30 -0
- package/skills/service-agentforce-channel-configure/references/agent-wiring.md +20 -0
- package/skills/service-agentforce-channel-configure/references/botemaildefinition.md +107 -0
- package/skills/service-agentforce-channel-configure/references/channel-branch-email.md +203 -50
- package/skills/service-agentforce-channel-configure/references/channel-types.md +30 -3
- package/skills/service-agentforce-channel-configure/references/queue-resolution.md +17 -8
- package/skills/service-agentforce-channel-configure/references/routing-flow.md +14 -3
- package/skills/service-agentforce-channel-configure/scripts/validate-botemaildefinition.py +126 -0
- package/skills/service-agentforce-channel-configure/scripts/validate-emailtemplate.py +133 -0
- package/skills/service-de-channel-activate/SKILL.md +271 -0
- package/skills/service-de-channel-activate/references/gotchas.md +31 -0
- package/skills/service-de-channel-activate/references/phone-verification.md +96 -0
- package/skills/service-de-channel-activate/references/worked-examples.md +14 -0
- package/skills/service-de-channel-consent-configure/SKILL.md +230 -0
- package/skills/service-de-channel-consent-configure/references/gotchas.md +41 -0
- package/skills/service-de-channel-consent-configure/references/language-keywords.md +84 -0
- package/skills/service-de-channel-consent-configure/references/worked-examples.md +134 -0
- package/skills/service-de-channel-create/SKILL.md +369 -0
- package/skills/service-de-channel-create/references/apple.md +59 -0
- package/skills/service-de-channel-create/references/connect-insert.md +84 -0
- package/skills/service-de-channel-create/references/facebook.md +154 -0
- package/skills/service-de-channel-create/references/line.md +66 -0
- package/skills/service-de-channel-create/references/sms.md +98 -0
- package/skills/service-de-channel-create/references/whatsapp.md +98 -0
- package/skills/service-de-channel-create/references/worked-examples.md +70 -0
- package/skills/service-de-channel-routing-configure/SKILL.md +345 -0
- package/skills/service-de-channel-routing-configure/references/asa-routing.md +90 -0
- package/skills/service-de-channel-routing-configure/references/gotchas.md +27 -0
- package/skills/service-de-channel-routing-configure/references/queue-creation.md +123 -0
- package/skills/service-de-channel-routing-configure/references/target-locate.md +98 -0
- package/skills/service-de-channel-routing-configure/references/worked-examples.md +174 -0
- package/skills/service-de-headless-channel-configure/SKILL.md +305 -0
- package/skills/service-de-headless-channel-configure/references/gotchas.md +27 -0
- package/skills/service-de-headless-channel-configure/references/inputs.md +49 -0
- package/skills/service-de-headless-channel-configure/references/output-envelopes.md +53 -0
- package/skills/service-de-headless-channel-configure/references/partial-success.md +24 -0
- package/skills/service-de-headless-channel-configure/references/terms-and-conditions.md +54 -0
- package/skills/service-de-headless-channel-configure/references/worked-examples.md +108 -0
- package/skills/service-de-waba-integrate/SKILL.md +227 -0
- package/skills/service-digital-engagement-channel-configure/scripts/check-api-version.sh +29 -0
- package/skills/service-digital-engagement-messaging-site-integrate/SKILL.md +10 -9
- package/skills/service-digital-engagement-messaging-site-integrate/references/lwr_patch.md +39 -21
- package/skills/service-digital-engagement-messaging-site-integrate/scripts/patch_lwr_bundle.sh +157 -96
- package/skills/service-email-to-case-configure/SKILL.md +190 -0
- package/skills/service-email-to-case-configure/assets/CaseSettings.settings-meta.xml +45 -0
- package/skills/service-email-to-case-configure/examples/CaseSettings-two-addresses.settings-meta.xml +36 -0
- package/skills/service-email-to-case-configure/references/apply-mechanics.md +73 -0
- package/skills/service-email-to-case-configure/references/routing_address_reference.md +73 -0
- package/skills/service-email-to-case-configure/references/troubleshooting.md +25 -0
- package/skills/service-email-to-case-configure/scripts/apply-casesettings.py +1315 -0
- package/skills/service-email-to-case-configure/scripts/check-agent-email-capability.sh +26 -0
- package/skills/service-email-to-case-configure/scripts/tests/__init__.py +0 -0
- package/skills/service-email-to-case-configure/scripts/tests/_bootstrap.py +45 -0
- package/skills/service-email-to-case-configure/scripts/tests/_fakeorg.py +366 -0
- package/skills/service-email-to-case-configure/scripts/tests/_run.py +84 -0
- package/skills/service-email-to-case-configure/scripts/tests/test_apply_org_scenarios.py +655 -0
- package/skills/service-email-to-case-configure/scripts/tests/test_get_session.py +134 -0
- package/skills/service-email-to-case-configure/scripts/tests/test_new_capabilities.py +193 -0
- package/skills/service-email-to-case-configure/scripts/tests/test_validate_casesettings.py +170 -0
- package/skills/service-email-to-case-configure/scripts/validate-casesettings.py +229 -0
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +33 -15
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +63 -47
- package/skills/service-itsm-agentic-setup-agentforce-studio-configure/SKILL.md +17 -12
- package/skills/service-itsm-agentic-setup-agentforce-studio-configure/references/cli-invocation.md +5 -3
- package/skills/service-itsm-agentic-setup-agentforce-studio-configure/scripts/classify-enable-plan.mjs +11 -3
- package/skills/service-itsm-agentic-setup-agentforce-studio-validate/SKILL.md +8 -6
- package/skills/service-itsm-agentic-setup-agentforce-studio-validate/references/cli-invocation.md +3 -3
- package/skills/service-itsm-agentic-setup-agentforce-studio-validate/scripts/classify-readiness.mjs +11 -3
- package/skills/service-itsm-agentic-setup-configure/SKILL.md +5 -5
- package/skills/service-itsm-agentic-setup-configure/examples/output-templates.md +5 -5
- package/skills/service-itsm-agentic-setup-employee-agent-configure/SKILL.md +2 -2
- package/skills/service-itsm-agentic-setup-employee-agent-configure/references/report-format.md +11 -7
- package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/render-report.mjs +20 -7
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/SKILL.md +10 -6
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/action-availability.md +7 -7
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/report-format.md +11 -7
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/build-create-body.mjs +24 -17
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-action-availability.mjs +98 -58
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/render-report.mjs +20 -7
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/strip-release-management.mjs +176 -0
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/SKILL.md +19 -19
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/cli-invocation.md +3 -4
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/helper-contracts.md +6 -6
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/permset-topology.md +3 -10
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/scripts/classify-permset-availability.mjs +7 -9
- package/skills/service-itsm-incident-mgmt-configure/SKILL.md +2 -0
- package/skills/service-itsm-incident-priority-configure/SKILL.md +15 -12
- package/skills/service-itsm-incident-priority-configure/examples/matrix-operations.md +27 -1
- package/skills/service-itsm-incident-priority-configure/references/sf-cli-invocation.md +37 -6
- package/skills/service-native-voice-recording-transcription-configure/SKILL.md +146 -0
- package/skills/service-native-voice-recording-transcription-configure/assets/confirmation-output.json +16 -0
- package/skills/service-native-voice-recording-transcription-configure/assets/package.xml +22 -0
- package/skills/service-native-voice-recording-transcription-configure/references/thunderbird-voice-settings.md +101 -0
- package/skills/service-native-voice-recording-transcription-configure/scripts/enable-recording-transcription.sh +181 -0
- package/skills/data360-activate/README.md +0 -38
- package/skills/data360-activate/SKILL.md +0 -127
- package/skills/data360-connect/README.md +0 -57
- package/skills/data360-connect/SKILL.md +0 -163
- package/skills/data360-connect/examples/connections/heroku-postgres.json +0 -15
- package/skills/data360-connect/examples/connections/ingest-api-connection.json +0 -5
- package/skills/data360-connect/examples/connections/ingest-api-schema.json +0 -31
- package/skills/data360-connect/examples/connections/redshift.json +0 -16
- package/skills/data360-connect/examples/connections/sharepoint-unstructured.json +0 -20
- package/skills/data360-connect/examples/connections/snowflake-connection.json +0 -42
- package/skills/data360-harmonize/README.md +0 -31
- package/skills/data360-harmonize/SKILL.md +0 -126
- package/skills/data360-orchestrate/README.md +0 -120
- package/skills/data360-orchestrate/SKILL.md +0 -263
- package/skills/data360-orchestrate/assets/definitions/activation-target.template.json +0 -5
- package/skills/data360-orchestrate/assets/definitions/activation.template.json +0 -7
- package/skills/data360-orchestrate/assets/definitions/calculated-insight.template.json +0 -7
- package/skills/data360-orchestrate/assets/definitions/data-action-target.template.json +0 -5
- package/skills/data360-orchestrate/assets/definitions/data-action.template.json +0 -5
- package/skills/data360-orchestrate/assets/definitions/data-graph.template.json +0 -21
- package/skills/data360-orchestrate/assets/definitions/data-stream.template.json +0 -55
- package/skills/data360-orchestrate/assets/definitions/dmo.template.json +0 -17
- package/skills/data360-orchestrate/assets/definitions/identity-resolution.template.json +0 -30
- package/skills/data360-orchestrate/assets/definitions/mapping.template.json +0 -14
- package/skills/data360-orchestrate/assets/definitions/relationship.template.json +0 -12
- package/skills/data360-orchestrate/assets/definitions/search-index.template.json +0 -9
- package/skills/data360-orchestrate/assets/definitions/segment.template.json +0 -16
- package/skills/data360-orchestrate/references/feature-readiness.md +0 -157
- package/skills/data360-orchestrate/references/plugin-setup.md +0 -138
- package/skills/data360-orchestrate/scripts/bootstrap-plugin.sh +0 -53
- package/skills/data360-orchestrate/scripts/diagnose-org.mjs +0 -511
- package/skills/data360-orchestrate/scripts/generate-manifest.mjs +0 -68
- package/skills/data360-orchestrate/scripts/verify-plugin.sh +0 -58
- package/skills/data360-prepare/README.md +0 -50
- package/skills/data360-prepare/SKILL.md +0 -203
- package/skills/data360-prepare/examples/ingestion-api/.env.example +0 -8
- package/skills/data360-prepare/examples/ingestion-api/README.md +0 -48
- package/skills/data360-prepare/examples/ingestion-api/send-data.py +0 -144
- package/skills/data360-query/README.md +0 -43
- package/skills/data360-query/SKILL.md +0 -128
- package/skills/data360-query/examples/search-indexes/hybrid-structured.json +0 -44
- package/skills/data360-query/examples/search-indexes/vector-knowledge.json +0 -43
- package/skills/data360-segment/README.md +0 -35
- package/skills/data360-segment/SKILL.md +0 -123
- package/skills/service-helpagent-coordinate/references/channel-help-portal.md +0 -22
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-1-1-non-text-content.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-i-lists.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-ii-tables.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-iii-form-labels.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-iv-regions.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-v-groups.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-5-identify-input.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-4-3-contrast.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-1-1-keyboard.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-4-4-link-purpose.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-4-6-headings-labels.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-5-1-pointer-gestures.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-5-2-pointer-cancellation.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-5-3-label-in-name.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-5-7-dragging-movement.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-2-1-on-focus.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-2-2-on-input.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-3-1-error-identification.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-3-2-labels-instructions.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-3-3-error-suggestion.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-4-1-2-i-name.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-4-1-2-ii-role.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-4-1-2-iii-value.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-1-1-non-text-content.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-4-1-use-of-color.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-4-10-resize-reflow.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-4-11-non-text-contrast.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-4-3-contrast.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/scripts/contrast-ratio.py +0 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Steps 8, 9, 10 — full detail (edit, publish, post-publish)
|
|
2
|
+
|
|
3
|
+
SKILL.md keeps the entry rule and route summary for each of these steps. This file holds the full procedural detail. All three are **MCP-only — no SOQL, no CLI.**
|
|
4
|
+
|
|
5
|
+
## Step 8: Edit Workflow
|
|
6
|
+
|
|
7
|
+
**MCP-only — no SOQL, no CLI.** Read via `content-readonly` (`get_content`/`get_content_variant`), write via `content-write` `update_cms_content_variant`. Never `sf data query`, SOQL, or CLI to find/read/update a record. Resolving by name is not permitted (Step 0-U gate).
|
|
8
|
+
|
|
9
|
+
**8a. Determine edit scope.** For single content (or if user names a specific item by number): edit that one item. For bulk content: dispatch the Step 8a scope prompt from `assets/questions.md`. If the user selects "Specific items (by number)", follow up with the item-number prompt.
|
|
10
|
+
|
|
11
|
+
**8b. Get edit instructions from user.** Dispatch the Step 8b edit-instructions prompt from `assets/questions.md`. Wait for the user's response — this is the edit instruction. The same instruction applies to all selected items; the server-side pipeline adapts it against each item's existing content.
|
|
12
|
+
|
|
13
|
+
**8c. Build the update payload.** Use `assets/payloads/update-content.json`. Per selected item:
|
|
14
|
+
- `variantId` — the `managedContentVariantId` from that item's latest `create_cms_content`/`update_cms_content_variant` response, **or the ID captured at Step 0-U** (direct-entry, record not created this session). Either source, same shape.
|
|
15
|
+
- `prompt` — the edit instruction verbatim; the server reads the existing `contentBody` for that variant and applies it.
|
|
16
|
+
- `title` — re-emit ONLY when the edit clearly targets the title ("rename to X"); otherwise omit so the server keeps the existing value. Never regenerate `title` on unrelated edits.
|
|
17
|
+
- Optional (`urlName`, `apiName`) only when the user named them.
|
|
18
|
+
|
|
19
|
+
**8d. Dispatch `update_cms_content_variant`.** One call per selected item; for bulk, all N in parallel (each carries its own `variantId` + `prompt`).
|
|
20
|
+
|
|
21
|
+
**8e. Check the result.** On success: go back to **Step 6** — display the **full updated content body**, every field, using the single-content summary + content-body tables from `assets/display-formats.md` (the same format used at fetch time). **Do NOT print a change-summary / diff table** (a "Field | Change" list of only what changed) in place of the body — the user must see the complete post-edit record, all properties, not just the edited ones. Source the body correctly: if `update_cms_content_variant`'s response echoes the full `contentBody`, display that; if the response carries only IDs / partial fields, **re-fetch the variant with `content-readonly` `get_content_variant` (param `variantId`) and display that body.** Never reconstruct the body from memory or from the edit instruction — display server-returned values only. Then proceed to **Step 7** (post-action loop). This allows iterative editing. **Step 7 dispatches the `ask_user_tool` post-action prompt — clickable options, never a plain-text "what's next" line.** The turn does not end at the display; it ends at the dispatched dialog.
|
|
22
|
+
|
|
23
|
+
On partial failure (bulk): register successful edits, surface failures, and dispatch the retry prompt from `assets/questions.md`.
|
|
24
|
+
|
|
25
|
+
On failure: surface the error and ask the user via `ask_user_tool`: `Retry / Refine edit instruction and retry / Cancel`. If unrecoverable **on a bulk edit** (all N `update_cms_content_variant` calls failed in the same dispatch turn), apply the "Bulk total-failure retry guards" in `references/error-recovery.md` before dispatching a retry prompt — the guards select the correct total-failure prompt variant from `assets/questions.md`. Single-content edit failures use the plain `Retry / Refine edit instruction and retry / Cancel` prompt unchanged.
|
|
26
|
+
|
|
27
|
+
## Step 9: Publish Workflow
|
|
28
|
+
|
|
29
|
+
**MCP-only — no SOQL, no CLI.** Resolve/confirm via `content-readonly`, publish via `content-write` `publish_content`. Never `sf data query`, SOQL, or CLI to find/publish a record.
|
|
30
|
+
|
|
31
|
+
**9a. Determine publish scope.**
|
|
32
|
+
|
|
33
|
+
- `Publish content` / `Publish all` → publish all items in the session content registry.
|
|
34
|
+
- `Publish subset` → user has already specified which items by number; use those variant IDs.
|
|
35
|
+
- Default behavior (no explicit scope) → publish all items.
|
|
36
|
+
|
|
37
|
+
**9b. Dispatch `publish_content`.** Use `assets/payloads/publish-content.json`. `publish_content` accepts `variantIds` (array of `managedContentVariantId`) or `contentIds` (array of `managedContentId`); this skill uses `variantIds`. In-session items carry a `managedContentVariantId` from their create/edit response; pass those (single content = one-element array; bulk = all selected variant IDs from the session content registry). **On the Step 0-P direct-entry path**, pass the validated `managedContentVariantId` resolved in Step 0-P (via `get_content` for a content key / `managedContentId`, or via `get_content_variant` for a `9Ps` variant ID). On this direct-entry path, after the publish confirmation, end the turn — do NOT proceed to Step 10's render handoff (there is no session `channelId` / UIBundle context for an externally-identified record).
|
|
38
|
+
|
|
39
|
+
**9c. Check the result and update the registry.** On success: for every `managedContentVariantId` that `publish_content` reports as published, update its registry entry's `publishStatus` from `draft` to `published`. This is a hard requirement — Step 10's render handoff filters on `publishStatus=published`, so items not marked published will be excluded from the render call. Then print a confirmation using `assets/display-formats.md` (single or bulk variant) and proceed to **Step 10**.
|
|
40
|
+
|
|
41
|
+
On partial failure (some items published, some failed): mark the successful items as `publishStatus=published` in the registry — leave the failed items at `publishStatus=draft`. Surface successes and failures separately, then dispatch the retry prompt from `assets/questions.md`. If the user retries, mark newly-published items on the retry response the same way.
|
|
42
|
+
|
|
43
|
+
On failure: surface the error. Common publish errors (channel not configured, permission denied, content validation failure) and their responses → `references/error-recovery.md`.
|
|
44
|
+
|
|
45
|
+
On a bulk publish total failure (every `managedContentVariantId` in the batch failed to publish), apply the "Bulk total-failure retry guards" in `references/error-recovery.md` before dispatching a retry prompt — the guards select the correct total-failure prompt variant from `assets/questions.md`. Single-content publish failures use the standard `Retry / Cancel` flow from the error-recovery rows above.
|
|
46
|
+
|
|
47
|
+
## Step 10: Post-Publish
|
|
48
|
+
|
|
49
|
+
After successful publish, dispatch the Step 10 prompt from `assets/questions.md`. The options depend on `workspaceMethod` recorded in Step 3 (`uibundle` variant includes the render option; `manual` variant hides it because there is no resolved `channelId` — the manual-workspace prompt tells the user why).
|
|
50
|
+
|
|
51
|
+
**In-session publish ALWAYS dispatches this prompt — both `workspaceMethod` values.** `manual` hides only the render option; it does NOT skip Step 10. Jumping straight to `Session ended.` after an in-session publish is a regression — the user loses `Create more content`. The `manual` variant still offers `Create more content / End session`. (The ONLY publish path that ends without Step 10 is the Step 0-P direct-entry path — a record not created this session, no session context.)
|
|
52
|
+
|
|
53
|
+
**Route on user response:**
|
|
54
|
+
- `Create more content` → restart the FULL workflow from **Step 1** as a fresh content creation — exactly as if the user had opened a new request. **Step 1 stays silent: do NOT ask "What would you like to create next?" or dispatch any `ask_user_tool`; end the turn and wait for the user's next message, then run Step 1 → Step 2 (type) → Step 3 (workspace) → create.** Do NOT reuse this run's resolved `contentSpaceOrFolderId`/`workspaceMethod` and do NOT print a "same space confirmed" line — Step 3 re-resolves the workspace normally on the new request. (The "don't re-ask workspace" rule applies ONLY within a single run's delegation path, never across a Create-more loop-back.)
|
|
55
|
+
- `Render it to the UI Bundle (...)` → collect the following data from the session and hand off to skill `experience-cms-content-render`:
|
|
56
|
+
- `channelId` — the channel ID returned by `get_or_create_cms_workspace_and_web_app_channel` in Step 3
|
|
57
|
+
- `contentKeys` — array of `contentKey` values from **only** the registry items with `publishStatus=published`. Draft items (never published, or failed to publish in Step 9c) MUST be excluded — a UI Bundle render is a live-content operation and drafts have no rendered URL. If a partial publish left some items as drafts, they are silently omitted from the handoff; the confirmation preceding this handoff should already have shown the user which items published successfully.
|
|
58
|
+
- `contentTypeFqn` — the content type FQN captured in Step 2
|
|
59
|
+
- `uiBundleDeveloperName` — the selected UIBundle's `developerName`
|
|
60
|
+
- `uiBundleMasterLabel` — the selected UIBundle's `masterLabel`
|
|
61
|
+
|
|
62
|
+
**If the filter produces zero `contentKeys`** (every item is still `draft` — e.g. every item in a bulk publish failed), do NOT invoke the render handoff. Print chat text: `No published items available to render. Publish at least one item before rendering.` Then re-dispatch the Step 10 prompt from `assets/questions.md`.
|
|
63
|
+
- `End session` → print one line: `Session ended.` and exit.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# `create_cms_content` / `update_cms_content_variant` / `publish_content` — error → fix mapping
|
|
2
|
+
|
|
3
|
+
When a call fails, read the returned error before retrying. Most failures are structural (wrong FQN, wrong workspace id, permission issue) — blind retries waste attempts.
|
|
4
|
+
|
|
5
|
+
This skill dispatches exclusively via the `prompt` channel; the server owns generation and validation. Field-level schema-validation errors are the server's responsibility. If any surface to the client, they are shown to the user via `ask_user_tool` (`Retry / Refine goal and retry / Cancel`) — the agent does NOT parse or regenerate rejected fields client-side.
|
|
6
|
+
|
|
7
|
+
## Common errors
|
|
8
|
+
|
|
9
|
+
| Error signal | Likely cause | Fix |
|
|
10
|
+
|--------------|--------------|-----|
|
|
11
|
+
| `INVALID_TYPE` / "Content type not found" / 404 on type | `contentType` value is the masterLabel (not the FQN); or the type isn't deployed in the target org; or, on the Step-2 fast-path, the user-provided FQN doesn't resolve in this org. | Surface the error verbatim. Then dispatch `ask_user_tool`: `Try a different FQN` / `Discover a type via natural language (delegates to experience-cms-content-type-generate)` / `Cancel`. On "Try a different FQN" — collect via `ask_user_tool` and re-run from Step 3 with the new FQN. On "Discover a type…" — invoke `experience-cms-content-type-generate` with the original user intent (as if the fast-path had not fired). Do NOT retry the same FQN silently. |
|
|
12
|
+
| `INVALID_ID` / "Content space not found" / 404 on space | `contentSpaceOrFolderId` is wrong, stale, or from a different org. | Ask the user to confirm the workspace ID they provided belongs to the connected org — do NOT read `ui-bundle.json`. Don't reuse an id from an example or another tenant. |
|
|
13
|
+
| `UNKNOWN_EXCEPTION` / "These content type(s) X are not supported by this space" | The type is deployed in the org but not configured on the workspace's allowed-types list. | Stop and ask the user. Three viable paths: **(a)** different workspace that supports the type, **(b)** different type from the workspace's supported list (re-run discovery filtered to this workspace if possible), or **(c)** deploy a new type and update workspace channel config (the deploy is delegated to `experience-cms-content-type-generate`; the workspace-config update is **out of scope** — surface that the user must do it manually or via workspace tooling). Do **not** retry the same payload — it will keep failing. |
|
|
14
|
+
| Server-side schema/content validation error (any field-level rejection surfaced to the client) | The server-side generation pipeline could not produce a valid body from the `prompt`, or the user's edit instruction violated the type's schema. | Surface the error verbatim. Ask via `ask_user_tool`: `Retry / Refine goal and retry / Cancel`. On "Refine goal and retry" — collect a revised `[USER GOAL]` or edit instruction via `ask_user_tool` and redispatch. Do NOT parse the error or regenerate specific fields client-side. |
|
|
15
|
+
| `INSUFFICIENT_ACCESS` / 403 | The current user lacks CMS authoring permission in this workspace. | Surface the error and exit — this is an org-permission concern the skill can't fix. |
|
|
16
|
+
| Empty/garbage content from the server | The user's `[USER GOAL]` was too sparse. | Surface the result and ask the user to re-run with more detail via `ask_user_tool`: `Refine goal and retry / Cancel`. |
|
|
17
|
+
| Tool returns an unfamiliar shape | The MCP server's surface may differ across IDE namespaces. | Re-read `references/content-write-tool.md`. Confirm the canonical tool id is `create_cms_content`. |
|
|
18
|
+
| `UNKNOWN_EXCEPTION` / "Content generation is not supported for content type '<fqn>' (type class: '<class>')" | The type belongs to a type class that `create_cms_content` / `update_cms_content_variant` cannot generate a body for at all — e.g. `sfdc_cms__media` (`sfdc_cms__image`, `sfdc_cms__video`, and other media-class types). This is a fixed capability limit of the type class, not a per-request, per-org, or per-workspace problem. Rewording the prompt, retrying, switching workspaces, or picking a different FQN for the *same* type will never succeed — and there is no in-scope way to complete the original request. | **Terminal — hard stop, same shape as Step 0-D.** Print **exactly and only** this message, with `<fqn>` and `<class>` filled in from the server error, nothing else: <br>`Content generation isn't supported for content type \`<fqn>\` (type class: \`<class>\`). This skill can't author that type class. To create or edit this content, use the Salesforce CMS UI directly.` <br>**Say NOTHING before or after the message** — no preamble, no reasoning, no alternatives, no meta-narration. Do NOT propose the Connect REST API, a direct `contentBody` payload, or any other client-side workaround — Principle 3 means this agent never constructs `contentBody` itself, and suggesting that path is a bigger violation than the original error. Do NOT dispatch the standard `Retry / Refine goal and retry / Cancel` prompt — refining the goal cannot change what the type class supports. Do NOT delegate to `experience-cms-content-type-generate` (this is not a type-discovery or schema gap) and do NOT auto-substitute a different FQN. Then end the turn. If the user wants to try an unrelated content type, that is a new request — resume at Step 2 only if they explicitly name one. |
|
|
19
|
+
|
|
20
|
+
## Workflow-level errors (create/update/publish + orchestration)
|
|
21
|
+
|
|
22
|
+
| Error signal | Response |
|
|
23
|
+
|---|---|
|
|
24
|
+
| Sibling returned `status: not_deployed` | Bundle is local-only; `create_cms_content` will fail with `INVALID_TYPE` against a type that isn't in the org. STOP. Print the sibling's `message` verbatim ("Content type `<fqn>` isn't deployed to `<org>`. Deploy it and re-run."). Do NOT retry with a guessed FQN, do NOT continue to Step 3. |
|
|
25
|
+
| Sibling returned `status: cancelled` | User cancelled at a decision point inside the sibling. STOP silently. Print `Session ended.` and exit. Do NOT re-invoke the sibling. |
|
|
26
|
+
| Sibling returned `status: error` | Unrecoverable sibling failure (missing `sfdx-project.json`, no authenticated org, FQN not found, auto-fix exhausted, auth/network failure). STOP. Print the sibling's `message` verbatim — it already carries the specific reason and recovery hint. Do NOT retry or attempt a workaround. |
|
|
27
|
+
| Sibling returned `status: success` but `fqn` is missing or malformed | Contract violation from the sibling. STOP dispatch. Ask via `ask_user_tool`: `Retry with an explicit FQN / Cancel`. Do NOT invent an FQN from folder names or training data. |
|
|
28
|
+
| `metadata-grounding` unreachable during sibling discovery | Handled entirely by the sibling — it records `grounding=unavailable` and either routes to create-new or surfaces its own error message. This skill only reads the resulting `status`. |
|
|
29
|
+
| User asks to attach an image | Out of scope for this skill. Point the user to the CMS UI. |
|
|
30
|
+
| `get_content` returns `INVALID_ID_FIELD` on a `9Ps` value | Wrong read tool for a variant ID. `get_content` does not accept variant IDs — a `9Ps` identifier must be validated via `get_content_variant` (param `variantId`). Re-route to `get_content_variant`; do NOT publish/edit the ID blindly. |
|
|
31
|
+
| Direct-entry read (`get_content` / `get_content_variant`) fails — not-found, `INVALID_ID_FIELD`, or empty | The identifier the user supplied did not resolve to a real record. STOP. Tell the user the identifier didn't resolve and ask for a valid content key, `managedContentId`, or `managedContentVariantId`. Do NOT fall back to publishing/editing the unvalidated ID. |
|
|
32
|
+
| Identifier prefix matches no known form (`MC…` / `20Y…` / `9Ps`) | Cannot classify. Ask via `ask_user_tool` for a content key, `managedContentId`, or `managedContentVariantId`. Do NOT guess the read tool or the identifier form. |
|
|
33
|
+
| `update_cms_content_variant` returns 404 on `variantId` | The variant ID may be stale or from a different org. Surface error and ask user to verify. |
|
|
34
|
+
| `publish_content` returns channel not configured | The content type is not enabled for any channel. Ask user to check channel settings in CMS setup. |
|
|
35
|
+
| `publish_content` returns permission denied | User lacks CMS publish permissions. Surface error and suggest verifying permissions. |
|
|
36
|
+
| `publish_content` returns content validation failure | Surface the specific validation error. Ask via `ask_user_tool`: `Retry / Edit content / End session`. |
|
|
37
|
+
| Bulk `create_cms_content` partial failure — some of the N parallel calls succeeded, others failed | Register the successful items in the session content registry. Surface each failed item with its `[USER GOAL]` and error message. Ask via `ask_user_tool`: `Retry failed / Skip / End session`. When retrying, redispatch ONLY the failed items — each as its own fresh 1-element parallel `create_cms_content` call. Do NOT combine retries into a multi-item `inputs` array. Do NOT re-dispatch the successful items. |
|
|
38
|
+
| Bulk `create_cms_content` — a single call timed out or dropped connection | Only that one item is affected (blast radius = 1); every other parallel call is unaffected and its result already in hand. Retry just that item's payload as a fresh 1-element `create_cms_content` call. If the same item fails repeatedly, ask the user via `ask_user_tool`: `Refine goal and retry / Skip this item / End session`. |
|
|
39
|
+
| Bulk dispatch built a multi-element `inputs` array instead of N parallel 1-element calls | Documented regression — Step 5b requires exactly one `create_cms_content` call per item, each with a 1-element `inputs` array, all N dispatched in parallel. Do NOT dispatch. Rebuild as N separate 1-element payloads and fan them out in parallel in a single turn. Combining items into one `inputs` array violates the hard rule regardless of N (even N=2). |
|
|
40
|
+
| Bulk dispatch serialized the N calls (dispatch call 1, await, dispatch call 2, …) instead of fanning them out in parallel | Documented regression — Step 5b requires all N calls dispatched in the SAME turn in parallel. Serialization multiplies wall-clock by N and defeats the purpose. Rebuild as a single-turn parallel fan-out. |
|
|
41
|
+
| Bulk `update_cms_content_variant` partial failure | Register successful edits, surface failed items. Ask via `ask_user_tool`: `Retry failed / Skip / End session`. |
|
|
42
|
+
| Bulk `publish_content` partial failure | Surface successes and failures separately. Ask via `ask_user_tool`: `Retry failed / Skip / End session`. |
|
|
43
|
+
|
|
44
|
+
## Bulk total-failure retry guards
|
|
45
|
+
|
|
46
|
+
These two guards apply **ONLY** to the bulk-operation total-failure branch — all N parallel `create_cms_content` / `update_cms_content_variant` / `publish_content` calls failed in the same dispatch turn. They do NOT apply to partial-failure branches, single-content flows, or per-item errors. Partial success bypasses both guards entirely.
|
|
47
|
+
|
|
48
|
+
**Guard A — Uniform-error short-circuit.** Before dispatching any total-failure retry prompt, compare the failure signatures across all N failed calls. Two errors share a signature when their primary error signal matches — prefer the server's error code / status field (e.g. all `INVALID_TYPE`, all `INSUFFICIENT_ACCESS`, all `INVALID_ID`, all `UNKNOWN_EXCEPTION`); fall back to full error message-string equality when no code is present. Do NOT normalize whitespace or case — exact match keeps the check cheap and deterministic. Any doubt → fall through to Guard B.
|
|
49
|
+
|
|
50
|
+
- **All N errors share the same signature** → print chat text: `All <N> items failed with the same error: <verbatim error message>. This looks like a systemic issue rather than a per-item problem. Retrying is unlikely to help until it's resolved.` Then dispatch the **"Total failure — uniform error"** prompt from `assets/questions.md` (`End session` only). Do NOT offer `Retry all`.
|
|
51
|
+
- **Errors differ across the N calls** → fall through to Guard B.
|
|
52
|
+
|
|
53
|
+
**Guard B — Retry counter (mixed-error total failure).** Track a `totalFailureRetryCount` in session state, scoped to the current bulk-operation instance (one instance = the current run of Step 5b for create, Step 8d for edit, or Step 9b for publish). Counter starts at 0 on fresh entry and increments each time the user clicks `Retry all` and re-dispatch produces another total failure.
|
|
54
|
+
|
|
55
|
+
| Retry attempt | Counter value on entry to total-failure branch | Prompt to dispatch |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| Retry #1 (first total failure) | 0 | Standard **"Total failure"** prompt from `assets/questions.md` (`Retry all` / `End session`). |
|
|
58
|
+
| Retry #2 | 1 | Print chat text: `This is retry #2 with all <N> items still failing. Consider ending the session if the underlying issue isn't resolved.` Then dispatch the standard **"Total failure"** prompt. |
|
|
59
|
+
| Retry #3+ | ≥ 2 | Dispatch the **"Total failure — retry exhausted"** prompt from `assets/questions.md` (`End session` only). Do NOT offer `Retry all`. |
|
|
60
|
+
|
|
61
|
+
**Counter reset rules — refactor-safety.** The counter is per-bulk-operation-instance and must be reset to 0 in every one of these cases so no state leaks across independent bulk cycles:
|
|
62
|
+
|
|
63
|
+
- A new bulk operation starts (fresh entry into Step 5b, Step 8d, or Step 9b).
|
|
64
|
+
- Any dispatch produces a partial success (some of the N calls succeeded). Partial success routes to the partial-failure prompt, which is out of scope for these guards — the counter is discarded.
|
|
65
|
+
- The user selects `End session` at any total-failure prompt.
|
|
66
|
+
- The bulk cycle ends normally (transitions to Step 6 / Step 7 with all items in the registry).
|
|
67
|
+
|
|
68
|
+
The counter does NOT carry across separate bulk operations within the same session (e.g. bulk create followed by bulk edit — each gets its own counter).
|
|
69
|
+
|
|
70
|
+
**Guard application order.** Always check Guard A first (cheap comparison, deterministic exit). If Guard A does not fire, check Guard B. Never dispatch a `Retry all` option when either guard says to hide it.
|
|
71
|
+
|
|
72
|
+
**Scope reminder.** These guards live inside the total-failure branch only. The partial-failure branch (`Retry failed items` / `Skip and continue` / `End session`) is untouched — that flow already retries only the failed subset and does not enter this guard logic.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Identifier resolution — content key / managedContentId / variantId
|
|
2
|
+
|
|
3
|
+
Shared by **Step 0-U** (UPDATE entry) and **Step 0-P** (PUBLISH entry). Both `update_cms_content_variant` and `publish_content` act on a `managedContentVariantId`; every direct-entry path must validate + resolve the user-supplied identifier to one via a `content-readonly` read BEFORE touching the write tool. The read also confirms the record exists.
|
|
4
|
+
|
|
5
|
+
**Precondition:** the hard identifier gate in Step 0-U / 0-P has already run. This resolution only executes once an identifier is in hand (session registry, or a user-typed value). The name-only / no-identifier case is STOPPED at the gate — never search the org to turn a name into an ID.
|
|
6
|
+
|
|
7
|
+
## Classify by prefix, pick the read tool
|
|
8
|
+
|
|
9
|
+
| Prefix | Identifier | Validate + resolve with | Yields |
|
|
10
|
+
|--------|-----------|-------------------------|--------|
|
|
11
|
+
| `9Ps` | `managedContentVariantId` | `get_content_variant` — param `variantId` (pattern `^(9Ps)\w*`) | the same `managedContentVariantId` (confirmed to exist) |
|
|
12
|
+
| `MC…` | content key | `get_content` — accepts a content key | the record's `managedContentVariantId` |
|
|
13
|
+
| `20Y…` | `managedContentId` | `get_content` — accepts an ID | the record's `managedContentVariantId` |
|
|
14
|
+
|
|
15
|
+
Both read tools live on `content-readonly`. `get_content` does **not** accept a variant ID — a `9Ps` value MUST go to `get_content_variant`, never `get_content` (sending a `9Ps` to `get_content` returns `INVALID_ID_FIELD`). Both reads return the variant's current field values and `contentBody` — retain that body (Step 0-U displays it before asking for edits).
|
|
16
|
+
|
|
17
|
+
## On the read result
|
|
18
|
+
|
|
19
|
+
- **Read fails** (`INVALID_ID_FIELD`, not-found, empty) → the ID is invalid. STOP and tell the user the identifier did not resolve; ask via `ask_user_tool` for a valid content key / `managedContentId` / `managedContentVariantId`. Do NOT edit or publish blindly.
|
|
20
|
+
- **`9Ps` fails its pattern, or the prefix matches none of the three rows** → unrecognized. Ask via `ask_user_tool` for a valid identifier; do NOT guess or dispatch.
|
|
21
|
+
- **Success** → take the `managedContentVariantId` (for `9Ps`, the ID the user gave, now confirmed valid) and continue: Step 0-U → Step 8c; Step 0-P → Step 9b.
|
|
22
|
+
|
|
23
|
+
## Hard rules
|
|
24
|
+
|
|
25
|
+
- **Never run SOQL / `sf data query`** to look one up — these reads are the only resolution path.
|
|
26
|
+
- If the required read tool is unavailable on this bridge, apply the No-drift STOP rule (Step 0).
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Step 0 — intent routing: direct-entry UPDATE / PUBLISH / DELETE (full detail)
|
|
2
|
+
|
|
3
|
+
Step 0 of SKILL.md classifies the opening verb and routes. The routing table, the no-drift STOP summary, and the DELETE (0-D) exact message live in SKILL.md. This file holds the no-drift STOP message + per-route slot values, and the full procedural detail for the UPDATE (0-U) and PUBLISH (0-P) direct-entry paths — a record identified directly, possibly from any prior session.
|
|
4
|
+
|
|
5
|
+
## No-drift STOP rule — message + per-route slots
|
|
6
|
+
|
|
7
|
+
If a required `content-write` tool for the chosen route is not available on this bridge (`create_cms_content` for CREATE, `update_cms_content_variant` for UPDATE, `publish_content` for PUBLISH), **STOP.** Print the user-facing message below — filling the `<operation>` and `<tool>` slots for the current route — then end the turn. Do NOT substitute SOQL, `sf data`, a CLI call, a sibling tool, or the `contentBody` channel. Tool-unavailable and unsupported-operation are terminal — never a fallback trigger.
|
|
8
|
+
|
|
9
|
+
Slot values per route: CREATE → operation `create content`, tool `create_cms_content`; UPDATE → operation `update this content`, tool `update_cms_content_variant`; PUBLISH → operation `publish this content`, tool `publish_content`.
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
I can't <operation> — this needs the Salesforce CMS content-write service, which isn't connected to your workspace right now. That service provides the `<tool>` tool this step requires, and without it I've stopped rather than risk changing the wrong record another way.
|
|
13
|
+
|
|
14
|
+
To continue: connect the content-write MCP server to this workspace (check your MCP / tool configuration), then re-run your request.
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The message **MAY** name the CMS `content-write` service, the tool needed, and the fix (connect + re-run) — that lets the user self-serve. It **must NOT** quote the hard-stop rule or enumerate the rejected fallbacks (never "I can't substitute SOQL, CLI, or the contentBody channel").
|
|
18
|
+
|
|
19
|
+
## Step 0-U: UPDATE entry (record identified directly, may be from any prior session)
|
|
20
|
+
|
|
21
|
+
This is the direct-entry counterpart to the in-session edit at Step 8. This skill edits **any** existing record — one created this session OR in a prior session OR by another user. Editing is **not** session-only; a record you did not create is fully in scope. Do NOT conclude "the skill only edits session records, so I'll work with the tools directly" — that reasoning is the bug this step exists to prevent.
|
|
22
|
+
|
|
23
|
+
**Hard identifier gate — run BEFORE any tool call.** `update_cms_content_variant` targets one specific `managedContentVariantId`; the only ways to obtain it are (a) a session-registry entry for a record created/edited this session, or (b) an identifier the user typed. Decide in this order:
|
|
24
|
+
|
|
25
|
+
1. **Session-registry match?** If the user's phrasing clearly refers to an item already in the session content registry (e.g. "edit the one you just made", "change item 2"), use that entry's `managedContentVariantId` and route to **Step 8** — this is the in-session path, no user ID needed.
|
|
26
|
+
2. **Explicit identifier in the message?** If the user typed a content key (`MC…`), `managedContentId` (`20Y…`), or `managedContentVariantId` (`9Ps`), proceed to the resolve step below.
|
|
27
|
+
3. **Neither** — the user named the content by title/subject/description ("edit the Erling Haaland content", "update the vaccine article") with NO ID and it is NOT in the session registry → **STOP and ask.** Dispatch an `ask_user_tool`, answers `["Cancel"]`, `question` copied EXACTLY (one plain sentence — do NOT reformat into `- **Content Key**` bullets): `Which record should I work with? Paste the content key (starts with \`MC\`), the Managed Content ID (starts with \`20Y\`), or the Variant ID (starts with \`9Ps\`).` **You may NOT locate the record yourself** — do NOT call `search_content`, `get_spaces`, `get_content_types_for_workspace`, any discovery/listing tool, SOQL / `sf data query`, or a guessed variant ID. Searching the org to turn a name into an ID is forbidden — the ID comes from the user. Continue only after the user supplies an identifier.
|
|
28
|
+
|
|
29
|
+
Once an identifier is in hand (path 2, or path 3 after the user answers):
|
|
30
|
+
|
|
31
|
+
1. **Validate + resolve the `managedContentVariantId` by prefix, and retain the fetched body** — per `references/identifier-resolution.md` (`9Ps` → `get_content_variant`; `MC…`/`20Y…` → `get_content`). Keep the returned `contentBody` for the next step. Read fails → the ID is invalid, STOP and tell the user; do NOT edit blindly. Never run SOQL to look one up.
|
|
32
|
+
2. **Display the fetched content body — MANDATORY before asking for edits.** On this direct-entry path the user has not seen this record in the session, and a content type may carry a large number of properties. Print the current state using `assets/display-formats.md` — the single-content summary table followed by the content body table (iterate over every key in the fetched `contentBody`). This is what lets the user decide what to change. Do NOT print only the title / status — print the full body.
|
|
33
|
+
3. **Ask what to update** — dispatch the Step 8b edit-instructions prompt from `assets/questions.md` (the free-text, multi-property prompt). Wait for the user's response — that is the edit instruction. If the user's opening message already contained the edit instruction, skip the prompt and use it verbatim.
|
|
34
|
+
4. **Jump to Step 8c** with `{ variantId, prompt: <edit instruction> }` — the existing edit workflow (single-item path) handles payload build, dispatch, display, and the post-action loop. Do NOT run Steps 1–5 (no type discovery, no workspace resolution — the record already exists). Do NOT prompt for the render skill.
|
|
35
|
+
5. **Mandatory close — dispatch the dialog, never plain text.** After `update_cms_content_variant` succeeds and the body is displayed (Step 6), you MUST end the turn by dispatching the **Step 7 post-action `ask_user_tool` prompt** (single-content variant) from `assets/questions.md` — the clickable `Edit content / Publish content / End session` options. A plain-text "What's next?" line here is a regression — the direct-entry edit closes the same way the in-session edit does. Do not stop after the display.
|
|
36
|
+
|
|
37
|
+
## Step 0-P: PUBLISH entry (record identified directly, may be from any prior session)
|
|
38
|
+
|
|
39
|
+
Direct-entry counterpart to the in-session publish at Step 9. **The user may hand you any identifier for the content — a content key, a `managedContentId`, or a `managedContentVariantId`. Classify it by prefix, then validate + resolve it to a `managedContentVariantId` via the matching `content-readonly` read tool before publishing.** `publish_content` publishes by `variantIds`, so every path must end with a validated `managedContentVariantId`. Never publish an unvalidated ID — the read confirms the record exists first.
|
|
40
|
+
|
|
41
|
+
**Hard identifier gate — run BEFORE any tool call.** Same rule as Step 0-U: publishing needs a specific `managedContentVariantId` that comes from (a) the session registry or (b) an identifier the user typed. If the user's phrasing refers to a session-registry item, use it and route to **Step 9**. If the user typed an `MC…` / `20Y…` / `9Ps` identifier, proceed below. If the user named the content by title/subject with NO ID and it is NOT in the session registry → **STOP and dispatch an `ask_user_tool`, answers `["Cancel"]`, `question` copied EXACTLY (one plain sentence, no markdown bullets): `Which record should I work with? Paste the content key (starts with \`MC\`), the Managed Content ID (starts with \`20Y\`), or the Variant ID (starts with \`9Ps\`).` **Do NOT locate it yourself** — same no-org-search ban as Step 0-U (no discovery/listing tool, no SOQL, no guessed ID). Continue only once an identifier is in hand.
|
|
42
|
+
|
|
43
|
+
1. **Classify by prefix, validate + resolve to a `managedContentVariantId`** — per `references/identifier-resolution.md` (`9Ps` → `get_content_variant`; `MC…`/`20Y…` → `get_content`). Read fails / prefix unrecognized → STOP and ask the user for a valid identifier; do NOT publish blindly or guess. Never run SOQL.
|
|
44
|
+
2. **Jump to Step 9b** with that validated `managedContentVariantId` — the existing publish workflow handles dispatch and confirmation. Do NOT run Steps 1–5. Do NOT prompt for the render skill after publish on this direct-entry path.
|
|
45
|
+
3. **Close = the publish confirmation from `assets/display-formats.md`, then end the turn.** This direct-entry path is terminal — there is no Step 10 render handoff (no session `channelId` / UIBundle context for an externally-identified record). Do NOT append a plain-text "what's next" options list and do NOT dispatch a post-publish `ask_user_tool` — the confirmation statement is the final message.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Key Principles — full elaboration
|
|
2
|
+
|
|
3
|
+
The SKILL.md "Key Principles" list is the compressed index of these invariants; the operational detail also lives in each Step body. This file holds the long form for reference.
|
|
4
|
+
|
|
5
|
+
1. **Follow the workflow in order** — sequential steps. Step 1 silent parse; Step 2 fast-path (FQN in prompt) or sibling delegation; Step 3 workspace only after `contentTypeFqn` is captured. Asking workspace before Step 2, clarifying content type before Step 2, or delegating when an FQN was already provided are all documented failure modes.
|
|
6
|
+
2. **Dispatch is the work** — every successful run ends with `create_cms_content` returning a managed content record. Drafting content as chat prose without persisting is a bug.
|
|
7
|
+
3. **Server-side generation only** — both `create_cms_content` and `update_cms_content_variant` run on the `prompt` channel; the server generates + validates the body. The agent generates only the title (and re-emits it on edit only when the edit targets the title). The agent does NOT walk a schema, does NOT assemble `contentBody`, does NOT pre-validate client-side, and does NOT regenerate rejected fields client-side. `prompt` and `contentBody` are mutually exclusive — never send both.
|
|
8
|
+
4. **User goal verbatim as `prompt`** — pass the user's message (or approved topic prompt / edit instruction) to the tool as `prompt` unmodified. Do not paraphrase or trim.
|
|
9
|
+
5. **Sibling owns content type on the delegation path — route strictly on `status`** — `experience-cms-content-type-generate` is a black box. This skill consumes `{ status, fqn, message }`; the sibling may also emit `schema` but this skill ignores it. Only `success` continues; `not_deployed` / `cancelled` / `error` STOP with the sibling's `message` printed verbatim. On `success`, validate FQN format (Step 2c). Never call `metadata-grounding` yourself, re-present candidates, or construct FQNs from folder names. A `not_deployed` type is local-only and NOT dispatchable — do NOT proceed to Step 3 or try a guessed FQN ("the FQN is predictable, I'll just try" IS the bug); `create_cms_content` would fail `INVALID_TYPE`. (N/A on Buckets 1/2/3 — no sibling call.)
|
|
10
|
+
6. **Workspace from user or UIBundle** — `contentSpaceOrFolderId` comes from a user-selected local UIBundle (resolved via `get_or_create_cms_workspace_and_web_app_channel`) or a manually provided ID. **Never silently infer, never run SOQL / `sf data query` to discover spaces** — always present the UIBundle options and manual fallback, then let the user choose.
|
|
11
|
+
7. **Cancel terminates immediately** — a user `cancel` / `no` / `stop` / `End session` ends the workflow. Do not dispatch after a cancel.
|
|
12
|
+
8. **Consistent display format** — same table format after create and after edit; never switch mid-session.
|
|
13
|
+
9. **Track session content registry** — maintain `{title, managedContentId, managedContentVariantId, contentKey, publishStatus, index}` for every item created or edited. `publishStatus` starts as `draft` at create time and flips to `published` when Step 9c confirms the item was published server-side. The variant ID is stable across edits (versions bump, variants do not) — the same `managedContentVariantId` from `create_cms_content` remains valid for all subsequent `update_cms_content_variant` calls. Step 10's render handoff filters on `publishStatus=published`.
|
|
14
|
+
10. **Post-action loop is mandatory** — after every successful create or edit, display the content body and ask: Edit / Publish / End session. Never skip or auto-publish.
|
|
15
|
+
11. **Bulk = one call per item, in parallel — HARD RULE** — every `create_cms_content` call carries a 1-element `inputs` array; for N items, dispatch N parallel calls in a single turn. Do NOT combine items into a single `inputs` array (not even for N=2), do NOT serialize (dispatch-then-await-then-dispatch defeats parallelism), do NOT re-batch on retry. Same shape for `update_cms_content_variant`. Tool schema-prep happens silently — never narrate "Let me load the content creation tool".
|
|
16
|
+
12. **Publish defaults to all** — unless the user requests a subset, publish all items in the registry.
|
|
17
|
+
13. **Route the intent FIRST (Step 0)** — update / edit / publish / delete are first-class entry points, not only create-flow tails. When the user opens with one of those verbs, route at Step 0 and follow the named path. UPDATE-by-id enters at Step 8c, PUBLISH-by-id at Step 9b (skipping Steps 1–5, no type/workspace resolution, no render prompt). DELETE is a hard stop — no delete tool exists. Editing/publishing is NOT session-only — a record from a prior session or another user is in scope, but ONLY when an identifier is available (session registry OR a user-typed `MC…`/`20Y…`/`9Ps`). When the user names content by title/subject with no ID and nothing in the registry matches, STOP and ask for the identifier — you may NOT search the org to find it by name (no `search_content`, `get_spaces`, `get_content_types_for_workspace`, other discovery/listing tool, SOQL, or `sf data query`). Freelancing (picking tools by intuition, or hunting for the record by name, on an update/publish/delete open) is the bug this step prevents.
|
|
18
|
+
14. **No-drift STOP — never fall back** — if the required `content-write` tool for the route is unavailable (`update_cms_content_variant` / `publish_content` / `create_cms_content`), or the operation is unsupported (delete), STOP and print the actionable user-facing message (see Step 0 no-drift rule / Step 0-D). The message MAY name the CMS `content-write` service/server, the specific tool the step needs, and the fix (connect it + re-run) — that's what lets the user self-serve. It must NOT quote "the hard stop rule" or enumerate the rejected fallbacks. Never substitute SOQL, `sf data`, a CLI call, a sibling tool, or the `contentBody` channel. **Identifier handling:** when the user supplies any content identifier for update or publish, classify it by prefix and validate + resolve it to a `managedContentVariantId` via the matching `content-readonly` read tool before touching the write tool — `9Ps` (variant ID) → `get_content_variant` (param `variantId`); content key `MC…` or `managedContentId` `20Y…` → `get_content`. `get_content` does NOT accept a variant ID (a `9Ps` returns `INVALID_ID_FIELD`), so route `9Ps` values only to `get_content_variant`. Pass the resolved `managedContentVariantId` to `update_cms_content_variant` / `publish_content`. If the read fails, the ID is invalid — STOP and tell the user; never publish/edit an unvalidated ID. Never resolve via SOQL/CLI. If the required read tool is unavailable, apply this STOP rule; if the prefix matches no known form, ask the user for a valid identifier — do NOT guess.
|
|
19
|
+
15. **Type-class-unsupported is a hard stop** — when `create_cms_content` / `update_cms_content_variant` returns `UNKNOWN_EXCEPTION` "Content generation is not supported for content type '<fqn>' (type class: '<class>')" (e.g. `sfdc_cms__media` — covers `sfdc_cms__image`, `sfdc_cms__video`, and other media-class types), the type class itself cannot be authored via this tool on any org / workspace / prompt. This is a fixed capability limit, not a per-request, per-org, or per-workspace problem. This fires ONLY on the actual server error — never pre-empt it by guessing a type class from the prompt (dispatch `create_cms_content` normally; let the server return the error). Print the fixed message from `references/error-recovery.md` **verbatim, nothing else** — no retry prompt, no rewording, no preamble, no delegating to the type-generate sibling (this is not a type-discovery or schema gap), no swapping FQNs, and never propose a direct-API / hand-built `contentBody` workaround (that violates Principle 3 worse than the original error). Then end the turn.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# UX rules for `ask_user_tool`
|
|
2
|
+
|
|
3
|
+
## VERBATIM QUESTION CONTRACT — EVERY `ask_user_tool`, no exceptions
|
|
4
|
+
|
|
5
|
+
All questions go through `ask_user_tool`, never plain text. Each is a fixed template in `assets/questions.md`; before ANY `ask_user_tool` call, have that file open and copy BOTH the `question` string AND the `answers` array **character-for-character**, filling only `<placeholders>`. You may NOT:
|
|
6
|
+
- reword, shorten, expand, or re-punctuate the `question` — identical wording every run (the 6 different Step 3 phrasings in the trace are this bug);
|
|
7
|
+
- invent, rename, reorder, add, or drop `answers` — the set is fixed (`Approve / Edit topics / Cancel` vs `Looks good, create them / Let me adjust` drift is banned);
|
|
8
|
+
- put list/table content or per-item numbers INTO an answer. Answers are the fixed choices only — numbering a list into them (`"1 - Spider-Man"`, `"2 - The Batman"`) is forbidden (renders run-on, doubles the index). Variable lists go in a chat-text Part 1 (two-part pattern below); answers stay the template's fixed set.
|
|
9
|
+
|
|
10
|
+
No template covers it? STOP and re-read `assets/questions.md` — never compose one ad hoc.
|
|
11
|
+
|
|
12
|
+
## Asking Questions — MANDATORY UX Rule
|
|
13
|
+
|
|
14
|
+
**EVERY question to the user MUST use the `ask_user_tool` tool.** Never ask a question as plain text in your chat response. Plain-text questions look like the skill has finished and the user has no visual cue that they need to respond.
|
|
15
|
+
|
|
16
|
+
The `ask_user_tool` renders an interactive prompt with clickable answer options, making it unmistakable that the user must respond before the workflow continues.
|
|
17
|
+
|
|
18
|
+
| Wrong (plain text — looks like skill ended) | Correct (interactive tool) |
|
|
19
|
+
|---|---|
|
|
20
|
+
| Printing "Which content space should I create the content in?" as part of your response text | Calling `ask_user_tool` with `question: "Which content space or folder should I create the content in? Provide the ID (Content Space IDs start with `0Zu`; Folder IDs start with `9Pu`)."` |
|
|
21
|
+
|
|
22
|
+
This applies to ALL questions in the workflow — see `assets/questions.md` for every prompt template. The complete list of question points:
|
|
23
|
+
|
|
24
|
+
- Step 0-U / Step 0-P: identifier ask when the user named content by title with no ID (shared template, single sentence, `Cancel`-only)
|
|
25
|
+
- Step 2 (Bucket 3 only): FQN-correction confirmation
|
|
26
|
+
- Step 3: workspace question (UIBundle selection or manual ID)
|
|
27
|
+
- Step 3: invalid workspace ID re-ask (format-gate fail OR server-confirm fail — MUST say "invalid")
|
|
28
|
+
- Step 4.B.2: bulk topic approval
|
|
29
|
+
- Step 5a: bulk pre-dispatch blanket approval
|
|
30
|
+
- Step 7: post-action loop (Edit / Publish / End)
|
|
31
|
+
- Step 8a: edit scope selection
|
|
32
|
+
- Step 8b: edit instructions
|
|
33
|
+
- Step 7: publish subset selection
|
|
34
|
+
- Step 10: post-publish next action
|
|
35
|
+
|
|
36
|
+
## Formatting rule for `ask_user_tool`
|
|
37
|
+
|
|
38
|
+
The `question` field in `ask_user_tool` renders as a **single paragraph** — it does NOT support line breaks, markdown, or lists. Long content (like topic lists, error details, or summaries) becomes an unreadable wall of text inside the prompt.
|
|
39
|
+
|
|
40
|
+
**Pattern: Split complex questions into two parts:**
|
|
41
|
+
|
|
42
|
+
1. **Print structured content as formatted chat text** (markdown lists, tables, bold, code blocks — all render correctly in chat output).
|
|
43
|
+
2. **Then call `ask_user_tool` with ONLY a short question** (one sentence max).
|
|
44
|
+
|
|
45
|
+
| Wrong | Correct |
|
|
46
|
+
|---|---|
|
|
47
|
+
| Stuffing a numbered list into `ask_user_tool.question` | Print the list in chat text, then call `ask_user_tool` with just "Do these look good?" |
|
|
48
|
+
| Putting error details in `ask_user_tool.question` | Print error details in chat text, then call `ask_user_tool` with just "How would you like to proceed?" |
|
|
49
|
+
|
|
50
|
+
## FAILURE LOOK — recognize the rendering bug
|
|
51
|
+
|
|
52
|
+
The `question` field does NOT render markdown — it shows every character literally, on one line. Reformatting a templated sentence into markdown is the #1 reported UX defect.
|
|
53
|
+
|
|
54
|
+
**Broken (what NOT to produce)** — a `question` field containing:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
To create the content, provide one of the following: - **Content Space ID** (starts with `0Zu…`) - **Folder ID** (starts with `9Pu…`)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The user sees the literal `- **…**` — asterisks and dashes printed as text, no list, no bold. Looks broken.
|
|
61
|
+
|
|
62
|
+
**Correct** — dispatch the template's single sentence unchanged:
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
Which content space or folder should I create the content in? Provide the ID (Content Space IDs start with `0Zu`; Folder IDs start with `9Pu`).
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Same rule for the field-proposal table, topic lists, and error details: the structured part is printed as chat text FIRST (Part 1), and the `question` (Part 2) stays a single plain sentence. Never move a table or list into `question`.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Step 3 — workspace resolution (full detail)
|
|
2
|
+
|
|
3
|
+
Resolves `contentSpaceOrFolderId` (and, for a UIBundle, `channelId` + `workspaceMethod`). See SKILL.md Step 3 for WHEN it runs (fast-path: after Step 2; delegation path: early, as the first action of Step 2a, before the sibling is dispatched).
|
|
4
|
+
|
|
5
|
+
## Discovery (silent — no output to user)
|
|
6
|
+
|
|
7
|
+
Scan the project for `uiBundles/` directories — read each `packageDirectories[].path` from `sfdx-project.json` and scan under it; if no `sfdx-project.json` is present, fall back to a recursive search for `uiBundles/` directories. For each `uiBundles/` directory, iterate its subdirectories. For each subdirectory `<name>`, read `<name>/<name>.uibundle-meta.xml` and extract `<masterLabel>`. Build a list of `{ developerName: "<folder-name>", masterLabel: "<masterLabel from XML>" }`. If the `.uibundle-meta.xml` is missing or unreadable, use the folder name as both `developerName` and `masterLabel` fallback.
|
|
8
|
+
|
|
9
|
+
If the scan returns **zero** UIBundles, use the "no local UIBundles" variant from `assets/questions.md` — ask the user directly for a Content Space or Folder ID. Do NOT invent a workspace, do NOT run SOQL / `sf data query` against `ContentSpace` or any other object, do NOT read `ui-bundle.json` from disk. If nothing is on disk, the user provides the ID.
|
|
10
|
+
|
|
11
|
+
## Ask (single question)
|
|
12
|
+
|
|
13
|
+
Use the "Step 3 — Workspace resolution" templates in `assets/questions.md`. Dispatch via `ask_user_tool` — do NOT print as plain text.
|
|
14
|
+
|
|
15
|
+
## Routing
|
|
16
|
+
|
|
17
|
+
- **User selects a UIBundle** → call `get_or_create_cms_workspace_and_web_app_channel` with the selected UIBundle's `developerName` and `masterLabel`. Use the returned `spaceId` as `contentSpaceOrFolderId` for the rest of the workflow. **Record** `workspaceMethod=uibundle` and store the selected UIBundle's `developerName`, `masterLabel`, and the returned `channelId` for Step 10. **Then persist the `channelId` to disk** — write it into `uiBundles/<developerName>/public/content-metadata.json` under the `channelId` key. File-writing rules: if `public/` doesn't exist, create it; if `content-metadata.json` doesn't exist, create it as `{"channelId": "<value>"}`; if it exists, merge — preserve every existing key and overwrite ONLY the `channelId` value, do NOT delete or reformat other keys. On failure of the tool call itself, dispatch the retry prompt from `assets/questions.md`.
|
|
18
|
+
- **User selects "Provide a space or folder ID manually"** → **Record** `workspaceMethod=manual`. Dispatch the manual-ID prompt from `assets/questions.md` with a "Go back" clickable option. If the user clicks "Go back", re-present the original Step 3 question. Otherwise **validate the provided ID before using it** (see below). **Note:** with `workspaceMethod=manual` there is no resolved `channelId`, so the Step 10 "Render to UI Bundle" option is hidden — the user can still create, edit, and publish, but the render handoff requires selecting a UIBundle up front.
|
|
19
|
+
|
|
20
|
+
## Validate a user-provided workspace ID — MANDATORY before use
|
|
21
|
+
|
|
22
|
+
Never accept a manual Content Space / Folder ID blindly (the observed bug: a wrong ID was accepted with no check, then failed deep in `create_cms_content`). Two-layer validation:
|
|
23
|
+
|
|
24
|
+
1. **Format gate (client-side, before any tool call).** A valid Content Space ID starts with `0Zu`; a valid Folder ID starts with `9Pu`. The full ID must also be a well-formed Salesforce ID: prefix + only alphanumeric chars, exactly 15 or 18 chars total, no spaces. If the pasted value starts with neither prefix, OR is not 15/18 alphanumeric chars (e.g. `9Pualkskjhlkasdfjhlksdf` — right prefix but junk length), do NOT proceed and do NOT call any tool. Re-dispatch the **invalid-ID re-ask** template from `assets/questions.md` with `<reason>` = "it wasn't a 15- or 18-character `0Zu`/`9Pu` ID". Classify a passing ID by prefix: `0Zu` → `spaceId`; `9Pu` → `folderId`.
|
|
25
|
+
|
|
26
|
+
**Prefix + length is NECESSARY, NOT SUFFICIENT.** A perfectly well-formed `0Zu`/`9Pu` ID can still be fake, stale, deleted, or from a different org — the format gate cannot prove the space exists. Passing Layer 1 does NOT confirm the ID; only a server call does (Layer 2). Do NOT reason "the format looks right, so I'll proceed and validation will happen later at create" — that deferral IS the bug. The ID is unconfirmed until Layer 2 fires.
|
|
27
|
+
2. **Server confirmation — fires on the FIRST server call that touches the space, whichever comes first.** The ID is confirmed real only when that call succeeds:
|
|
28
|
+
- **Delegation path (Bucket 4):** the space is passed to the sibling's `get_content_types_for_workspace` BEFORE any content type is built. That is the first touch. If the sibling returns `INVALID_API_INPUT` / "'spaceId' must be a valid ManagedContentSpace id" / space-not-found, the space is invalid — **HARD STOP. Do NOT let the sibling build or deploy a content type on a bad space.** Surface the server error **verbatim**, then re-dispatch the **invalid-ID re-ask** template with `<reason>` = the server error text. Only after a corrected ID passes Layer 1 do you re-dispatch the sibling.
|
|
29
|
+
- **Fast path (Buckets 1/2/3):** the first touch is `create_cms_content`. If it returns `INVALID_ID` / "Content space not found" / an invalid cross-reference error, same handling — surface verbatim, re-ask via the invalid-ID template.
|
|
30
|
+
|
|
31
|
+
Do NOT retry the same ID. Do NOT defer confirmation past the first touch.
|
|
32
|
+
|
|
33
|
+
**Cross-reference / wrong-org error — do NOT improvise an org picker.** On an invalid cross-reference error, the ID belongs to a different org than the connected default. Surface the error verbatim and re-ask for the correct `0Zu`/`9Pu` ID via the manual-ID template ONLY. Do NOT run `sf org list`, do NOT enumerate available orgs, and do NOT invent an "Which org should I use?" question with an org list as answers — org selection is not this skill's job and that improvised prompt is a documented regression. The connected org is fixed; the user supplies an ID that belongs to it.
|