@salesforce/afv-skills 1.40.0 → 1.41.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.
Files changed (136) hide show
  1. package/package.json +1 -1
  2. package/skills/automation-flow-generate/SKILL.md +32 -43
  3. package/skills/experience-portal-create/SKILL.md +497 -0
  4. package/skills/experience-portal-create/assets/report-template.md +30 -0
  5. package/skills/experience-portal-create/references/mcp-invocation.md +288 -0
  6. package/skills/experience-portal-create/references/post-creation-activate-publish.md +165 -0
  7. package/skills/experience-portal-create/references/templates.md +253 -0
  8. package/skills/experience-ui-bundle-features-generate/SKILL.md +5 -1
  9. package/skills/experience-ui-bundle-frontend-generate/SKILL.md +2 -0
  10. package/skills/experience-ui-bundle-frontend-generate/references/page.md +1 -0
  11. package/skills/platform-datamask-run/SKILL.md +345 -0
  12. package/skills/platform-datamask-run/references/api-surface.md +130 -0
  13. package/skills/platform-datamask-run/references/policy-authoring.md +185 -0
  14. package/skills/platform-datamask-run/references/run-and-abort.md +116 -0
  15. package/skills/platform-datamask-run/scripts/poll-job.sh +115 -0
  16. package/skills/platform-dataspace-access-configure/SKILL.md +51 -3
  17. package/skills/platform-dataspace-access-configure/scripts/inspect-dataspace-scopes.sh +56 -0
  18. package/skills/platform-lightning-type-widget-coordinate/references/build-plan-format.md +1 -0
  19. package/skills/platform-sandbox-configure/SKILL.md +17 -2
  20. package/skills/platform-trial-org-create/SKILL.md +175 -0
  21. package/skills/platform-trial-org-create/examples/create_request.json +9 -0
  22. package/skills/platform-trial-org-create/examples/error_response.json +41 -0
  23. package/skills/platform-trial-org-create/examples/success_response.json +27 -0
  24. package/skills/platform-trial-org-create/references/error_codes.md +42 -0
  25. package/skills/platform-trial-org-create/references/signup_request_fields.md +69 -0
  26. package/skills/platform-trial-org-create/scripts/create_signup_request.sh +175 -0
  27. package/skills/platform-trial-org-create/scripts/get_signup_request.sh +155 -0
  28. package/skills/platform-widget-generate/SKILL.md +47 -6
  29. package/skills/platform-widget-generate/examples/conditional.json +3 -3
  30. package/skills/platform-widget-generate/examples/list-with-foreach.json +2 -2
  31. package/skills/platform-widget-generate/examples/single-object.json +2 -2
  32. package/skills/platform-widget-generate/references/widget-bundle-layout.md +1 -1
  33. package/skills/service-agentforce-channel-configure/SKILL.md +271 -0
  34. package/skills/service-agentforce-channel-configure/references/agent-wiring.md +97 -0
  35. package/skills/service-agentforce-channel-configure/references/channel-branch-email.md +145 -0
  36. package/skills/service-agentforce-channel-configure/references/channel-branch-voice.md +69 -0
  37. package/skills/service-agentforce-channel-configure/references/channel-types.md +61 -0
  38. package/skills/service-agentforce-channel-configure/references/live-traffic-gate.md +86 -0
  39. package/skills/service-agentforce-channel-configure/references/queue-resolution.md +135 -0
  40. package/skills/service-agentforce-channel-configure/references/routing-flow.md +384 -0
  41. package/skills/service-catalog-template-deploy/SKILL.md +310 -0
  42. package/skills/service-catalog-template-deploy/references/cli-invocation.md +258 -0
  43. package/skills/service-catalog-template-deploy/scripts/activate-verify.mjs +164 -0
  44. package/skills/service-catalog-template-deploy/scripts/build-deploy-payload.mjs +94 -0
  45. package/skills/service-catalog-template-deploy/scripts/resolve-template.mjs +331 -0
  46. package/skills/service-catalog-template-search/SKILL.md +212 -0
  47. package/skills/service-catalog-template-search/references/cli-invocation.md +128 -0
  48. package/skills/service-catalog-template-search/scripts/classify-catalog.mjs +205 -0
  49. package/skills/service-concierge-portal-generate/SKILL.md +126 -0
  50. package/skills/service-concierge-portal-generate/references/portal-deploy-runbook.md +1428 -0
  51. package/skills/service-digital-engagement-channel-configure/SKILL.md +46 -6
  52. package/skills/service-digital-engagement-channel-configure/assets/messaging_channel_template.xml +2 -1
  53. package/skills/service-digital-engagement-channel-configure/examples/asa_agent_channel.xml +4 -1
  54. package/skills/service-helpagent-coordinate/README.md +8 -2
  55. package/skills/service-helpagent-coordinate/SKILL.md +126 -130
  56. package/skills/service-helpagent-coordinate/assets/help-agent-spec.md +70 -53
  57. package/skills/service-helpagent-coordinate/references/agent-script.md +571 -457
  58. package/skills/service-helpagent-coordinate/references/channel-voice.md +38 -9
  59. package/skills/service-helpagent-coordinate/references/channel-web-chat.md +173 -49
  60. package/skills/service-helpagent-coordinate/references/output-report-format.md +126 -0
  61. package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +153 -0
  62. package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +79 -0
  63. package/skills/service-itsm-agentic-setup-agentforce-coordinate/scripts/verify-child-verdict.mjs +35 -0
  64. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/SKILL.md +271 -0
  65. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/references/cli-invocation.md +265 -0
  66. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/scripts/classify-enable-plan.mjs +220 -0
  67. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/scripts/classify-final-report.mjs +102 -0
  68. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/scripts/record-enable-result.mjs +73 -0
  69. package/skills/service-itsm-agentic-setup-agentforce-studio-validate/SKILL.md +206 -0
  70. package/skills/service-itsm-agentic-setup-agentforce-studio-validate/references/cli-invocation.md +194 -0
  71. package/skills/service-itsm-agentic-setup-agentforce-studio-validate/scripts/classify-readiness.mjs +223 -0
  72. package/skills/service-itsm-agentic-setup-cmdb-configure/SKILL.md +45 -7
  73. package/skills/service-itsm-agentic-setup-cmdb-configure/references/mcp-invocation.md +45 -5
  74. package/skills/service-itsm-agentic-setup-configure/SKILL.md +116 -0
  75. package/skills/service-itsm-agentic-setup-configure/examples/output-templates.md +64 -0
  76. package/skills/service-itsm-agentic-setup-employee-agent-configure/SKILL.md +158 -0
  77. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/cli-invocation.md +361 -0
  78. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/error-taxonomy.md +44 -0
  79. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/reactivation.md +66 -0
  80. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/report-format.md +66 -0
  81. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/specialized-templates.md +148 -0
  82. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/workflow-detail.md +169 -0
  83. package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/build-create-body.mjs +116 -0
  84. package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/classify-agent-existence.mjs +185 -0
  85. package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/classify-preflight.mjs +168 -0
  86. package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/create-scratch-dir.mjs +58 -0
  87. package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/render-report.mjs +197 -0
  88. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/SKILL.md +186 -0
  89. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/action-availability.md +51 -0
  90. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/cli-invocation.md +345 -0
  91. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/error-taxonomy.md +44 -0
  92. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/reactivation.md +63 -0
  93. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/report-format.md +44 -0
  94. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/workflow-detail.md +149 -0
  95. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/build-create-body.mjs +110 -0
  96. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-action-availability.mjs +201 -0
  97. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-activate-result.mjs +135 -0
  98. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-agent-existence.mjs +194 -0
  99. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-preflight.mjs +158 -0
  100. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/create-scratch-dir.mjs +58 -0
  101. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/render-report.mjs +191 -0
  102. package/skills/service-itsm-agentic-setup-incident-management/SKILL.md +133 -0
  103. package/skills/service-itsm-agentic-setup-incident-management/examples/output-templates.md +71 -0
  104. package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +308 -0
  105. package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/attach-milestone.json +23 -0
  106. package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/milestone-patterns.md +193 -0
  107. package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/output-templates.md +57 -0
  108. package/skills/service-itsm-agentic-setup-incident-sla-configure/references/mcp-invocation.md +394 -0
  109. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/SKILL.md +266 -0
  110. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/cli-invocation.md +106 -0
  111. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/helper-contracts.md +142 -0
  112. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/permset-topology.md +82 -0
  113. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/scripts/classify-action-surface.mjs +137 -0
  114. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/scripts/classify-assignment-state.mjs +99 -0
  115. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/scripts/classify-permset-availability.mjs +120 -0
  116. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/scripts/resolve-target-user.mjs +86 -0
  117. package/skills/service-itsm-agentic-setup-uel-user-create/SKILL.md +284 -0
  118. package/skills/service-itsm-agentic-setup-uel-user-create/references/mcp-invocation.md +302 -0
  119. package/skills/service-itsm-channels-coordinate/SKILL.md +472 -0
  120. package/skills/service-itsm-incident-mgmt-configure/SKILL.md +212 -0
  121. package/skills/service-itsm-incident-mgmt-configure/references/mcp-invocation.md +225 -0
  122. package/skills/service-itsm-incident-priority-configure/SKILL.md +53 -12
  123. package/skills/service-itsm-swarming-configure/SKILL.md +212 -0
  124. package/skills/service-itsm-teams-configure/SKILL.md +395 -0
  125. package/skills/service-itsm-teams-configure/references/azure-credential-population.md +213 -0
  126. package/skills/service-itsm-teams-configure/references/gotchas.md +23 -0
  127. package/skills/service-itsm-teams-coordinate/SKILL.md +175 -0
  128. package/skills/service-itsm-teams-coordinate/examples/output-templates.md +85 -0
  129. package/skills/service-itsm-teams-debug/SKILL.md +144 -0
  130. package/skills/service-itsm-teams-debug/references/configuration-checklists.md +277 -0
  131. package/skills/service-itsm-teams-debug/references/report-generation.md +95 -0
  132. package/skills/service-itsm-teams-employee-agent-configure/SKILL.md +139 -0
  133. package/skills/service-itsm-teams-employee-agent-configure/assets/Teams_AgentForce.EmbeddedServiceConfig-meta.xml +43 -0
  134. package/skills/service-itsm-teams-employee-agent-configure/references/teams-embedded-employee-agent.md +480 -0
  135. package/skills/service-itsm-teams-itdesk-configure/SKILL.md +232 -0
  136. package/skills/service-itsm-teams-itservice-configure/SKILL.md +391 -0
@@ -0,0 +1,175 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # create_signup_request.sh — Create a Salesforce trial org by inserting a
4
+ # SignupRequest sObject against an authenticated host org.
5
+ #
6
+ # This wraps the deterministic parts of the create step: enforcing the
7
+ # "exactly one of --template-id / --edition" rule, assembling and quoting the
8
+ # `sf data create record --values` payload, running the insert, and returning
9
+ # the assigned SignupRequest id (0SR...). Prose interpretation is not needed —
10
+ # the field-selection and serialization rules live here.
11
+ #
12
+ # Auth is handled by the `sf` CLI (the access token never surfaces here).
13
+ #
14
+ # Usage:
15
+ # create_signup_request.sh --target-org <alias-or-username> \
16
+ # --last-name <name> --email <addr> --username <email-format> \
17
+ # --company <name> --country <ISO> \
18
+ # ( --template-id 0TT... | --edition Developer ) \
19
+ # [--first-name <name>]
20
+ #
21
+ # Options:
22
+ # --target-org, -o <org> REQUIRED. Host org alias or username to create in.
23
+ # --last-name <name> REQUIRED. Admin user last name.
24
+ # --email <addr> REQUIRED. SignupEmail — a real inbox.
25
+ # --username <email> REQUIRED. Admin username (email-format, globally unique).
26
+ # --company <name> REQUIRED. Company / org name (spaces allowed).
27
+ # --country <ISO> REQUIRED. ISO country code (e.g. US, GB, IN).
28
+ # --template-id 0TT... Trialforce template id. Mutually exclusive with --edition.
29
+ # --edition <Edition> Generic edition (Developer, Enterprise, ...). Mutually
30
+ # exclusive with --template-id.
31
+ # --first-name <name> Optional. Admin user first name.
32
+ # --output-dir <dir> On a rejected create, write the failure outcome to
33
+ # <dir>/signup-request-result.json (so the run still
34
+ # has an artifact when no org is created).
35
+ # --json Emit the raw `sf` create envelope as-is (default:
36
+ # print the 0SR id on success, error text on failure).
37
+ # --help, -h Show this help.
38
+ #
39
+ # Output:
40
+ # On success (default): the SignupRequest id (0SR...) on stdout, exit 0.
41
+ # On success (--json): the raw `sf data create record --json` envelope.
42
+ # On failure: the raw CLI error (name/code + message) on stderr, and
43
+ # (with --output-dir) a create-rejected artifact JSON.
44
+ #
45
+ # Exit codes:
46
+ # 0 create succeeded
47
+ # 1 create rejected by the API (validation / entitlement / access error)
48
+ # 2 bad usage or missing dependency (sf or jq)
49
+
50
+ set -uo pipefail
51
+
52
+ die() { echo "Error: $*" >&2; exit 2; }
53
+
54
+ command -v sf >/dev/null 2>&1 || die "Salesforce CLI ('sf') not found on PATH."
55
+ command -v jq >/dev/null 2>&1 || die "'jq' not found on PATH."
56
+
57
+ TARGET_ORG=""
58
+ LAST_NAME=""
59
+ EMAIL=""
60
+ USERNAME=""
61
+ COMPANY=""
62
+ COUNTRY=""
63
+ TEMPLATE_ID=""
64
+ EDITION=""
65
+ FIRST_NAME=""
66
+ OUTPUT_DIR=""
67
+ OUTPUT="id"
68
+
69
+ usage() { sed -n '2,/^set -uo/p' "$0" | sed '/^set -uo/d; s/^# \{0,1\}//; s/^#//'; }
70
+
71
+ while [ $# -gt 0 ]; do
72
+ case "$1" in
73
+ --target-org|-o) TARGET_ORG="${2:-}"; shift 2 ;;
74
+ --last-name) LAST_NAME="${2:-}"; shift 2 ;;
75
+ --email) EMAIL="${2:-}"; shift 2 ;;
76
+ --username) USERNAME="${2:-}"; shift 2 ;;
77
+ --company) COMPANY="${2:-}"; shift 2 ;;
78
+ --country) COUNTRY="${2:-}"; shift 2 ;;
79
+ --template-id) TEMPLATE_ID="${2:-}"; shift 2 ;;
80
+ --edition) EDITION="${2:-}"; shift 2 ;;
81
+ --first-name) FIRST_NAME="${2:-}"; shift 2 ;;
82
+ --output-dir) OUTPUT_DIR="${2:-}"; shift 2 ;;
83
+ --json) OUTPUT="json"; shift ;;
84
+ --help|-h) usage; exit 0 ;;
85
+ *) die "Unknown argument: $1" ;;
86
+ esac
87
+ done
88
+
89
+ # --- required-field validation ------------------------------------------
90
+ [ -n "$TARGET_ORG" ] || die "--target-org is required (host org alias or username)."
91
+ [ -n "$LAST_NAME" ] || die "--last-name is required."
92
+ [ -n "$EMAIL" ] || die "--email is required."
93
+ [ -n "$USERNAME" ] || die "--username is required."
94
+ [ -n "$COMPANY" ] || die "--company is required."
95
+ [ -n "$COUNTRY" ] || die "--country is required (ISO code, e.g. US)."
96
+
97
+ # --- exactly-one-of rule (TemplateId XOR Edition) -----------------------
98
+ if [ -n "$TEMPLATE_ID" ] && [ -n "$EDITION" ]; then
99
+ die "Send exactly one of --template-id or --edition, not both (would fail with redundantTemplateId)."
100
+ fi
101
+ if [ -z "$TEMPLATE_ID" ] && [ -z "$EDITION" ]; then
102
+ die "Send exactly one of --template-id or --edition (neither given would fail with missingEdition)."
103
+ fi
104
+
105
+ # --- reject values 'sf --values' cannot represent -----------------------
106
+ # A value containing BOTH a single and a double quote cannot be expressed in the
107
+ # space-separated --values string, whose parser honors only one quote style per
108
+ # token. Check here in the main scope: a guard inside sf_quote would run inside
109
+ # $(...) command substitution, where `exit` kills only the subshell and (with no
110
+ # `set -e`) the script would carry on and issue a malformed create.
111
+ for v in "$LAST_NAME" "$EMAIL" "$USERNAME" "$COMPANY" "$COUNTRY" \
112
+ "$FIRST_NAME" "$TEMPLATE_ID" "$EDITION"; do
113
+ case "$v" in
114
+ *\'*\"* | *\"*\'*) die "Value contains both single and double quotes, which 'sf --values' cannot represent: $v" ;;
115
+ esac
116
+ done
117
+
118
+ # --- assemble the --values payload --------------------------------------
119
+ # `sf data create record --values` takes ONE space-separated string of
120
+ # Field=Value pairs and re-splits it on whitespace, honoring only quotes that
121
+ # appear *inside* that string (see plugin-data's stringToDictionary parser).
122
+ # So any value containing whitespace (e.g. Company="Acme Corporation") must be
123
+ # quoted within the payload, or sf mis-parses it into separate tokens. Quote
124
+ # each value: single-quote by default; switch to double quotes when the value
125
+ # itself contains a single quote (e.g. a last name like O'Brien). Values with
126
+ # both quote types are already rejected above.
127
+ sf_quote() {
128
+ case "$1" in
129
+ *\'*) printf '"%s"' "$1" ;;
130
+ *) printf "'%s'" "$1" ;;
131
+ esac
132
+ }
133
+
134
+ PAIRS=(
135
+ "LastName=$(sf_quote "$LAST_NAME")"
136
+ "SignupEmail=$(sf_quote "$EMAIL")"
137
+ "Username=$(sf_quote "$USERNAME")"
138
+ "Company=$(sf_quote "$COMPANY")"
139
+ "Country=$(sf_quote "$COUNTRY")"
140
+ )
141
+ [ -n "$FIRST_NAME" ] && PAIRS+=("FirstName=$(sf_quote "$FIRST_NAME")")
142
+ [ -n "$TEMPLATE_ID" ] && PAIRS+=("TemplateId=$(sf_quote "$TEMPLATE_ID")")
143
+ [ -n "$EDITION" ] && PAIRS+=("Edition=$(sf_quote "$EDITION")")
144
+
145
+ # Join the quoted pairs into the single space-separated string sf expects.
146
+ VALUES_STR="${PAIRS[*]}"
147
+
148
+ # --- run the insert ------------------------------------------------------
149
+ RESP="$(sf data create record --target-org "$TARGET_ORG" --sobject SignupRequest \
150
+ --values "$VALUES_STR" --json 2>/dev/null)"
151
+
152
+ STATUS="$(printf '%s' "$RESP" | jq -r '.status // 1' 2>/dev/null)"
153
+
154
+ if [ "$STATUS" != "0" ]; then
155
+ # Surface the raw CLI error verbatim (name/code + message) — do not diagnose.
156
+ NAME="$(printf '%s' "$RESP" | jq -r '.name // .code // "ERROR"')"
157
+ MSG="$(printf '%s' "$RESP" | jq -r '.message // "unknown error"')"
158
+ printf '%s: %s\n' "$NAME" "$MSG" >&2
159
+ # No org is created on a rejected create, so get_signup_request.sh never runs.
160
+ # Still leave the run an artifact when --output-dir is given: capture the
161
+ # create-rejected outcome and the raw error verbatim (no diagnosis).
162
+ if [ -n "$OUTPUT_DIR" ]; then
163
+ mkdir -p "$OUTPUT_DIR"
164
+ jq -n --arg name "$NAME" --arg msg "$MSG" \
165
+ '{outcome: "create-rejected", error: {name: $name, message: $msg}, CreatedOrgId: null, Status: null}' \
166
+ > "$OUTPUT_DIR/signup-request-result.json"
167
+ fi
168
+ exit 1
169
+ fi
170
+
171
+ if [ "$OUTPUT" = "json" ]; then
172
+ printf '%s\n' "$RESP"
173
+ else
174
+ printf '%s\n' "$(printf '%s' "$RESP" | jq -r '.result.id')"
175
+ fi
@@ -0,0 +1,155 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # get_signup_request.sh — Read back a SignupRequest to pick up the assigned
4
+ # trial org id, applying a fixed polling policy, and (optionally) write the
5
+ # record as the skill's output artifact.
6
+ #
7
+ # Trial-org provisioning is asynchronous: the insert only returns the 0SR
8
+ # handle, while CreatedOrgId / Status populate shortly after. This script
9
+ # encapsulates the deterministic policy so every invocation behaves the same:
10
+ # - read the record;
11
+ # - stop as soon as CreatedOrgId is populated (this typically happens while
12
+ # Status is still InProgress — the caller need not wait for Success);
13
+ # - otherwise re-read up to --max-attempts times TOTAL, sleeping --delay
14
+ # seconds between reads, then return the current state (no infinite loop);
15
+ # - stop immediately on a terminal Status (Success or Error) or a CLI error.
16
+ #
17
+ # It always prints the resolved record (its `result` object) as JSON on stdout.
18
+ # With --output-dir it also writes that JSON to <dir>/signup-request-result.json.
19
+ #
20
+ # Auth is handled by the `sf` CLI (the access token never surfaces here).
21
+ #
22
+ # Usage:
23
+ # get_signup_request.sh --target-org <org> --id <0SR...> [--output-dir <dir>]
24
+ # get_signup_request.sh --target-org <org> --id <0SR...> --max-attempts 3 --delay 20
25
+ #
26
+ # Options:
27
+ # --target-org, -o <org> REQUIRED. Host org alias or username.
28
+ # --id, -i <0SR...> REQUIRED. SignupRequest id to read.
29
+ # --output-dir <dir> Write the record JSON to <dir>/signup-request-result.json.
30
+ # --max-attempts <n> TOTAL reads before giving up on an empty CreatedOrgId
31
+ # (1 to 3; default 3). Provisioning is async, so we do
32
+ # not poll indefinitely: at most three lookups, then
33
+ # hand back the request id (exit 3) for the user to
34
+ # re-check.
35
+ # --delay <seconds> Sleep between reads (default 20).
36
+ # --help, -h Show this help.
37
+ #
38
+ # Output:
39
+ # The SignupRequest record (the `sf` envelope's `result`) as JSON on stdout.
40
+ #
41
+ # Exit codes:
42
+ # 0 CreatedOrgId populated (org allocated) — the only exit that carries an org id
43
+ # 1 Status=Error, or the record could not be read (auth / id not found)
44
+ # 2 bad usage or missing dependency (sf or jq)
45
+ # 3 no org id available — record read but CreatedOrgId still empty (still
46
+ # provisioning after --max-attempts, or a terminal status with no id).
47
+ # Not an error. The caller reports the 0SR id and the record's REAL Status,
48
+ # and tells the user to re-check later. The exit code never reflects a
49
+ # synthesized status — only what is actually on the record.
50
+
51
+ set -uo pipefail
52
+
53
+ die() { echo "Error: $*" >&2; exit 2; }
54
+
55
+ command -v sf >/dev/null 2>&1 || die "Salesforce CLI ('sf') not found on PATH."
56
+ command -v jq >/dev/null 2>&1 || die "'jq' not found on PATH."
57
+
58
+ TARGET_ORG=""
59
+ SR_ID=""
60
+ OUTPUT_DIR=""
61
+ MAX_ATTEMPTS=3
62
+ DELAY=20
63
+
64
+ usage() { sed -n '2,/^set -uo/p' "$0" | sed '/^set -uo/d; s/^# \{0,1\}//; s/^#//'; }
65
+
66
+ while [ $# -gt 0 ]; do
67
+ case "$1" in
68
+ --target-org|-o) TARGET_ORG="${2:-}"; shift 2 ;;
69
+ --id|-i) SR_ID="${2:-}"; shift 2 ;;
70
+ --output-dir) OUTPUT_DIR="${2:-}"; shift 2 ;;
71
+ --max-attempts) MAX_ATTEMPTS="${2:-}"; shift 2 ;;
72
+ --delay) DELAY="${2:-}"; shift 2 ;;
73
+ --help|-h) usage; exit 0 ;;
74
+ *) die "Unknown argument: $1" ;;
75
+ esac
76
+ done
77
+
78
+ [ -n "$TARGET_ORG" ] || die "--target-org is required."
79
+ [ -n "$SR_ID" ] || die "--id is required (the 0SR... SignupRequest id)."
80
+ case "$MAX_ATTEMPTS" in 1|2|3) ;; *) die "--max-attempts must be 1, 2, or 3 (provisioning is async; we do not poll more than three times)." ;; esac
81
+ case "$DELAY" in ''|*[!0-9]*) die "--delay must be a non-negative integer." ;; esac
82
+
83
+ # read the record once; sets RESULT (the `result` object) and RECORD_STATUS,
84
+ # or returns non-zero on a CLI error (RESULT holds the raw error envelope).
85
+ read_record() {
86
+ local resp env_status
87
+ resp="$(sf data get record --target-org "$TARGET_ORG" --sobject SignupRequest \
88
+ --record-id "$SR_ID" --json 2>/dev/null)"
89
+ env_status="$(printf '%s' "$resp" | jq -r '.status // 1' 2>/dev/null)"
90
+ if [ "$env_status" != "0" ]; then
91
+ printf '%s' "$resp" | jq -r '"\(.name // .code // "ERROR"): \(.message // "unknown error")"' >&2
92
+ return 1
93
+ fi
94
+ RESULT="$(printf '%s' "$resp" | jq '.result')"
95
+ RECORD_STATUS="$(printf '%s' "$RESULT" | jq -r '.Status // ""' | tr '[:upper:]' '[:lower:]')"
96
+ CREATED_ORG_ID="$(printf '%s' "$RESULT" | jq -r '.CreatedOrgId // ""')"
97
+ return 0
98
+ }
99
+
100
+ RESULT=""
101
+ RECORD_STATUS=""
102
+ CREATED_ORG_ID=""
103
+ FINAL_RC=0
104
+
105
+ # At most MAX_ATTEMPTS total reads (1 to 3). Provisioning is async, so if the
106
+ # org id has not appeared by the final read we stop and hand back the request
107
+ # id rather than polling on — the caller reports 0SR and asks the user to
108
+ # re-check later (exit 3).
109
+ attempt=0
110
+ while : ; do
111
+ if ! read_record; then
112
+ exit 1
113
+ fi
114
+ attempt=$((attempt + 1))
115
+ # Stop as soon as the org is allocated, or on a terminal status. Success and
116
+ # Error are both terminal — there is nothing to gain by re-reading either, so
117
+ # neither consumes the retry budget. The exit code is driven by what is
118
+ # actually on the record, never by a synthesized value:
119
+ # - CreatedOrgId present -> 0 (org allocated; caller shares the id)
120
+ # - Status=Error -> 1 (provisioning failed)
121
+ # - terminal but no id (e.g. odd
122
+ # Success with empty CreatedOrgId) -> 3 (no id to give; report real Status)
123
+ if [ -n "$CREATED_ORG_ID" ]; then
124
+ FINAL_RC=0
125
+ break
126
+ fi
127
+ if [ "$RECORD_STATUS" = "error" ]; then
128
+ FINAL_RC=1
129
+ break
130
+ fi
131
+ if [ "$RECORD_STATUS" = "success" ]; then
132
+ # Terminal, but the org id never populated — stop (nothing to re-read) and
133
+ # hand back the request id with the record's real Status.
134
+ FINAL_RC=3
135
+ break
136
+ fi
137
+ # CreatedOrgId still empty and status not yet terminal. Give up once we've
138
+ # used our lookup budget.
139
+ if [ "$attempt" -ge "$MAX_ATTEMPTS" ]; then
140
+ FINAL_RC=3
141
+ break
142
+ fi
143
+ sleep "$DELAY"
144
+ done
145
+
146
+ # Always emit the record as JSON on stdout.
147
+ printf '%s\n' "$RESULT"
148
+
149
+ # Defined output artifact: write the record when an output dir is given.
150
+ if [ -n "$OUTPUT_DIR" ]; then
151
+ mkdir -p "$OUTPUT_DIR"
152
+ printf '%s\n' "$RESULT" > "$OUTPUT_DIR/signup-request-result.json"
153
+ fi
154
+
155
+ exit "$FINAL_RC"
@@ -2,7 +2,7 @@
2
2
  name: platform-widget-generate
3
3
  description: "Use this skill to author a complete HXL WidgetBundle (UEM body + schema.json + -meta.xml). TRIGGER when: user asks for a widget, mosaic, fragment, card, or rich UI surface for any subject, domain, feature, or entity noun; the prompt names only an entity or data shape without invoking Lightning Types, CLTs, or Apex-backed types. DO NOT TRIGGER when: the prompt explicitly says 'Lightning Type', 'CLT', 'Custom Lightning Type', 'Apex-backed type', or references '@apexClassType/...' (use platform-lightning-type-widget-coordinate); authoring a custom-LWC renderer for a Custom Lightning Type (use platform-custom-lightning-type-generate); or editing only an LWC component."
4
4
  metadata:
5
- version: "1.2"
5
+ version: "1.3"
6
6
  domains: ["Platform", "Agentforce"]
7
7
  minApiVersion: "68.0"
8
8
  relatedSkills:
@@ -96,6 +96,42 @@ The first child of `tile/widget.children` SHOULD be a single `tile/column`. All
96
96
 
97
97
  ---
98
98
 
99
+ ## Actions
100
+
101
+ `tile/button` supports an `actions` attribute that dispatches an action node on an event. Two action definitions are supported:
102
+
103
+ | Action | Timing | Required attributes | Effect |
104
+ |---|---|---|---|
105
+ | `action/openLink` | synchronous | `url` (string). Optional `target` (`_blank`\|`_self`, default `_blank`) | Opens a URL |
106
+ | `action/sendMessage` | asynchronous | `content` (string) | Posts a new user message back to the agent and earns a fresh turn |
107
+
108
+ ```json
109
+ {
110
+ "definition": "tile/button",
111
+ "attributes": {
112
+ "label": "Button Label",
113
+ "variant": "primary",
114
+ "actions": { "click": [ { "definition": "action/sendMessage", "attributes": { "content": "content" } } ] }
115
+ }
116
+ }
117
+ ```
118
+
119
+ ```json
120
+ {
121
+ "definition": "tile/button",
122
+ "attributes": {
123
+ "label": "Button Label",
124
+ "variant": "primary",
125
+ "actions": { "click": [ { "definition": "action/openLink", "attributes": { "url": "https://www.example.com", "target": "_blank" } } ] }
126
+ }
127
+ }
128
+ ```
129
+
130
+
131
+ **A `tile/button` with no `actions` attribute renders disabled** — a button exists to trigger an action, so always attach a `click` action to a button meant to be interactive.
132
+
133
+ ---
134
+
99
135
  ## Layout Best Practices
100
136
 
101
137
  These conventions cover widget *structure* — how blocks are grouped and stacked.
@@ -116,11 +152,12 @@ These conventions cover widget *structure* — how blocks are grouped and stacke
116
152
  Widgets express *intent*, not pixels. Each surface provides a default look and feel; brand/theme overrides apply automatically.
117
153
 
118
154
  - **Style semantically.** Use `variant`, `size`, and other enum-typed attributes (`primary`, `destructive`, `success`, `warning`). Do not pin literal colors or pixel values.
119
- - **One primary action per visible group.** At most one `tile/button` with `variant: primary`. Use `secondary`, `outline`, or `ghost` for additional actions.
155
+ - **One primary action per visible group.** At most one `tile/button` with `variant: primary`. Use `secondary` or `destructive` for additional actions (see the `tile/button` schema for the full variant enum).
156
+ - **Every `tile/button` needs a `click` action.** See *Actions* above — an action-less button renders disabled.
120
157
  - **One `h1` per widget.** Use `h2`/`h3` for sub-section headings, `body` for prose, `caption` for helper text.
121
- - **Use semantic state variants on state-bearing blocks** (`tile/alert`, `tile/badge`, `tile/callout`, `tile/chip`).
122
- - **Accept schema defaults for `gap`, `padding`, `size`** unless there is a specific reason to override.
123
- - **Don't pin `width`, `height`, `maxWidth`** unless a content constraint requires it. For long text, use `truncate: true`.
158
+ - **Use semantic state variants on state-bearing blocks** (`tile/badge`, `tile/callout`).
159
+ - **Accept schema defaults for `gap`, `size`** unless there is a specific reason to override.
160
+ - **Don't pin `width`** unless a content constraint requires it.
124
161
  - **Use the Lucide icon set.** Pass the Lucide name (`"check"`, `"alert-circle"`); other icon libraries are not supported.
125
162
 
126
163
  ---
@@ -197,12 +234,13 @@ Widgets express *intent*, not pixels. Each surface provides a default look and f
197
234
  9. **Self-validate.** Before reporting, confirm each check below and report each result individually (`pass` or `fail (<reason>)`). Do **not** summarize as a single "all passed" line — list every check so a reviewer can spot a silent skip.
198
235
  - **`schema-parses`** — `<pkgDir>/uiWidgets/<widgetName>/schema.json` parses as JSON.
199
236
  - **`schema-root-keys`** — root has `title` (string), `type: "object"`, and `properties.attributes` (object) — where `properties.attributes` carries `lightning:type: "lightning__objectType"` and a nested `properties` map. No `unevaluatedProperties: false`.
200
- - **`schema-leaf-types`** — every leaf under `properties.attributes.properties` carries a `lightning:type`. Singular nested inner-class fields carry `lightning:type` set to the inner Apex class reference (`@apexClassType/<namespace>__<OuterClass>$<InnerClass>`); the nested shape is not redeclared. `List<InnerClass>` fields carry `lightning:type: "lightning__listType"` with `items.lightning:type` set to the inner Apex class reference (`@apexClassType/<namespace>__<OuterClass>$<InnerClass>`), not a redeclared field map. See `references/schema-from-lightning-type.md`.
237
+ - **`schema-leaf-types`** — every leaf under `properties.attributes.properties` carries a `lightning:type`. Singular nested inner-class fields carry `lightning:type` set to the inner Apex class reference (`@apexClassType/<namespace>__<OuterClass>$<InnerClass>`); the nested shape is not redeclared. `List<InnerClass>` fields carry `lightning:type: "lightning__listType"` with `items.lightning:type` set to the inner Apex class reference (`@apexClassType/<namespace>__<OuterClass>$<InnerClass>`), not a redeclared field map — see `references/schema-from-lightning-type.md`. **When the list has no Apex-backed type** (schema inferred from the prompt), `items.lightning:type: "lightning__objectType"` MUST carry an inline nested `properties` map for every item field the body binds via `{!$item.X}`.
201
238
  - **`bindings-resolve`** — every `{!$attrs.X}` (or `{!$attrs.<outerField>.<innerField>}` for nested objects) in `<widgetName>.json` resolves to a property under `schema.json` `properties.attributes.properties`, and every `{!$item.X}` resolves to a `forItem` loop variable defined upstream.
202
239
  - **`body-envelope`** — `<widgetName>.json` root has `type: "lightning__agentforceWidget"` and a `contentBody` object whose `widgetBody` carries the UEM tree rooted at `tile/widget`. No node in the tree — root or non-root — carries a `type` key.
203
240
  - **`metaxml-wellformed`** — `<widgetName>.uiwidget-meta.xml` parses as well-formed XML.
204
241
  - **`metaxml-elements`** — `<widgetName>.uiwidget-meta.xml` has root `<UiWidgetBundle>` and contains `<masterLabel>` (non-empty), `<description>` (non-empty), and `<widgetType>JSON</widgetType>`.
205
242
  - **`files-present`** — all three files exist at the resolved `<pkgDir>/uiWidgets/<widgetName>/` path.
243
+ - **`button-actions-present`** — every `tile/button` in `<widgetName>.json` has an `actions.click` action node whose `definition` is `action/openLink` or `action/sendMessage`.
206
244
 
207
245
  ---
208
246
 
@@ -214,6 +252,7 @@ Widgets express *intent*, not pixels. Each surface provides a default look and f
214
252
  | Never pass `tile/widget` to `getUiComponentSchemas` | It is a fixed wrapper, not a queryable component |
215
253
  | Always supply `parameters` (with required keys) when calling `execute_metadata_action` | Missing parameters cause hard failure, not partial result |
216
254
  | Every `{!$attrs.X}` in the body resolves to a property in the widget `schema.json` | No invented fields |
255
+ | Every `tile/button` carries an `actions.click` entry using `action/openLink` or `action/sendMessage` only | These are the only two supported tile action definitions; an action-less button renders disabled |
217
256
  | No `$(…)`, backticks, `<(…)`, brace expansion `{a,b,c}`, or `eval`/`exec` in any Bash tool call | Vibes' safe-shell filter forces manual approval on these patterns even in Bypass mode. Emit separate commands (`mkdir -p a && mkdir -p b`) or print each value with its own command and reason about the output — do not capture into a shell variable |
218
257
 
219
258
  ---
@@ -226,6 +265,8 @@ Widgets express *intent*, not pixels. Each surface provides a default look and f
226
265
  | Body references `{!$attrs.foo}` but `foo` is not under `schema.json` `properties.attributes.properties` | Add `foo` to `schema.json` `properties.attributes.properties` OR remove the body reference |
227
266
  | Output written outside `<pkgDir>/uiWidgets/<widgetName>/` | `<pkgDir>` = `<packageDirectories[].path>/main/default` (see `references/widget-bundle-layout.md`). Dropping the `main/default/` segment is the common cause of widgets landing at `force-app/uiWidgets/...` instead of `force-app/main/default/uiWidgets/...` |
228
267
  | `if` bound to a non-boolean | Use `if` only when the schema has a `lightning__booleanType` property |
268
+ | `tile/button` renders but does nothing when clicked | No `actions.click` entry was set — an action-less button renders disabled by design. Add one (see *Actions* above) |
269
+ | Using `action/sendMessage` for pure navigation, or `action/openLink` when the agent should respond | `action/openLink` is synchronous and does not consume a turn; `action/sendMessage` is asynchronous and earns a fresh turn. Pick the one matching the intended UX |
229
270
 
230
271
  ---
231
272
 
@@ -6,7 +6,7 @@
6
6
  "children": [
7
7
  {
8
8
  "definition": "tile/column",
9
- "attributes": { "gap": "md", "padding": "md" },
9
+ "attributes": { "gap": "md" },
10
10
  "children": [
11
11
  {
12
12
  "definition": "tile/callout",
@@ -21,7 +21,7 @@
21
21
  },
22
22
  {
23
23
  "definition": "tile/column",
24
- "attributes": { "padding": "md" },
24
+ "attributes": { "gap": "md" },
25
25
  "meta": { "if": "{!$attrs.isVerified}"},
26
26
  "children": [
27
27
  {
@@ -50,7 +50,7 @@
50
50
  "children": [
51
51
  {
52
52
  "definition": "tile/column",
53
- "attributes": { "padding": "md" },
53
+ "attributes": { "gap": "md" },
54
54
  "children": [
55
55
  {
56
56
  "definition": "tile/row",
@@ -6,7 +6,7 @@
6
6
  "children": [
7
7
  {
8
8
  "definition": "tile/column",
9
- "attributes": { "gap": "md", "padding": "md" },
9
+ "attributes": { "gap": "md" },
10
10
  "children": [
11
11
  {
12
12
  "definition": "tile/text",
@@ -14,7 +14,7 @@
14
14
  },
15
15
  {
16
16
  "definition": "tile/column",
17
- "attributes": { "gap": "sm", "padding": "md" },
17
+ "attributes": { "gap": "sm" },
18
18
  "meta": { "forEach": "{!$attrs.products}", "forItem": "$product" },
19
19
  "children": [
20
20
  {
@@ -6,11 +6,11 @@
6
6
  "children": [
7
7
  {
8
8
  "definition": "tile/column",
9
- "attributes": { "gap": "md", "padding": "md" },
9
+ "attributes": { "gap": "md" },
10
10
  "children": [
11
11
  {
12
12
  "definition": "tile/column",
13
- "attributes": { "gap": "md", "padding": "lg" },
13
+ "attributes": { "gap": "md" },
14
14
  "children": [
15
15
  {
16
16
  "definition": "tile/text",
@@ -64,7 +64,7 @@ JSON Schema describing what data the widget accepts at runtime. Fields are wrapp
64
64
 
65
65
  - `description` (string)
66
66
 
67
- **Each leaf under `properties.attributes.properties` MUST have `lightning:type`.** Optional per-leaf: `title`, `description`. **A `lightning__listType` leaf MUST also carry `items.lightning:type`** — set to the matching primitive `lightning:type` for a list of primitives, or to an `@apexClassType/...` reference for a list of Apex objects (see `references/schema-from-lightning-type.md`).
67
+ **Each leaf under `properties.attributes.properties` MUST have `lightning:type`.** Optional per-leaf: `title`, `description`. **A `lightning__listType` leaf MUST also carry `items.lightning:type`** — set to the matching primitive `lightning:type` for a list of primitives, or to an `@apexClassType/...` reference for a list of Apex objects (see `references/schema-from-lightning-type.md`). **For a list of plain objects with no Apex-backed type**, `items.lightning:type` is `lightning__objectType` and `items` MUST also carry a nested `properties` map inlining every field the list items expose (same shape as the outer `attributes.properties` map).
68
68
 
69
69
  Example:
70
70