@salesforce/afv-skills 1.4.0 → 1.5.1

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 (31) hide show
  1. package/package.json +6 -5
  2. package/skills/creating-webapp/SKILL.md +0 -2
  3. package/skills/generating-apex/SKILL.md +253 -0
  4. package/skills/generating-apex/assets/abstract.cls +128 -0
  5. package/skills/generating-apex/assets/batch.cls +125 -0
  6. package/skills/generating-apex/assets/domain.cls +102 -0
  7. package/skills/generating-apex/assets/dto.cls +108 -0
  8. package/skills/generating-apex/assets/exception.cls +51 -0
  9. package/skills/generating-apex/assets/interface.cls +25 -0
  10. package/skills/generating-apex/assets/queueable.cls +92 -0
  11. package/skills/generating-apex/assets/schedulable.cls +75 -0
  12. package/skills/generating-apex/assets/selector.cls +92 -0
  13. package/skills/generating-apex/assets/service.cls +69 -0
  14. package/skills/generating-apex/assets/utility.cls +97 -0
  15. package/skills/generating-apex/references/AccountDeduplicationBatch.cls +148 -0
  16. package/skills/generating-apex/references/AccountSelector.cls +193 -0
  17. package/skills/generating-apex/references/AccountService.cls +201 -0
  18. package/skills/generating-apex-test/SKILL.md +108 -0
  19. package/skills/generating-apex-test/assets/test-class-template.cls +124 -0
  20. package/skills/generating-apex-test/assets/test-data-factory-template.cls +112 -0
  21. package/skills/generating-apex-test/references/assertion-patterns.md +165 -0
  22. package/skills/generating-apex-test/references/async-testing.md +276 -0
  23. package/skills/generating-apex-test/references/mocking-patterns.md +219 -0
  24. package/skills/generating-apex-test/references/test-data-factory.md +176 -0
  25. package/skills/generating-experience-lwr-site/SKILL.md +42 -16
  26. package/skills/generating-experience-lwr-site/docs/configure-content-brandingSet.md +17 -7
  27. package/skills/generating-experience-lwr-site/docs/configure-content-themeLayout.md +2 -1
  28. package/skills/generating-experience-lwr-site/docs/configure-content-view.md +3 -3
  29. package/skills/generating-experience-react-site/SKILL.md +11 -0
  30. package/skills/generating-flexipage/SKILL.md +39 -57
  31. package/skills/searching-media/SKILL.md +342 -0
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: generating-flexipage
3
- description: "Use this skill when users need to create, generate, modify, or validate Salesforce Lightning pages (FlexiPages). Trigger when users mention RecordPage, AppPage, HomePage, Lightning pages, page layouts, adding components to pages, or page customization. Also use when users say things like \"create a Lightning page\", \"add a component to a page\", \"customize the record page\", \"generate a FlexiPage\", or when they're working with FlexiPage XML files and need help with components, regions, or deployment errors. Always use this skill for any FlexiPage-related work, even if they just mention \"page\" in the context of Salesforce."
3
+ description: "Use this skill when users need to create, generate, modify, or validate Salesforce Lightning pages (FlexiPages). Trigger when users mention RecordPage, AppPage, HomePage, Lightning pages, page layouts, adding components to pages, or page customization. Also use when users say things like 'create a Lightning page', 'add a component to a page', 'customize the record page', 'generate a FlexiPage', or when they're working with FlexiPage XML files and need help with components, regions, or deployment errors. Always use this skill for any FlexiPage-related work, even if they just mention 'page' in the context of Salesforce."
4
4
  ---
5
5
 
6
6
  ## When to Use This Skill
@@ -20,6 +20,8 @@ Use this skill when you need to:
20
20
 
21
21
  ## Overview
22
22
 
23
+ **CRITICAL: When creating NEW FlexiPages, you MUST ALWAYS start with the CLI template command.** Never create FlexiPage XML from scratch - the CLI provides valid structure, proper regions, and correct component configuration that prevents deployment errors.
24
+
23
25
  Generate Lightning pages (RecordPage, AppPage, HomePage) using CLI bootstrapping for component discovery and configuration.
24
26
 
25
27
  ---
@@ -28,6 +30,8 @@ Generate Lightning pages (RecordPage, AppPage, HomePage) using CLI bootstrapping
28
30
 
29
31
  ### Step 1: Bootstrap with CLI
30
32
 
33
+ **MANDATORY FOR NEW PAGES: This step is NOT optional.** Always use the CLI template command when creating a new FlexiPage. The CLI generates valid XML structure, proper regions, and correct metadata that prevents common deployment errors. Only skip this step if you're editing an existing FlexiPage file.
34
+
31
35
  ```bash
32
36
  sf template generate flexipage \
33
37
  --name <PageName> \
@@ -39,19 +43,22 @@ sf template generate flexipage \
39
43
  --output-dir force-app/main/default/flexipages
40
44
  ```
41
45
 
42
- **Template-specific requirements:**
43
- - **RecordPage**: Requires `--sobject` (e.g., Account, Custom_Object__c)
44
- - **RecordPage**: Requires `--primary-field` and `--secondary-fields` for dynamic highlights, `--detail-fields` for full record details. Use the most important identifying field as primary, e.g. Name. Use the secondary fields (max 12, recommended 4-6) to show a summary of the record. Use detail fields to show the full details of the record.
45
- - **AppPage**: No additional requirements
46
- - **HomePage**: No additional requirements
47
-
48
46
  **Note:** If the `sf template generate flexipage` command fails, recommend users upgrade to the latest version of the Salesforce CLI:
49
47
  ```bash
50
48
  npm install -g @salesforce/cli@latest
51
49
  ```
52
50
 
51
+ #### **Field Selection Guidelines**
52
+ - **Validate fields exist**: Use MCP tools or describe commands to discover available fields for the object before specifying them in the command
53
+ - **Prefer compound fields**: Use `Name` (not `FirstName`/`LastName`), `BillingAddress` (not `BillingStreet`/`BillingCity`/`BillingState`), `MailingAddress`, etc. when available
53
54
 
54
- **What you get:**
55
+ #### **Template-specific requirements**
56
+ - **RecordPage**: Requires `--sobject` (e.g., Account, Custom_Object__c)
57
+ - **RecordPage**: Requires `--primary-field` and `--secondary-fields` for dynamic highlights, `--detail-fields` for full record details. Use the most important identifying field as primary, e.g. Name. Use the secondary fields (max 12, recommended 4-6) to show a summary of the record. Use detail fields to show the full details of the record.
58
+ - **AppPage**: No additional requirements
59
+ - **HomePage**: No additional requirements
60
+
61
+ #### **What you get**
55
62
  - Valid FlexiPage XML with correct structure
56
63
  - Pre-configured regions and basic components
57
64
  - Proper field references and facet structure
@@ -59,17 +66,31 @@ npm install -g @salesforce/cli@latest
59
66
 
60
67
  ### Step 2: Deploy Base Page
61
68
 
69
+ Run a **dry-run** deployment of the entire project to validate the page and dependencies:
62
70
  ```bash
63
- sf project deploy start --source-dir force-app/main/default/flexipages
71
+ sf project deploy start --dry-run -d "force-app/main/default" --test-level NoTestRun --wait 10 --json
64
72
  ```
65
73
 
66
- **Deploy early, deploy often.** Start with the bootstrapped page, validate it works, then enhance.
74
+ **Critical:** Fix any deployment errors before proceeding. The page must validate successfully.
75
+
76
+ ### Step 3: **STOP - No Further Modifications**
77
+
78
+ **MANDATORY: Stop after Step 2. Do not add components or edit the FlexiPage XML.**
67
79
 
68
- ### Step 3: Update and Redeploy
80
+ This applies even if the user requested:
81
+ - Additional components
82
+ - Page customization
83
+ - Component configuration
69
84
 
70
- Modify the generated XML, adding components discovered via MCP. Deploy incrementally.
85
+ What you CAN do:
86
+ - Suggest what components would be useful
87
+ - Explain what enhancements are possible
88
+ - Document what would need to be added manually
71
89
 
72
- **Note:** Warn users to use caution with updates beyond this step when using this command.
90
+ What you CANNOT do:
91
+ - Modify the XML file
92
+ - Add any components
93
+ - Make any enhancements
73
94
 
74
95
  ---
75
96
 
@@ -215,6 +236,10 @@ Every fieldInstance requires:
215
236
 
216
237
  ## Common Deployment Errors
217
238
 
239
+ ### "We couldn't retrieve or load the information on the field"
240
+ **Cause:** Invalid field API name - field doesn't exist on the object or has incorrect spelling
241
+ **Fix:** Use MCP tools or describe commands to discover valid fields, then update the field reference (see Field Selection Guidelines)
242
+
218
243
  ### "Invalid field reference"
219
244
  **Cause:** Used `ObjectName.Field` instead of `Record.Field`
220
245
  **Fix:** Change to `Record.{FieldApiName}`
@@ -245,49 +270,6 @@ Every fieldInstance requires:
245
270
 
246
271
  ---
247
272
 
248
- ## Incremental Development Pattern
249
-
250
- **Philosophy:** Deploy small, working increments. Don't build entire complex page at once.
251
-
252
- **Process:**
253
- 1. **CLI bootstrap** → Deploy base page
254
- 2. **Add one component** → Deploy
255
- 3. **Add another component** → Deploy
256
- 4. **Repeat** until complete
257
-
258
- **Benefits:**
259
- - Isolated errors (know exactly what broke)
260
- - Faster debugging
261
- - Build confidence with each success
262
- - Get user feedback early
263
-
264
- **Anti-pattern:** Building entire complex page → one giant error cascade.
265
-
266
- ---
267
-
268
- ## Adding Components to Existing FlexiPages
269
-
270
- ### Workflow
271
-
272
- When user provides an existing FlexiPage file path:
273
-
274
- 1. **Read the file** using native file I/O
275
- 2. **Parse XML** to extract:
276
- - **ALL existing component identifiers** (search for all `<identifier>` tags)
277
- - **ALL existing region/facet names** (search for all `<name>` tags in `<flexiPageRegions>`)
278
- - Available regions (parse from file, don't assume names)
279
- - Existing facets
280
- 3. **Verify uniqueness** - ensure your new identifiers and names don't conflict with ANY existing ones
281
- 4. **Check if target facet exists** - if adding to a named facet like `detailTabContent` that already exists:
282
- - **Add new `<itemInstances>` to existing region** (don't create duplicate region)
283
- - **Insert before the closing `</flexiPageRegions>` tag of that region**
284
- 5. **Generate component XML** (apply all rules from "Critical XML Rules" section)
285
- 6. **Insert** into appropriate region or add itemInstances to existing facet
286
- 7. **Write** modified XML back to file
287
- 8. **Deploy**: `sf project deploy start --source-dir force-app/...`
288
-
289
- ---
290
-
291
273
  ### Generating Unique Identifiers
292
274
 
293
275
  **CRITICAL: Before generating ANY new identifier or facet name, follow the rules in section 5 of "Critical XML Rules" above.**
@@ -474,7 +456,7 @@ Identifier Pattern: flexipage_richText or flexipage_richText_{sequence}
474
456
  ## Validation Checklist
475
457
 
476
458
  Before deploying:
477
- - [ ] Used CLI to bootstrap (don't start from scratch)
459
+ - [ ] **[NEW PAGES ONLY]** Used CLI to bootstrap - NEVER create FlexiPage XML from scratch
478
460
  - [ ] **ALL identifiers are unique** - no duplicate `<identifier>` values anywhere in file
479
461
  - [ ] **ALL region/facet names are unique** - no duplicate `<name>` values in `<flexiPageRegions>`
480
462
  - [ ] **Multiple components in same facet are combined** - ONE region with multiple `<itemInstances>`, NOT separate regions with same name
@@ -0,0 +1,342 @@
1
+ ---
2
+ name: searching-media
3
+ description: "Searches for and retrieves existing visual media (images, logos, icons, photos, graphics, banners, thumbnails, hero images, backgrounds) from any source. Use this skill ANY TIME a user request involves finding, searching, getting, fetching, retrieving, grabbing, looking up, or locating media. Takes PRIORITY and activates FIRST when ANY media search/retrieval is mentioned, regardless of what else happens with the media afterward. Triggers for requests like \"search for logo\", \"find hero image\", \"get company logo\", \"locate icons\", \"fetch background image\", \"retrieve product photos\". Handles the search and source selection workflow. Does not apply when the request is to generate NEW images with AI, design custom graphics from scratch, or edit existing images."
4
+ compatibility: "Requires search_media_cms_channels and/or search_electronic_media MCP tools"
5
+ metadata:
6
+ version: "1.0"
7
+ ---
8
+
9
+ # Media Search
10
+
11
+ Universal routing skill for searching and retrieving existing images and media.
12
+
13
+ ## Scope
14
+
15
+ **This skill is for SEARCHING FOR existing media, not CREATING new media.**
16
+
17
+ **Use this skill when the user wants to:**
18
+ - Search for images in Salesforce CMS, Data Cloud
19
+ - Find existing visual assets to use in their app
20
+ - Retrieve media from connected sources
21
+ - Browse available images for their project
22
+ - Locate specific photos or graphics
23
+
24
+ **DO NOT use this skill when the user wants to:**
25
+ - Generate new images with AI (use image generation tools)
26
+ - Create graphics or designs from scratch
27
+ - Edit or modify existing images
28
+ - Build custom visuals or diagrams
29
+
30
+ ## Before You Search
31
+
32
+ **CRITICAL: This is a routing skill, not a direct search skill.**
33
+
34
+ When a user requests to find an image:
35
+
36
+ **Your first response MUST be plain text only — zero tool calls.** You MUST follow this sequence:
37
+
38
+ 1. **First response MUST be text only:** A numbered list of search sources for the user. No tool calls of any kind.
39
+ 2. **Wait for user to reply** with their selected option number
40
+ 3. **Only then** call the appropriate search tool (this is the FIRST tool call in the entire interaction)
41
+
42
+ **Example of what NOT to do:**
43
+ - ❌ Calling ANY tool before the user picks a source (MCP tools, file reads, descriptor checks, etc.)
44
+ - ❌ "Checking which MCP tools are available" — do not probe or discover tools via tool calls
45
+ - ❌ Immediately calling `search_electronic_media` or `search_media_cms_channels`
46
+ - ❌ Reading MCP tool descriptors or schemas to see what's available
47
+ - ❌ Deciding which search source to use without asking
48
+
49
+ **Example of what TO do:**
50
+ - ✅ Respond with ONLY text — a numbered list of search sources
51
+ - ✅ Ask: "Which option would you like to use?"
52
+ - ✅ Wait for user to reply with their choice
53
+ - ✅ Then (and only then) call the tool they selected
54
+
55
+ **Your first response when this skill triggers MUST be a text-only message presenting search sources. No tool calls. No exceptions.**
56
+
57
+
58
+ ## Workflow Overview
59
+
60
+ **The user MUST choose the search source. You CANNOT skip this step.**
61
+
62
+ Copy this checklist and track your progress:
63
+
64
+ ```
65
+ Media Search Progress:
66
+ - [ ] Step 1: Check your own tool list for available search tools (no tool calls — just inspect what's in your context)
67
+ - [ ] Step 2: Present only the available options to the user as a numbered list (plain text, no tool calls)
68
+ - [ ] Step 3: Wait for the user to reply with their selection
69
+ - [ ] Step 4: Execute the selected search method (this is the first tool call)
70
+ - [ ] Step 5: Present all results to user for selection
71
+ - [ ] Step 6: Apply selected image to code
72
+ ```
73
+
74
+ If you call any tool before step 4, you are not following this skill correctly.
75
+
76
+ ## Presenting Search Sources (First Response)
77
+
78
+ **DO NOT call any tool, read any MCP descriptor, or make any external request to determine available tools.**
79
+
80
+ Your tools are already loaded into your context. Look at the tool names you already have access to — this is introspection, not a tool call.
81
+
82
+ **Step 1: Check your own tool list (no tool calls)**
83
+
84
+ Look at the tools already in your context and check for these names:
85
+ - `search_media_cms_channels` → If present, include **"Search using keywords"**
86
+ - `search_electronic_media` → If present, include **"Search using Data 360 hybrid search"**
87
+ - Always include **"Other"** as the last option
88
+
89
+ **Step 2: Build your response**
90
+
91
+ Include ONLY the sources whose tools you actually have. Number them sequentially.
92
+
93
+ ```
94
+ I can help you find that image. Where would you like to search?
95
+
96
+ [NUMBER]. [SEARCH SOURCE NAME] — [Brief description]
97
+ ...
98
+ [NUMBER]. Other — Provide your own URL or path
99
+
100
+ Which option would you like to use?
101
+ ```
102
+
103
+ **Step 3: Stop and wait**
104
+
105
+ After presenting the list, STOP. Do not call any tool. Do not proceed. Wait for the user to reply with their choice.
106
+
107
+ ### Examples
108
+
109
+ **Both tools available:**
110
+ ```
111
+ I can help you find that image. Where would you like to search?
112
+
113
+ 1. Search using Data 360 hybrid search — Semantic search across Salesforce CMS and connected DAMs
114
+ 2. Search using keywords — Search Salesforce CMS by keywords and taxonomies
115
+ 3. Other — Provide your own URL or path
116
+
117
+ Which option would you like to use?
118
+ ```
119
+
120
+ **Only `search_media_cms_channels` available:**
121
+ ```
122
+ I can help you find that image. Where would you like to search?
123
+
124
+ 1. Search using keywords — Search Salesforce CMS by keywords and taxonomies
125
+ 2. Other — Provide your own URL or path
126
+
127
+ Which option would you like to use?
128
+ ```
129
+
130
+ **Only `search_electronic_media` available:**
131
+ ```
132
+ I can help you find that image. Where would you like to search?
133
+
134
+ 1. Search using Data 360 hybrid search — Semantic search across Salesforce CMS and connected DAMs
135
+ 2. Other — Provide your own URL or path
136
+
137
+ Which option would you like to use?
138
+ ```
139
+
140
+ **Neither tool available:**
141
+ ```
142
+ No automated media search sources are currently configured. Please provide a direct URL or asset library path.
143
+ ```
144
+
145
+ **Wait for the user to select** before proceeding.
146
+
147
+ ## Executing the Selected Search Method
148
+
149
+ **⚠️ ONLY reach this step if the user has explicitly selected an option from your numbered list.**
150
+
151
+ If you haven't shown options yet, go back to the "Presenting Search Sources" section first.
152
+
153
+ After the user selects an option, execute the corresponding search method below.
154
+
155
+ ### Search using keywords
156
+
157
+ **Tool:** `search_media_cms_channels`
158
+
159
+ **Process:**
160
+
161
+ 1. **Analyze the query** — Understand what the user is searching for (subject, attributes, domain)
162
+
163
+ 2. **Extract keywords** — Concrete nouns that would appear in image metadata
164
+ - Use domain-specific synonyms
165
+ - Maximum 10 terms
166
+ - Examples:
167
+ - "luxury apartments" → apartment, villa, penthouse, residence, condo
168
+ - "company logo" → logo, emblem, corporate logo
169
+ - "bright room" → _(empty if no concrete nouns)_
170
+
171
+ 3. **Extract taxonomies** — Descriptive qualities, styles, moods, categories
172
+ - Only adjectives and attributes
173
+ - Examples:
174
+ - "luxury apartment with river view" → Luxury, Premium, Waterfront, Riverside, Panoramic
175
+ - "bright spacious room" → Bright, Spacious, Open, Airy, Light
176
+ - "car" → _(empty if no descriptive terms)_
177
+
178
+ 4. **Determine locale** — Use format `en_US`, `es_MX`, `fr_FR` (default: `en_US`)
179
+
180
+ 5. **Build the JSON payload** — Construct this exact structure:
181
+
182
+ ```json
183
+ {
184
+ "inputs": [{
185
+ "searchKeyword": "keyword1 OR keyword2 OR keyword3",
186
+ "taxonomyExpression": "{\"OR\": [\"Taxonomy1\", \"Taxonomy2\"]}",
187
+ "searchLanguage": "en_US",
188
+ "channelIds": "",
189
+ "channelType": "PublicUnauthenticated",
190
+ "contentTypeFqn": "sfdc_cms__image",
191
+ "pageOffset": 0,
192
+ "searchLimit": 5
193
+ }]
194
+ }
195
+ ```
196
+
197
+ **Field rules:**
198
+ - `searchKeyword`: Join keywords with ` OR ` (space-OR-space). Use empty string if no keywords.
199
+ - `taxonomyExpression`: Stringify JSON object `{"OR": ["term1", "term2"]}`. Use `"{}"` if no taxonomies.
200
+ - `searchLanguage`: Locale with underscore (e.g., `en_US`)
201
+ - `channelIds`: Always empty string
202
+ - `channelType`: Always `"PublicUnauthenticated"`
203
+ - `contentTypeFqn`: Always `"sfdc_cms__image"`
204
+ - `pageOffset`: Start at `0`, increment by `searchLimit` for pagination
205
+ - `searchLimit`: Default `5`, adjust if user requests more
206
+
207
+ **Examples:**
208
+
209
+ Query: "luxury apartment with river view"
210
+ ```json
211
+ {
212
+ "inputs": [{
213
+ "searchKeyword": "apartment OR villa OR penthouse OR residence",
214
+ "taxonomyExpression": "{\"OR\": [\"Luxury\", \"Premium\", \"Waterfront\", \"Riverside\"]}",
215
+ "searchLanguage": "en_US",
216
+ "channelIds": "",
217
+ "channelType": "PublicUnauthenticated",
218
+ "contentTypeFqn": "sfdc_cms__image",
219
+ "pageOffset": 0,
220
+ "searchLimit": 5
221
+ }]
222
+ }
223
+ ```
224
+
225
+ Query: "bright spacious room" (no concrete nouns)
226
+ ```json
227
+ {
228
+ "inputs": [{
229
+ "searchKeyword": "",
230
+ "taxonomyExpression": "{\"OR\": [\"Bright\", \"Spacious\", \"Open\", \"Airy\"]}",
231
+ "searchLanguage": "en_US",
232
+ "channelIds": "",
233
+ "channelType": "PublicUnauthenticated",
234
+ "contentTypeFqn": "sfdc_cms__image",
235
+ "pageOffset": 0,
236
+ "searchLimit": 5
237
+ }]
238
+ }
239
+ ```
240
+
241
+ Query: "car images" (no descriptive terms)
242
+ ```json
243
+ {
244
+ "inputs": [{
245
+ "searchKeyword": "car OR automobile OR vehicle OR auto",
246
+ "taxonomyExpression": "{}",
247
+ "searchLanguage": "en_US",
248
+ "channelIds": "",
249
+ "channelType": "PublicUnauthenticated",
250
+ "contentTypeFqn": "sfdc_cms__image",
251
+ "pageOffset": 0,
252
+ "searchLimit": 5
253
+ }]
254
+ }
255
+ ```
256
+
257
+ 6. **Call the tool** with the exact JSON payload
258
+
259
+ ### Search using Data 360 hybrid search
260
+
261
+ **Tool:** `search_electronic_media`
262
+
263
+ **Process:**
264
+
265
+ 1. Use the user's query **as-is** — no keyword extraction or transformation needed
266
+ 2. Call `search_electronic_media`
267
+ 3. Pass the query to the tool's `searchQuery` parameter
268
+
269
+ **Example:**
270
+ - User query: "modern luxury apartment with natural lighting"
271
+ - Tool call: `search_electronic_media(searchQuery="modern luxury apartment with natural lighting")`
272
+
273
+ ### Other (User-Provided URL)
274
+
275
+ Ask the user to provide:
276
+ - Direct URL to the image
277
+ - Asset library path
278
+ - Specific system/location to check
279
+
280
+ ## Presenting Search Results
281
+
282
+ Parse the tool response and present **ALL** results as numbered options. Show the image title only — do not display the URL. When the user selects an option, use the URL internally to apply the image.
283
+
284
+ ```
285
+ I found 4 images. Which one would you like to use?
286
+
287
+ 1. Luxury Apartment Exterior
288
+ Source: Salesforce CMS
289
+
290
+ 2. Modern High-Rise Building
291
+ Source: Salesforce CMS
292
+
293
+ 3. Waterfront Residence
294
+ Source: Salesforce CMS
295
+
296
+ 4. Premium Condominium
297
+ Source: Salesforce CMS
298
+ ```
299
+
300
+ **Never auto-select an image.** Always wait for user choice.
301
+
302
+ ## Applying the Selected Image
303
+
304
+ After the user chooses:
305
+
306
+ 1. Confirm the selection with image name and URL
307
+ 2. Use the complete URL returned by the tool, including all query parameters. CMS and DAM URLs rely on query parameters for authentication, resizing, and CDN routing — dropping them breaks the image. For example, a URL like `https://cms.example.com/media/img.jpg?oid=00D&refid=0EM&v=2` must be used in full.
308
+ 3. Apply the URL to the user's code/component
309
+ 4. Show what was changed (file path and line number)
310
+
311
+ ## Error Handling
312
+
313
+ | Error | Response |
314
+ |---|---|
315
+ | Tool unavailable | "The [source name] tool is unavailable. Would you like to try a different source?" |
316
+ | Tool returns error | Show error message, offer retry with different terms or alternative source |
317
+ | No results found | "No results found. Try broader keywords, removing descriptive terms, or a different source." |
318
+ | Invalid user selection | Re-display options and ask again |
319
+
320
+ **Never silently fail.** Always inform the user and offer alternatives.
321
+
322
+ ## Search Behavior Notes
323
+
324
+ **Search using keywords:**
325
+ - Both keyword and taxonomy → results match keyword OR (keyword + taxonomy)
326
+ - Empty keyword → search by taxonomy only
327
+ - Empty taxonomy → search by keyword only
328
+ - Use `pageOffset` for pagination (increment by `searchLimit`)
329
+
330
+ **Search using Data 360 hybrid search:**
331
+ - Handles natural language queries
332
+ - Semantic similarity matching
333
+ - Searches across multiple connected systems
334
+
335
+ ## Key Principles
336
+
337
+ 1. **First response is always text-only** — Present search sources without calling any tool
338
+ 2. **Only show configured sources** — Check your own tool list (introspection, not tool calls) and only present sources whose tools you have
339
+ 3. **Wait for user selection** — Never auto-select a source or image
340
+ 4. **Show all results** — Let the user choose the best match
341
+ 5. **Confirm before applying** — Verify the selection before modifying code
342
+ 6. **Handle errors gracefully** — Provide clear feedback and alternatives