@salesforce/afv-skills 1.57.0 → 1.59.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 (81) hide show
  1. package/package.json +1 -1
  2. package/skills/agentforce-bot-upgrade/SKILL.md +3 -1
  3. package/skills/agentforce-generate/SKILL.md +21 -1
  4. package/skills/agentforce-generate/references/known-issues.md +51 -1
  5. package/skills/agentforce-generate/references/legacy-nga-regression-eval.md +547 -0
  6. package/skills/agentforce-generate/references/upgrade-legacy-agent-to-agentscript.md +577 -0
  7. package/skills/agentforce-generate/scripts/upgrade-legacy-nga-analyze.py +404 -0
  8. package/skills/agentforce-generate/scripts/upgrade-legacy-nga-run-trials.sh +58 -0
  9. package/skills/agentforce-persona-generate/SKILL.md +505 -0
  10. package/skills/agentforce-persona-generate/assets/checklist-template.md +100 -0
  11. package/skills/agentforce-persona-generate/assets/persona-encoding-template.md +252 -0
  12. package/skills/agentforce-persona-generate/assets/persona-template.md +229 -0
  13. package/skills/agentforce-persona-generate/assets/sample-dialog-template.md +50 -0
  14. package/skills/agentforce-persona-generate/assets/workshop-outline-template.md +97 -0
  15. package/skills/agentforce-persona-generate/examples/concierge-persona.md +189 -0
  16. package/skills/agentforce-persona-generate/examples/concierge-sample-dialog.md +70 -0
  17. package/skills/agentforce-persona-generate/examples/drover-persona.md +194 -0
  18. package/skills/agentforce-persona-generate/examples/drover-sample-dialog.md +62 -0
  19. package/skills/agentforce-persona-generate/examples/steady-hand-persona.md +188 -0
  20. package/skills/agentforce-persona-generate/examples/steady-hand-sample-dialog.md +68 -0
  21. package/skills/agentforce-persona-generate/examples/yt-persona.md +195 -0
  22. package/skills/agentforce-persona-generate/examples/yt-sample-dialog.md +66 -0
  23. package/skills/agentforce-persona-generate/references/attributions.md +36 -0
  24. package/skills/agentforce-persona-generate/references/interaction-design-notes.md +30 -0
  25. package/skills/agentforce-persona-generate/references/persona-encoding-guide.md +566 -0
  26. package/skills/agentforce-persona-generate/references/persona-framework.md +796 -0
  27. package/skills/agentforce-persona-generate/references/refinement-mappings.md +31 -0
  28. package/skills/agentforce-persona-generate/references/scoring-rubric.md +58 -0
  29. package/skills/agentforce-persona-generate/references/voice-catalog.json +2327 -0
  30. package/skills/agentforce-persona-generate/references/workshop-question-policy.md +90 -0
  31. package/skills/agentforce-persona-generate/references/workshop-scenario-seeds.md +119 -0
  32. package/skills/agentforce-persona-generate/scripts/parse_agent_yaml.py +223 -0
  33. package/skills/dx-app-analytics-query/SKILL.md +8 -8
  34. package/skills/experience-ui-bundle-app-coordinate/SKILL.md +12 -12
  35. package/skills/experience-ui-bundle-app-coordinate/references/phase-completion-validation.md +3 -3
  36. package/skills/experience-ui-bundle-app-coordinate/references/phase-execution-pattern.md +9 -7
  37. package/skills/experience-ui-bundle-app-coordinate/scripts/check-dangling-refs.mjs +132 -0
  38. package/skills/experience-ui-bundle-app-coordinate/scripts/check-hosting-target.mjs +62 -0
  39. package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-1-complete.mjs +71 -0
  40. package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-4-complete.mjs +95 -0
  41. package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-6-ready.mjs +78 -0
  42. package/skills/experience-ui-bundle-app-coordinate/scripts/check-prerequisites.mjs +21 -0
  43. package/skills/experience-ui-bundle-app-coordinate/scripts/check-sfdx-project.mjs +28 -0
  44. package/skills/experience-ui-bundle-custom-app-generate/SKILL.md +3 -1
  45. package/skills/experience-ui-bundle-custom-app-generate/scripts/resolve-uibundle-path.mjs +40 -0
  46. package/skills/experience-ui-bundle-frontend-generate/SKILL.md +7 -5
  47. package/skills/experience-ui-bundle-frontend-generate/scripts/check-preconditions.mjs +70 -0
  48. package/skills/experience-ui-bundle-frontend-generate/scripts/resolve-ui-bundle.mjs +76 -0
  49. package/skills/experience-ui-bundle-frontend-generate/scripts/verify-rules.mjs +115 -0
  50. package/skills/experience-ui-bundle-metadata-generate/SKILL.md +7 -3
  51. package/skills/experience-ui-bundle-metadata-generate/references/angular-metadata-generate.md +1 -1
  52. package/skills/experience-ui-bundle-metadata-generate/references/react-metadata-generate.md +1 -1
  53. package/skills/experience-ui-bundle-metadata-generate/scripts/check-api-version.mjs +43 -0
  54. package/skills/experience-ui-bundle-metadata-generate/scripts/detect-framework.mjs +131 -0
  55. package/skills/experience-ui-bundle-metadata-generate/scripts/verify-bundle-location.mjs +152 -0
  56. package/skills/experience-ui-bundle-mfa-configure/references/branding.md +10 -6
  57. package/skills/experience-ui-bundle-project-generate/SKILL.md +13 -39
  58. package/skills/experience-ui-bundle-project-generate/scripts/flatten-project.mjs +33 -11
  59. package/skills/experience-ui-bundle-project-generate/scripts/generate-project.mjs +77 -0
  60. package/skills/experience-ui-bundle-project-generate/scripts/install-deps.mjs +95 -0
  61. package/skills/service-omni-channel-setup-coordinate/SKILL.md +1 -0
  62. package/skills/service-omni-command-center-analyze/SKILL.md +1 -0
  63. package/skills/service-omni-command-center-configure/SKILL.md +92 -0
  64. package/skills/service-omni-command-center-configure/references/api-notes.md +50 -0
  65. package/skills/service-omni-command-center-configure/scripts/configure-and-report.sh +257 -0
  66. package/skills/service-omni-command-center-configure/scripts/settings_document.py +97 -0
  67. package/skills/service-omni-command-center-configure/scripts/tests/test_command_center_configure_contracts.py +206 -0
  68. package/skills/experience-ui-bundle-app-coordinate/scripts/check-dangling-refs.sh +0 -42
  69. package/skills/experience-ui-bundle-app-coordinate/scripts/check-hosting-target.sh +0 -26
  70. package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-1-complete.sh +0 -35
  71. package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-4-complete.sh +0 -47
  72. package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-6-ready.sh +0 -33
  73. package/skills/experience-ui-bundle-app-coordinate/scripts/check-prerequisites.sh +0 -20
  74. package/skills/experience-ui-bundle-app-coordinate/scripts/check-sfdx-project.sh +0 -15
  75. package/skills/experience-ui-bundle-custom-app-generate/scripts/resolve-uibundle-path.sh +0 -30
  76. package/skills/experience-ui-bundle-frontend-generate/scripts/check-preconditions.sh +0 -37
  77. package/skills/experience-ui-bundle-frontend-generate/scripts/resolve-ui-bundle.sh +0 -66
  78. package/skills/experience-ui-bundle-frontend-generate/scripts/verify-rules.sh +0 -58
  79. package/skills/experience-ui-bundle-metadata-generate/scripts/check-api-version.sh +0 -30
  80. package/skills/experience-ui-bundle-metadata-generate/scripts/detect-framework.sh +0 -73
  81. package/skills/experience-ui-bundle-metadata-generate/scripts/verify-bundle-location.sh +0 -118
@@ -0,0 +1,577 @@
1
+ # Upgrade a Legacy Agent to Agent Script (NGA)
2
+
3
+ Workflow for migrating a legacy Salesforce `GenAiPlannerBundle` agent into a
4
+ Next Gen Authoring (NGA) `AiAuthoringBundle` (Agent Script) bundle.
5
+
6
+ > Steps run in order: **Step 1** project setup → **Step 2** pick the legacy
7
+ > agent version → **Step 3** migrate via the Connect API → **Step 4** retrieve
8
+ > the NGA bundle → **Step 5** analyze, optimize, and iterate.
9
+
10
+ > **Narration:** keep progress lines to one short phrase — _"Gathering
11
+ > migratable versions…"_, _"Running the migration call inside a subagent…"_.
12
+ > Don't explain the rationale (why a subagent, what a screen is) inline; the
13
+ > user wants terse status, not a play-by-play.
14
+
15
+ ## Contents
16
+
17
+ - [Kickoff — set expectations, then track progress](#kickoff--set-expectations-then-track-progress)
18
+ - [Step 1 — Project setup and requirements](#step-1--project-setup-and-requirements)
19
+ - [Step 2 — Identify the legacy agent version to upgrade](#step-2--identify-the-legacy-agent-version-to-upgrade)
20
+ - [Step 3 — Migrate the legacy agent with the `migrateAgentToNga` Connect API](#step-3--migrate-the-legacy-agent-with-the-migrateagenttonga-connect-api)
21
+ - [Step 4 — Retrieve the new NGA bundle into the project](#step-4--retrieve-the-new-nga-bundle-into-the-project)
22
+ - [Step 5 — Analyze, optimize, and iterate on the migrated Agent Script](#step-5--analyze-optimize-and-iterate-on-the-migrated-agent-script)
23
+ - [5d — Regression-test the draft against the legacy agent](#5d--regression-test-the-draft-against-the-legacy-agent)
24
+
25
+ ## Kickoff — set expectations, then track progress
26
+
27
+ Before touching anything, do two things so the user always knows what's coming
28
+ and where they are. Keep both **brief** — no rationale, no sub-steps.
29
+
30
+ **1. Show a high-level overview once, up front:**
31
+
32
+ > Migrating your legacy agent to Agent Script (NGA). The plan:
33
+ > 1. **Set up** — pick the target org and a local project
34
+ > 2. **Choose** — the legacy agent and the version to migrate
35
+ > 3. **Migrate** — one API call; creates a new NGA bundle in your org
36
+ > 4. **Retrieve** — pull the new agent down locally
37
+ > 5. **Optimize** — review and improve the result together
38
+ >
39
+ > The migration produces a **new NGA version** of your agent. Your original
40
+ > agent versions stay available in the legacy builder — nothing is overwritten
41
+ > or removed, so you can always fall back to them.
42
+ >
43
+ > The migration itself is quick — step 5 is where we make it good.
44
+
45
+ **2. Render this checklist now, and re-render it (compact) after each step** so
46
+ the user can see progress at a glance. Mark completed `[x]`, the active step
47
+ `[>]`, and the rest `[ ]`:
48
+
49
+ ```text
50
+ - [ ] Step 1 — Project & org setup
51
+ - [ ] Step 2 — Pick legacy agent + version
52
+ - [ ] Step 3 — Migrate (Connect API)
53
+ - [ ] Step 4 — Retrieve NGA bundle
54
+ - [ ] Step 5 — Analyze & optimize
55
+ ```
56
+
57
+ Re-render only the checklist between steps — don't re-explain finished work. At
58
+ the end of each step below you'll find a **Checklist** cue: advance the marker
59
+ and show the updated list before starting the next step.
60
+
61
+ ## Step 1 — Project setup and requirements
62
+
63
+ The workflow needs a local **Salesforce DX project** to hold retrieved
64
+ metadata — the legacy `botVersion-meta.xml` files read in Step 2 and the
65
+ migrated `AiAuthoringBundle` pulled down in Step 4 all land here. Establish this
66
+ once, up front.
67
+
68
+ ### Gather requirements
69
+
70
+ Collect two things. **Never assume a default for either — always confirm.**
71
+
72
+ 1. **Target org** — the org that holds the legacy agent and will receive the
73
+ migrated bundle (used as `<org-alias>` throughout). **Never silently use the
74
+ default org.** Show the user the current default and the alternatives, then
75
+ **require an explicit confirmation or choice** before proceeding — Step 3 is a
76
+ mutating call, so the wrong org creates a bundle in the wrong place.
77
+
78
+ ```bash
79
+ sf config get target-org --json # the current default, if any
80
+ sf org list --json # all authenticated orgs to choose from
81
+ ```
82
+
83
+ **Present the authenticated orgs as a selectable menu** (e.g. an
84
+ `AskUserQuestion` pick-list) — the user should **choose**, never type an
85
+ alias by hand. Mark the current default so it's obvious (e.g.
86
+ `mk-sandbox (default)`) but still require an explicit pick. Use the chosen
87
+ alias as `<org-alias>` everywhere below.
88
+ 2. **DX project** — the path to the DX project to work in. If they don't have
89
+ one, offer to create it and ask for a name/location.
90
+
91
+ Once the org is chosen, resolve **its** API version rather than pinning a
92
+ literal (versions bump every release, so a hardcoded number goes stale). Use it
93
+ as `<apiVersion>` in the endpoint paths below:
94
+
95
+ ```bash
96
+ sf org display --target-org <org-alias> --json 2>/dev/null \
97
+ | sed -E 's/\x1b\[[0-9;]*m//g' | jq -r '.result.apiVersion' # e.g. 67.0
98
+ ```
99
+
100
+ > **Minimum:** `migrateAgentToNga` (Step 3) requires **API v67.0+**. If the org
101
+ > reports lower, it predates the endpoint — stop and surface that.
102
+
103
+ ### Use an existing project, or create one
104
+
105
+ A DX project is any directory containing an `sfdx-project.json`. Verify:
106
+
107
+ ```bash
108
+ test -f <project-path>/sfdx-project.json && echo "DX project OK" || echo "no project here"
109
+ ```
110
+
111
+ If none exists, create one and set `sourceApiVersion` to the org's
112
+ `<apiVersion>` resolved above (must be `67.0`+ for the Step 3 endpoint):
113
+
114
+ ```bash
115
+ sf project generate --name <project-name> --output-dir <parent-dir>
116
+ # then, in sfdx-project.json, set "sourceApiVersion": "<apiVersion>"
117
+ ```
118
+
119
+ ### Resolve the package directory — never assume `force-app`
120
+
121
+ Retrieved metadata lands under the project's **default package directory**. That
122
+ directory is declared in `sfdx-project.json` and is **not always `force-app`** —
123
+ `sf project generate` defaults to it, but existing projects often rename it or
124
+ declare several. Resolve it once from the project and use the result as
125
+ `<package-dir>` in every path below (the `default: true` entry, falling back to
126
+ the first `packageDirectories` entry):
127
+
128
+ ```bash
129
+ jq -r '(.packageDirectories[] | select(.default == true) | .path) // .packageDirectories[0].path' \
130
+ <project-path>/sfdx-project.json # e.g. force-app
131
+ ```
132
+
133
+ **All subsequent `sf project retrieve start` commands must be run from inside
134
+ this project directory** (`cd <project-path>`), so retrieved metadata is written
135
+ under its `<package-dir>/main/default/` tree — including
136
+ `aiAuthoringBundles/` (the migrated NGA bundle) and `bots/` (the legacy
137
+ `botVersion-meta.xml` files).
138
+
139
+ > **Checklist:** mark Step 1 done, Step 2 `[>]`, and re-render before continuing.
140
+
141
+ ## Step 2 — Identify the legacy agent version to upgrade
142
+
143
+ The `migrateAgentToNga` call in Step 3 takes a single input: a classic
144
+ **`BotVersion`** Id (key prefix `0X9`). This step presents a **two-screen
145
+ selection** — first pick the agent, then pick one of its **non-NGA** versions —
146
+ and resolves the choice to that Id.
147
+
148
+ ### Concepts
149
+
150
+ An Agentforce agent is backed by classic Bot SObjects, but as an **Agentforce
151
+ copilot**, not an old Einstein Bot:
152
+
153
+ - **`BotDefinition`** (key prefix `0Xx`) — the agent. For Agentforce agents
154
+ `Type` is **`ExternalCopilot`** or **`InternalCopilot`**. **Do not** pick
155
+ `Type = 'Bot'` records — those are old Einstein Bots, not Agentforce agents.
156
+ - **`BotVersion`** (key prefix `0X9`) — one version of that agent, with a
157
+ `VersionNumber` and a `Status` (`Active` / `Inactive`). This is what you
158
+ migrate.
159
+ - Each version is authored by a **planner**, identified in the version's
160
+ `botVersion-meta.xml` as `<genAiPlannerName>`. That planner's
161
+ **`PlannerType`** (queryable on the `GenAiPlannerDefinition` SObject) is the
162
+ authoritative NGA-vs-legacy discriminator (see below).
163
+
164
+ ### Distinguishing NGA from legacy (migratable) versions
165
+
166
+ Only **non-NGA** versions can be migrated — an NGA version is already Agent
167
+ Script. Once an NGA agent is published it *also* gets `Bot`/`BotVersion` records,
168
+ so the presence of a `BotVersion` does **not** mean a version is legacy. The
169
+ reliable signal is the planner's `PlannerType`:
170
+
171
+ | `PlannerType` | Meaning |
172
+ |--------------------------------------------|----------------------------|
173
+ | `Atlas__ConcurrentMultiAgentOrchestration` | **NGA** — already Agent Script; exclude |
174
+ | `AiCopilot__ReAct` | Legacy Agentforce (copilot) — migratable |
175
+ | `SentOS__SearchAgent` | Legacy search agent — migratable |
176
+ | _(anything other than `Atlas__…`)_ | Legacy — migratable |
177
+
178
+ > **Do not** rely on `Bot.agentDSLEnabled` (in `bot-meta.xml`). It exists but is
179
+ > **definition-level and stale** — it can read `false` for an agent whose latest
180
+ > version is already NGA. Classify **per version** via `PlannerType`.
181
+
182
+ ### Screen 1 — pick the agent
183
+
184
+ List the Agentforce agents (copilot-typed `BotDefinition`) and let the user pick
185
+ one:
186
+
187
+ ```bash
188
+ sf data query \
189
+ --query "SELECT DeveloperName, MasterLabel, Type FROM BotDefinition WHERE Type IN ('ExternalCopilot','InternalCopilot') ORDER BY MasterLabel" \
190
+ --target-org <org-alias> \
191
+ --json
192
+ ```
193
+
194
+ #### Silent gate — reject developer names ending in `_<digits>`
195
+
196
+ **As soon as the agent is chosen, silently check its `DeveloperName` against the
197
+ pattern `_\d+$`** (an underscore followed by one or more digits at the end —
198
+ e.g. `Agent_01`, `Order_Agent_007`). Do **not** narrate this check when it
199
+ passes; just continue.
200
+
201
+ If it **matches**, the migration produces a bundle that can't be worked on from
202
+ the terminal (broken version handling) — see
203
+ [known-issues.md](known-issues.md) **Issue 21**. **Stop the migration here.** Do
204
+ not proceed to Screen 2 or the Step 3 call. Tell the user, concisely:
205
+
206
+ - The agent's developer name ends in `_<digits>`, which hits a known migration
207
+ bug (link Issue 21).
208
+ - The fix is to rename the developer name to break up the trailing digits
209
+ (e.g. `Agent_01` → `Agent_v01`), **then** restart this workflow.
210
+ - Renaming has ripple effects — Email Configurations, `package.xml` /
211
+ `AiAuthoringBundle` deploy configs, and any Agent API integrations reference
212
+ the agent by name and must be updated to match. (Point them at Issue 21 for
213
+ the full list.)
214
+
215
+ ```bash
216
+ # silent detection — no output unless it matches
217
+ printf '%s\n' "<agent-name>" | grep -Eq '_[0-9]+$' && echo "BLOCKED: see Issue 21"
218
+ ```
219
+
220
+ ### Screen 2 — pick a non-NGA version
221
+
222
+ For the chosen agent, gather its versions and each version's planner type, then
223
+ present **only the non-NGA versions**, ordered by `VersionNumber` **ascending**.
224
+
225
+ 1. **Versions + Ids** (ascending) — the `0X9…` Id per version:
226
+
227
+ ```bash
228
+ sf data query \
229
+ --query "SELECT Id, VersionNumber, Status FROM BotVersion WHERE BotDefinition.DeveloperName = '<agent-name>' AND BotDefinition.Type IN ('ExternalCopilot','InternalCopilot') ORDER BY VersionNumber ASC" \
230
+ --target-org <org-alias> \
231
+ --json
232
+ ```
233
+
234
+ 2. **Per-version planner link** — retrieve all versions' metadata at once and
235
+ read `<genAiPlannerName>` from each `vN.botVersion-meta.xml`:
236
+
237
+ ```bash
238
+ sf project retrieve start --metadata "BotVersion:<agent-name>.*" --target-org <org-alias> --json
239
+ # each: <package-dir>/main/default/bots/<agent-name>/vN.botVersion-meta.xml
240
+ # → <conversationDefinitionPlanners><genAiPlannerName>…</genAiPlannerName>
241
+ ```
242
+
243
+ 3. **Planner types** — resolve every planner's `PlannerType`:
244
+
245
+ ```bash
246
+ sf data query \
247
+ --query "SELECT DeveloperName, PlannerType FROM GenAiPlannerDefinition" \
248
+ --target-org <org-alias> \
249
+ --json
250
+ ```
251
+
252
+ Join version → `genAiPlannerName` → `PlannerType`, drop any version whose
253
+ `PlannerType` is `Atlas__ConcurrentMultiAgentOrchestration` (NGA), and present
254
+ the rest ascending, e.g.:
255
+
256
+ ```text
257
+ Agent: Search_Agent
258
+ v1 Inactive (legacy: SentOS__SearchAgent)
259
+ v6 Inactive (legacy: SentOS__SearchAgent)
260
+ # v2–v5, v7 hidden — already NGA (Atlas)
261
+ ```
262
+
263
+ The `Id` (`0X9…`) of the version the user picks is the `botVersionId` you pass to
264
+ `migrateAgentToNga` in Step 3.
265
+
266
+ > **Checklist:** mark Step 2 done, Step 3 `[>]`, and re-render before continuing.
267
+
268
+ ## Step 3 — Migrate the legacy agent with the `migrateAgentToNga` Connect API
269
+
270
+ Salesforce Core exposes a Connect REST endpoint that converts a classic
271
+ `BotVersion` into an NGA Agent Script bundle:
272
+
273
+ ```text
274
+ POST /services/data/v<apiVersion>/connect/migrateAgentToNga # <apiVersion> from Step 1, v67.0+
275
+ ```
276
+
277
+ **Warning: This is a mutating call.** It does not validate/preview — a successful call
278
+ *creates* a new NGA bundle in the org (a real `AiAuthoringBundle`, key prefix
279
+ `1bY`, with a bundle version, key prefix `1bZ`). Confirm the target org and the
280
+ `botVersionId` before running it.
281
+
282
+ ### Preferred: call it through the `sf` CLI
283
+
284
+ Invoke the Connect endpoint with `sf api request rest` — no manual token
285
+ handling. **`sf api request rest` has no `--json` flag** (passing it errors with
286
+ `Nonexistent flag: --json`). It streams the raw response *body* to stdout — for
287
+ this endpoint that body is already JSON — and prints a beta-command warning to
288
+ stderr. The body is ANSI-colorized even when piped, so strip the color codes
289
+ before reading or feeding it to `jq`:
290
+
291
+ ```bash
292
+ sf api request rest "/services/data/v<apiVersion>/connect/migrateAgentToNga" \
293
+ --method POST \
294
+ --body '{"botVersionId":"<botVersionId>"}' \
295
+ --target-org <org-alias> \
296
+ 2>/dev/null | sed -E 's/\x1b\[[0-9;]*m//g'
297
+ ```
298
+
299
+ - `botVersionId` — the classic `BotVersion` Id (`0X9…`) selected in Step 2.
300
+ - The stripped stdout is the full JSON response. Pipe it to `jq` after the `sed`
301
+ strip to pull individual fields.
302
+
303
+ #### Warning: Do the call in a subagent — the response can be huge
304
+
305
+ A newer version of this endpoint returns an **`agentScript`** field containing
306
+ the *entire* generated Agent Script inline. Reading the raw response into the
307
+ main context would bloat it badly. **Make the `migrateAgentToNga` call inside a
308
+ subagent** and have the subagent return only the small fields you need:
309
+ `bundleVersionApiName`, `bundleId`, `bundleVersionId`, `agentVersionFromNumber`,
310
+ `bundleVersionToNumber`, `conversionWarnings`, and `agentResponse`. Never return
311
+ `agentScript` up to the caller; the full script comes down through the Step 4
312
+ retrieve instead.
313
+
314
+ #### Response fields
315
+
316
+ The response shape is expanding. Handle the new fields **if present**, and fall
317
+ back to the older shape when they are absent:
318
+
319
+ | Field | Use |
320
+ |-------|-----|
321
+ | `bundleVersionApiName` | **Preferred.** The metadata `fullName` of the new bundle version — pass **directly** to the Step 4 retrieve, skipping the `bundleVersionId → fullName` lookup. |
322
+ | `bundleVersionId` (`1bZ…`) | Fallback join key when `bundleVersionApiName` is absent (see Step 4). |
323
+ | `bundleId` (`1bY…`) | The bundle (not version) Id. |
324
+ | `conversionWarnings` | List of warnings; review in Step 5. Often non-empty. |
325
+ | `agentResponse` | Notes/fixes from an agent that reviewed the generated script — useful input for Step 5 optimization. |
326
+ | `agentScript` | The full generated script inline — **do not** surface it; retrieve the bundle in Step 4 instead. |
327
+ | `agentVersionFromNumber` (Integer) | The legacy agent version that was migrated **from**. Use in the success message below. |
328
+ | `bundleVersionToNumber` (Integer) | The NGA bundle version that was created **to**. Use in the success message below. |
329
+
330
+ #### Report the result — always present the builder link
331
+
332
+ **On any successful migration, present the builder deep link so the user can
333
+ open the new agent immediately.** The link needs only `bundleId` and
334
+ `bundleVersionId`, which are present in **both** the old and new response shapes
335
+ — so the link is unconditional, never gated on the newer fields.
336
+
337
+ Confirm in one line, then hand over the link:
338
+
339
+ ```text
340
+ Migrated <agent> to a new NGA agent. Open it in the builder: <builderUrl>
341
+ ```
342
+
343
+ When the newer fields (`agentVersionFromNumber`, `bundleVersionToNumber`) are
344
+ present, use the more specific wording; otherwise fall back to the generic line
345
+ above:
346
+
347
+ ```text
348
+ Legacy <agent> version <agentVersionFromNumber> has been migrated to NGA version <bundleVersionToNumber>.
349
+ Open in the builder: <builderUrl>
350
+ ```
351
+
352
+ The builder URL is the org's Lightning host + the agent-authoring app, with the
353
+ **bundle** as the `project` and the **bundle version** as the `projectVersion`
354
+ (`project == bundle`):
355
+
356
+ ```text
357
+ https://<lightning-host>/AgentAuthoring/agentAuthoringBuilder.app#/project?projectId=<bundleId>&projectVersionId=<bundleVersionId>
358
+ ```
359
+
360
+ - `projectId` = `bundleId` (`1bY…`); `projectVersionId` = `bundleVersionId` (`1bZ…`) — both from the Step 3 response.
361
+ - Derive `<lightning-host>` from the chosen org, don't hardcode it:
362
+
363
+ ```bash
364
+ sf org display --target-org <org-alias> --json 2>/dev/null \
365
+ | sed -E 's/\x1b\[[0-9;]*m//g' | jq -r '.result.instanceUrl'
366
+ ```
367
+
368
+ Use that host as-is; if it's a `*.my.salesforce.com` domain it redirects to the
369
+ matching `*.lightning.force.com` builder.
370
+
371
+ > **Always call through `sf api request rest`.** It keeps authentication
372
+ > internal to the CLI. **Do not** hand-roll a `curl` call that extracts the org
373
+ > access token (e.g. `jq -r '.result.accessToken'`) — pulling a session token
374
+ > into a shell variable is prohibited in agent-executed workflows because it can
375
+ > surface in the transcript, context, or traces, even when it is never echoed.
376
+
377
+ #### Response shapes
378
+
379
+ A successful migration returns **HTTP 201**. The **current** shape (older
380
+ endpoint) looks like:
381
+
382
+ ```json
383
+ {
384
+ "bundleId": "1bYak000000LoRdEAK",
385
+ "bundleVersionId": "1bZak000000dXCDEA2",
386
+ "conversionWarnings": [
387
+ "WARNING: Subagent TestSubAgent007 could not be resolved from standard subagents or has no actions. Is this expected?"
388
+ ]
389
+ }
390
+ ```
391
+
392
+ The **newer** shape adds `bundleVersionApiName`, `agentScript`, `agentResponse`,
393
+ and version-number fields:
394
+
395
+ ```json
396
+ {
397
+ "bundleId": "1bYak000000LoRdEAK",
398
+ "bundleVersionId": "1bZak000000dXCDEA2",
399
+ "bundleVersionApiName": "Agentforce_Service_Agent_4",
400
+ "conversionWarnings": ["WARNING: …"],
401
+ "agentScript": "system:\n instructions:| … (full script — do not surface)",
402
+ "agentResponse": "Reviewed the generated script; adjusted …",
403
+ "bundleVersionToNumber": 4,
404
+ "agentVersionFromNumber": 1
405
+ }
406
+ ```
407
+
408
+ `conversionWarnings` is often non-empty. Common entries flag subagents that
409
+ resolved to no actions during conversion (e.g. `Escalation`, custom test
410
+ subagents) — review them in Step 5 when refining the migrated script; they do
411
+ **not** fail the migration.
412
+
413
+ > **Checklist:** mark Step 3 done, Step 4 `[>]`, and re-render before continuing.
414
+
415
+ ## Step 4 — Retrieve the new NGA bundle into the project
416
+
417
+ Pull the freshly-created `AiAuthoringBundle` into the DX project from Step 1 so
418
+ it can be reviewed and refined locally. Retrieval is by metadata **fullName**.
419
+
420
+ ### Get the retrievable fullName
421
+
422
+ **Preferred (newer endpoint):** Step 3's response already includes
423
+ **`bundleVersionApiName`** — that *is* the metadata `fullName`. Use it directly
424
+ and **skip the lookup below**.
425
+
426
+ **Fallback (older endpoint, no `bundleVersionApiName`):** map the
427
+ `bundleVersionId` to a `fullName`. `sf org list metadata` reports each
428
+ `AiAuthoringBundle`'s `id`, and that `id` equals the **`bundleVersionId`**
429
+ (`1bZ…`) from Step 3 — **not** the `bundleId` (`1bY…`). Match on it:
430
+
431
+ ```bash
432
+ sf org list metadata --metadata-type AiAuthoringBundle --target-org <org-alias> --json \
433
+ 2>/dev/null | sed -E 's/\x1b\[[0-9;]*m//g' \
434
+ | jq -r --arg id "<bundleVersionId>" '.result[] | select(.id == $id) | .fullName'
435
+ ```
436
+
437
+ Either path yields a versioned name like `Agentforce_Service_Agent_4`.
438
+
439
+ ### Retrieve into the project
440
+
441
+ Run from **inside the Step 1 project directory** so the bundle lands under
442
+ `<package-dir>/main/default/aiAuthoringBundles/` (the `<package-dir>` resolved in
443
+ Step 1):
444
+
445
+ ```bash
446
+ cd <project-path>
447
+ sf project retrieve start --metadata "AiAuthoringBundle:<fullName>" --target-org <org-alias>
448
+ ```
449
+
450
+ > **Note on the on-disk name.** You pass the *versioned* `fullName` (e.g.
451
+ > `Agentforce_Service_Agent_4`), but the retrieve normalizes the local folder to
452
+ > the bundle's **`developer_name`** (its base name, e.g.
453
+ > `Agentforce_Service_Agent`). The result is:
454
+ >
455
+ > ```text
456
+ > <package-dir>/main/default/aiAuthoringBundles/<developer_name>/
457
+ > <developer_name>.agent # the Agent Script (YAML)
458
+ > <developer_name>.bundle-meta.xml # <bundleType>AGENT</bundleType>
459
+ > ```
460
+
461
+ The `.agent` file is the migrated Agent Script — `system:` instructions,
462
+ `config:`, `variables:`, subagents, and actions — ready for review in Step 5.
463
+
464
+ > **Checklist:** mark Step 4 done, Step 5 `[>]`, and re-render before continuing.
465
+
466
+ ## Step 5 — Analyze, optimize, and iterate on the migrated Agent Script
467
+
468
+ `migrateAgentToNga` produces a **basic, mechanical transformation** of the
469
+ legacy agent metadata into Agent Script. It maps the old subagents/actions across
470
+ but does **not** leverage any of the primitives that make Agent Script powerful —
471
+ deterministic flow control, wired data flow, proper reference syntax, structured
472
+ escalation, etc. The migrated `.agent` is a *starting point*, not a finished
473
+ agent. This step hands off to the existing capabilities of the
474
+ **`agentforce-generate`** skill to understand it, then improve it.
475
+
476
+ Work against the retrieved bundle from Step 4
477
+ (`<package-dir>/main/default/aiAuthoringBundles/<developer_name>/<developer_name>.agent`).
478
+ Available inputs to inform the work:
479
+
480
+ - The retrieved `.agent` file (Step 4) — the migrated script itself.
481
+ - Step 3 `conversionWarnings` — unresolved subagents / actions to address.
482
+ - Step 3 `agentResponse` (newer endpoint only) — fixes/comments from an agent
483
+ that already reviewed the generated script; a useful starting checklist.
484
+
485
+ ### 5a — Understand what was produced
486
+
487
+ Route into the skill's **"Comprehend an Existing Agent"** task domain (see
488
+ [SKILL.md](../SKILL.md)). It reverse-engineers an Agent Spec, produces a Subagent
489
+ Map diagram, and flags anti-patterns — establishing what the mechanical
490
+ conversion actually built before you change it. Core references:
491
+ [Core Language](agent-script-core-language.md),
492
+ [Subagent Map Diagrams](agent-subagent-map-diagrams.md).
493
+
494
+ ### 5b — Optimize to leverage Agent Script primitives
495
+
496
+ Route into the skill's **"Optimize an Agent"** task domain (see
497
+ [SKILL.md](../SKILL.md)) — this is the heart of turning a mechanical conversion
498
+ into a real Agent Script agent. It scans every subagent and applies:
499
+
500
+ - **Pattern 1 — Wire action outputs to deterministic consumers**
501
+ ([Data Flow](optimization-pattern-1-data-flow.md)).
502
+ - **Pattern 2 — Extract requirement-backed deterministic logic**
503
+ ([Deterministic Logic](optimization-pattern-2-deterministic-logic.md)) — the
504
+ biggest lever on migrated agents, which encode all logic as model judgment.
505
+ In particular, **any consequential or state-changing action** (order/status
506
+ updates, writes, refunds, cancellations) must be **structurally gated** with
507
+ `available when @variables.<trusted_state>` over verified state — do not leave
508
+ the guard as a prose instruction like "only update for a verified customer,"
509
+ which the model can ignore. For example, gate an `UpdateOrderStatus` alias with
510
+ `available when @variables.verified` rather than trusting reasoning text.
511
+ - **Pattern 3 — Fix variable/action reference syntax**
512
+ ([Reference Syntax](optimization-pattern-3-reference-syntax.md)) —
513
+ `{!@variables.X}` / `{!@actions.X}` instead of bare references.
514
+ - **Pattern 4 — Repair promised human handoff**
515
+ ([Escalation](optimization-pattern-4-escalation.md)) — resolves the
516
+ unresolved-`Escalation`-subagent warnings commonly seen in `conversionWarnings`.
517
+ - **Pattern 5 — Voice-readiness** ([Voice Modality](voice-modality-reference.md))
518
+ if the agent has a `modality voice:` block.
519
+
520
+ The domain presents an `## Optimization Report`, **stops for explicit approval**,
521
+ then applies approved edits. For deeper judgment on what "good" looks like, see
522
+ [Zen of AgentScript](zen-of-agentscript.md),
523
+ [Posture & Determinism](posture-and-determinism.md), and the
524
+ [Scoring Rubric](scoring-rubric.md).
525
+
526
+ ### 5c — Validate, preview, and iterate
527
+
528
+ After edits, validate and confirm behavior — then loop 5b/5c until satisfied:
529
+
530
+ ```bash
531
+ sf agent validate authoring-bundle --json --api-name <developer_name>
532
+ sf agent preview start --json --use-live-actions --authoring-bundle <developer_name>
533
+ ```
534
+
535
+ See [Validation & Debugging](agent-validation-and-debugging.md) for the
536
+ preview/trace loop and [Safety Review](safety-review-reference.md) for the
537
+ 7-category safety pass. When the agent is ready to release, continue into the
538
+ skill's **"Deploy, Publish, and Activate"** task domain.
539
+
540
+ ### 5d — Regression-test the draft against the legacy agent
541
+
542
+ For higher assurance — especially before release, or when 5b changed routing or
543
+ actions — run a **side-by-side regression eval** that previews the migrated NGA
544
+ draft and the legacy agent against a fixed utterance suite and compares them.
545
+ This confirms the draft routes to the same subagents, calls the same actions, and
546
+ returns equivalent (ideally improved) responses. Full mechanism, scripts, and the
547
+ utterance-suite format are in
548
+ [legacy-nga-regression-eval.md](legacy-nga-regression-eval.md).
549
+
550
+ **When to run:** after the draft compiles and previews cleanly (5c), when you want
551
+ objective evidence that the migration preserved behavior — not on every tiny edit.
552
+ It requires the legacy agent to still have an **Active** `BotVersion` and `sf` CLI
553
+ **≥ 2.149.9**.
554
+
555
+ Two bundled scripts do the mechanical work:
556
+
557
+ - `scripts/upgrade-legacy-nga-run-trials.sh` — collects fresh-session preview
558
+ trials for a subject (`legacy` | `draft`) × utterance (agent/org from
559
+ `EVAL_AGENT` / `EVAL_ORG`).
560
+ - `scripts/upgrade-legacy-nga-analyze.py` — reads the local plan traces and emits
561
+ the comparison report (mechanical Rubric #1 + verbatim responses + an LLM-judge
562
+ prompt for Rubric #2).
563
+
564
+ > **Safety.** Live utterances that fire real side effects (escalation, customer
565
+ > email, lead capture) must be tagged and default to **simulated** mode or
566
+ > explicit per-utterance confirmation — never run repeatedly in live mode without
567
+ > opt-in. Draft-only otherwise: **no publish/activate/deploy** without explicit
568
+ > human approval.
569
+
570
+ **Stop condition:** every utterance's oracle-triangle verdict is `PASS` or
571
+ `PASS + LEGACY-DEFECT` (no open `DRAFT-REGRESSION`; any `SPEC-REVIEW` /
572
+ `ADJUDICATE` resolved), drift is `none` against a deliberately-approved baseline,
573
+ and the Rubric #2 judgment is `EQUIVALENT` / `IMPROVED` (no open `REGRESSION`). A
574
+ `LEGACY-DEFECT` is a **pass** — don't chase legacy parity when legacy was wrong.
575
+
576
+ > **Checklist:** mark Step 5 done — all five steps complete. Confirm the
577
+ > migration is finished and point the user at the optimized bundle.