From 8af66a4fd2be9512dd84f492ce41ce0b1637b4ac Mon Sep 17 00:00:00 2001 From: Hemant Singh Bisht Date: Wed, 11 Mar 2026 21:13:19 +0530 Subject: [PATCH] feat: update flexipage skills --- skills/salesforce-flexipage/SKILL.md | 798 +++++++++++++++------------ 1 file changed, 432 insertions(+), 366 deletions(-) diff --git a/skills/salesforce-flexipage/SKILL.md b/skills/salesforce-flexipage/SKILL.md index fc55d7a..083e6c7 100644 --- a/skills/salesforce-flexipage/SKILL.md +++ b/skills/salesforce-flexipage/SKILL.md @@ -6,466 +6,532 @@ description: Use this skill when users need to create, generate, modify, or vali ## When to Use This Skill Use this skill when you need to: -- Create Lightning pages (Record, App, or Home pages) -- Build custom page layouts in Lightning Experience -- Add components to Lightning pages -- Configure page structure and components -- Troubleshoot deployment errors related to FlexiPages +- Create Lightning page layouts (RecordPage, AppPage, HomePage) +- Generate FlexiPage metadata XML +- Add components to existing FlexiPages +- Troubleshoot FlexiPage deployment errors +- Configure field sections, highlights panels, and related lists +- Work with FlexiPage regions, facets, and component properties +## Specification -# FlexiPage Generation Guide +# FlexiPage Metadata Specification ## Overview -Generate Lightning pages (RecordPage, AppPage, HomePage) using CLI bootstrapping + MCP actions for component discovery and configuration. +Lightning page layouts for RecordPage, AppPage, and HomePage. Dynamic, component-based design supporting desktop, phone, and tablet. --- -## Quick Start Workflow +## Generation Philosophy -### Step 1: Bootstrap with CLI +**Deploy Incrementally, Iterate Quickly** -```bash -sf template generate flexipage \ - --name \ - --template \ - --sobject \ - --primary-field \ - --secondary-fields \ - --detail-fields \ - --output-dir force-app/main/default/flexipages -``` +FlexiPages are complex. Deploy in small increments for fast feedback: +1. **Start simple**: Deploy with minimal components (e.g., just header region) +2. **Add incrementally**: Add one region or component at a time +3. **Deploy often**: Each addition = immediate validation +4. **Use errors to learn**: Deployment errors are faster than guessing -**Template-specific requirements:** -- **RecordPage**: Requires `--sobject` (e.g., Account, Custom_Object__c) -- **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 Use detail fields to show the full details of the record. -- **AppPage**: No additional requirements -- **HomePage**: No additional requirements +**Benefits:** +- Isolated errors (one component at a time) +- Faster debugging (know exactly what broke) +- Build confidence (each success validates approach) +- User feedback (see progress, adjust direction) -**What you get:** -- Valid FlexiPage XML with correct structure -- Pre-configured regions and basic components -- Proper field references and facet structure -- Ready to deploy as-is or enhance further - -### Step 2: Deploy Base Page - -```bash -sf project deploy start --source-dir force-app/main/default/flexipages -``` - -**Deploy early, deploy often.** Start with the bootstrapped page, validate it works, then enhance. - -### Step 3: Enhance with MCP Actions (Optional) - -If you need to add more components or customize: - -#### A. Discover Available Components -``` -DISCOVER_UI_COMPONENTS -``` -Returns: List of components available for this page type with descriptions. - -#### B. Get Component Schemas -``` -GET_UI_COMPONENT_SCHEMAS -``` -Returns: JSON schemas showing required/optional properties, types, data sources. Also includes instructions specific to each component. - -#### C. Get Data Source Values -``` -GET_DATA_SOURCE_VALUES -``` -Returns: Valid values for properties with data sources. - -### Step 4: Update and Redeploy - -Modify the generated XML, adding components discovered via MCP. Deploy incrementally. +**Anti-pattern:** Creating entire complex page at once → hard-to-debug error cascade --- -## Critical XML Rules +## Critical Rules (Read First) ### 1. Property Value Encoding (MOST COMMON ERROR) -**Any property value with HTML/XML characters MUST be manually encoded in the following order** (wrong order causes double-encoding corruption): +**ANY property value containing HTML/XML tags MUST be manually encoded in your XML.** +Common properties with HTML: +- Component labels with formatting: `Important` +- Rich text descriptions +- Help text with links: `Link` + +**Encoding rules you must apply:** ``` -1. & → & (FIRST! Encode this before others) -2. < → < -3. > → > -4. " → " -5. ' → ' +< → < +> → > +& → & +" → " +' → ' ``` -**Wrong:** +**Wrong XML (will fail deployment):** ```xml -Important text + + label + Important: Read this + ``` -**Correct:** +**Correct XML (manually encoded):** ```xml -<b>Important</b> text + + label + <b>Important:</b> Read this + ``` -**Check your XML:** Search for `` tags - they should never contain raw `<` or `>` characters. +**Process:** +1. When writing component properties, scan for `<`, `>`, `&`, `"`, or `'` characters +2. **BEFORE writing XML**, manually replace each with its entity +3. Write the encoded value directly into the XML +4. **VERIFY**: Search your generated XML for `` tags - check they don't contain raw HTML tags + +**Self-check:** If you see `` or `Text") +``` +Returns `encoded` field - copy that exact string into your XML `` tag. ### 2. Field References **ALWAYS:** `Record.{FieldApiName}` **NEVER:** `{ObjectName}.{FieldApiName}` +**Correct:** ```xml - Record.Name +``` - +**Incorrect:** +```xml Account.Name ``` ### 3. Region vs Facet Types -**Template Regions** (header, main, sidebar): -```xml -header -Region -``` - -**Component Facets** (internal slots like fieldSection columns): -```xml -Facet-12345 -Facet -``` - -**Rule:** If it's a template region name → `Region`. If it's a component slot → `Facet`. +- Template regions (header, main, sidebar) → `Region` +- Component facets (internal slots) → `Facet` ### 4. fieldInstance Structure Every fieldInstance requires: -```xml - - - - uiBehavior - none - - Record.FieldName__c - RecordFieldName_cField - - -``` - -**Rules:** -- Each fieldInstance in its own `` wrapper -- Must have `fieldInstanceProperties` with `uiBehavior` -- Use `Record.{Field}` format +- Own `` wrapper +- `fieldInstanceProperties` with `uiBehavior` +- `Record.{Field}` format --- -## Using MCP Actions +## Generation Workflow -### When to Use Each Action +### Step 1: Get Metadata Information +``` +get_metadata_resource("flexiPage-knowledge") +``` +Returns: This knowledge content, metadata skills, resource URIs (knowledge://, schema://, example://), and schema content -#### DISCOVER_UI_COMPONENTS -**When:** You want to see what components are available for your page type. +### Step 2: Examine Existing FlexiPages +**CRITICAL:** Study working FlexiPages BEFORE creating spec. Real examples show actual XML patterns. -**Returns:** Component list with names, namespaces, descriptions. +**Priority 1: Org-Retrieved FlexiPages (Best Source)** -**Use for:** Finding components to add to your bootstrapped page. +Check `/main/default/flexipages/` for existing FlexiPages: +- Use standard file tools: `list_dir`, `read_file` +- These are org-specific, production-tested pages +- Show real component usage, not theoretical patterns +- **Most valuable reference** - use as primary template -#### GET_UI_COMPONENT_SCHEMAS -**When:** You know which components you want but need to understand their properties. If you have issues configuring a component and need more detailed instructions or knowledge. +**Priority 2: Static Examples (Fallback)** -**Returns:** JSON schemas with: -- Required vs optional properties -- Property types (string, boolean, array, etc.) -- Data source references -- Descriptions -- Additional component-specific instructions or knowledge, often useful for more complex components. +If no org FlexiPages exist, use static examples via URIs from Step 1: +``` +get_metadata_resource("example://FlexiPage/0") +``` +Index 0 is the App Page example +Index 1 is the Home Page example +Index 2 is the Record Page example -**Use for:** Understanding how to configure components before adding to XML. +**What to learn:** +- Complete XML structure (regions, Facets, components) +- Remember that regions need to be adjusted to match the page template +- fieldInstance structure (itemInstances, fieldInstanceProperties) +- Facet definition and reference patterns +- Component property formats +- Valid starting point for new pages -#### GET_DATA_SOURCE_VALUES -**When:** A component property references a data source and you need valid values. +**Use as structural reference when generating XML.** -**Returns:** Valid values (e.g., "1", "2", "3" for column count). +### Step 3: Get Templates +``` +get_page_templates("RecordPage") +``` +Returns: Available templates and their required regions -**Use for:** Ensuring property values match allowed options. +### Step 4: Create Specification File + +**Purpose:** Plan what the user wants to achieve (business requirements), NOT just inventory existing components. + +**File:** `.flexipage__spec.md` (delete after deployment) + +```markdown +# FlexiPage: [Page Name] + +## Goal +[1-2 sentences: what should this page accomplish for users?] + +## Page Info +- Type: RecordPage|AppPage|HomePage +- Object: [if RecordPage] +- Template: [chosen from step 2] + +## Functionality Required + +### [Region Name] +1. **[Functionality Description]** + - Purpose: [what user needs to do] + - Solution: [existing component URI] OR [Custom component to build] + - Config needed: [properties, fields, etc.] + +2. **[Another Functionality]** + - Purpose: [user need] + - Solution: [component or "TODO: Build CustomComponent__c"] + - Config needed: [details] + +## Custom Components Needed +- [ ] [ComponentName] - [what it does, why existing components insufficient] + +## Fields to Display +- [Field] - [why user needs to see this] + +## Relationships/Data +- [ ] Verify [relationship] exists for [component] + +## Open Questions +- [Anything uncertain that needs clarification] +``` + +**Key principle:** Spec describes DESIRED functionality, not technical inventory. Include custom components that don't exist yet. + +### Step 5: Discover Components +``` +get_org_component_palette(target: "lightning__RecordPage") +``` +Use to find components that match functionality in spec. Not all functionality may have existing components. + +### Step 6: Get Component Details +``` +get_org_component_metadata([uris], includeAiInfo: true, includeSource: false) +``` +For components identified in step 5. + +**When debugging property errors:** Fetch source code to understand component internals: +``` +get_org_component_metadata([uri], includeSource: true) +``` +Source code shows: +- Actual property names and types +- Required vs. optional properties +- Property value formats +- Decorators and annotations + +Use when: AI descriptions are unclear or property errors occur during deployment. + +### Step 7: Get Component Knowledge (When Available) +Check metadata skills from Step 1. Call for complex components: +``` +get_component_knowledge("fieldSection") +``` + +**Components with knowledge:** `fieldSection`, `dynamicHighlights`, `dynamicRelatedList` + +### Step 8: Update Spec with Solutions +Mark which functionality uses existing components vs. needs custom development. + +### Step 9: Get User Approval +Present spec. Confirm approach before generating XML. + +### Step 10: Generate XML +Follow approved spec. **Use example file from Step 2 as structural reference.** + +**Incremental approach:** +1. Start with minimal version (e.g., header + one main component) +2. Deploy and validate +3. Add next component or region +4. Deploy again +5. Repeat until complete + +Key patterns from examples: +- Template regions (`type="Region"`) vs. component facets (`type="Facet"`) +- Facet structure and references +- fieldInstance with fieldInstanceProperties +- Region and component nesting +- Property value formats + +--- + +## Using Examples Effectively + +### Example Priority + +1. **Org FlexiPages** (in `force-app/main/default/flexipages/`) - **Best source** + - Production-tested, org-specific + - Access via `list_dir`, `read_file` +2. **Static examples** (from metadata information response) - Fallback only + +### When to Reference Examples + +1. **Before creating spec** (Step 2): Understand existing patterns +2. **Before generating XML** (Step 10): Copy structural patterns +3. **When debugging errors**: Compare your XML to working examples + +### What Examples Show + +**Facet Patterns:** +- How Facets are defined with `type="Facet"` +- How components reference Facets in properties +- Field Facets vs. component Facets + +**Field Structure:** +- `fieldInstance` always in own `itemInstances` +- `fieldInstanceProperties` with `uiBehavior` required +- `Record.{Field}` format (never object name) + +**Component Configuration:** +- Property formats (`componentInstanceProperties`) +- ValueLists for arrays +- Facet references in properties + +**Region Structure:** +- Required regions for templates +- Component placement in regions +- Nesting patterns + +### How to Use Examples + +1. **Check org first**: `list_dir force-app/main/default/flexipages/`, then `read_file` similar page types +2. **If no org pages**: Use static examples for your page type +3. **Identify similar components** to what you need +4. **Copy XML structure patterns**, not exact content +5. **Adapt** to your specific fields/components +6. **Maintain** the same nesting and property structure + +**Workflow:** +- Need dynamicHighlights? → Find org RecordPage with header region, or use static example +- Need fields in main? → Find org page with fieldSection, or use static example +- Need related list? → Find org page with similar component, or use static example + +--- + +## Critical XML Rules + +### Parent flexipage +**DO NOT** define a parent flexipage: do not include \`\` tags + +### Field References +**ALWAYS:** `Record.{FieldApiName}` +**NEVER:** `{ObjectName}.{FieldApiName}` + +**Correct:** +```xml +Record.Name +``` + +**Incorrect:** +```xml +Account.Name +``` + +### fieldInstance Requirements +**Every fieldInstance MUST have:** +1. Its own `` wrapper (no grouping) +2. `fieldInstanceProperties` with `uiBehavior` +3. `Record.{Field}` format + +```xml + + + + + uiBehavior + none + + Record.Name + RecordNameField + + + Facet-uuid + Facet + +``` + +### Region vs. Facet Types +**CRITICAL DISTINCTION:** + +**Template Regions** (header, main, sidebar, etc.): +- Use `Region` +- Defined by page template +- **ONLY** use regions defined in the page template +- **DO NOT** define a \`\` for regions +- Top-level containers for components + +```xml + + + + record_flexipage:dynamicHighlights + highlights + + + header + Region + +``` + +**Component Facets** (component slots like column body, fieldSection columns): +- Use `Facet` +- Internal component properties +- Referenced by component properties + +```xml + + + + + uiBehavior + none + + Record.Name + RecordNameField + + + Facet-uuid + Facet + +``` + +### Facet Rules +- Each Facet referenced exactly once by a component property +- No unused Facets +- Unique names (use UUIDs for Facets) + +--- + +## Component-Specific Guidance + +### fieldSection +**Retrieve knowledge before use.** Complex three-level nesting required. + +### dynamicHighlights +**Retrieve knowledge before use.** Two approaches: +- Compact Layout (no config) - if object has compact layout +- Explicit Fields (Facets) - for new objects without compact layouts + +**Must be in header region.** + +### dynamicRelatedList +**Retrieve knowledge before use.** +- Use relationship name (NOT field name) +- Format: `parentFieldApiName: {Object}.Id` --- ## Common Deployment Errors ### "Invalid field reference" -**Cause:** Used `ObjectName.Field` instead of `Record.Field` -**Fix:** Change to `Record.{FieldApiName}` +Wrong: `Delivery__c.Order_Number__c` +Fix: `Record.Order_Number__c` ### "Element fieldInstance is duplicated" -**Cause:** Multiple fieldInstances in one itemInstances -**Fix:** Each fieldInstance needs its own `` wrapper +Cause: Multiple fieldInstances in one itemInstances +Fix: Separate itemInstances for each ### "Missing fieldInstanceProperties" -**Cause:** No uiBehavior specified -**Fix:** Add `fieldInstanceProperties` with `uiBehavior` +Cause: No uiBehavior +Fix: Add fieldInstanceProperties block with uiBehavior -### "Invalid component property" -**Cause:** Wrong property name or format -**Fix:** Use `GET_UI_COMPONENT_SCHEMAS` to see exact property names and types, or to find additional documentation. +### "Invalid component property" / "Unknown property" +Cause: Wrong property name or format +**Debug strategy:** Fetch component source code: +``` +get_org_component_metadata([uri], includeSource: true) +``` +Source code reveals exact property names, types, and required values. ### "Unused Facet" -**Cause:** Facet defined but not referenced by any component -**Fix:** Remove Facet or reference it in a component property +Cause: Facet defined but not referenced +Fix: Reference in component property or remove -### "XML parsing error" -**Cause:** Unencoded HTML/XML in property values -**Fix:** Manually encode `<`, `>`, `&`, `"`, `'` in all `` tags +### "Invalid Region/Facet type" +**Cause:** Using wrong type for context -### "Cannot create component with namespace" -**Cause:** Invalid page name (don't use `__c` suffix in page names) -**Fix:** Use "Volunteer_Record_Page" not "Volunteer__c_Record_Page" +**Fix:** +- Template regions (header, main, sidebar) → `Region` +- Component facets (column body, fieldSection columns) → `Facet` -### "Region specifies mode that parent doesn't support" -**Cause:** Added `` tag to region -**Fix:** Remove `` tags - they're not needed for standard regions +Common mistake: Using `Facet` for header/main/sidebar regions + +### Region specifies mode that parent region doesn't support +**Cause:** Using a mode that is not enabled for the parent region +**Fix:** Remove the mode from the region + +### "XML parsing error" / "Malformed XML" / "Unexpected element" +**Cause:** Unencoded HTML/XML tags in property values + +**Fix:** See "Critical Rules" section at top of this spec for encoding requirements. You must manually encode `<`, `>`, `&`, `"`, `'` characters in property values before writing XML. + +### Cannot create a new component with the namespace +**Cause:** invalid flexipage name or file name +**Fix:** Do not include \`__c\` suffix in page names and *.flexipage-meta.xml file names --- -## Component-Specific Tips +## Template Region Requirements -### dynamicHighlights (RecordPage Header) +Templates specify which regions are required. Get from `get_page_templates`. -**Location:** Must be in `header` region. -**Explicit Fields** (via CLI): Use the most important fields to show a summary of the record. The single primary field is used to identify the record, like a name. The secondary fields (max 12, recommended 6) are used as a summary of the record. -```bash ---primary-field Name ---secondary-fields Phone,Industry,AnnualRevenue -``` -CLI generates Facets with field references automatically. +Common patterns: +- Three-column: header, main, sidebar +- Two-column: main, sidebar +- Single: main -### fieldSection - -**Use for:** Displaying fields in columns. - -**Structure:** Three-level nesting: -1. Template Region (Region type) -2. Column Facets (Facet type) -3. Field Facets (Facet type) - -**Referenced in component property:** -```xml - - columns - Facet-{uuid} - -``` ---- - -## Incremental Development Pattern - -**Philosophy:** Deploy small, working increments. Don't build entire complex page at once. - -**Process:** -1. **CLI bootstrap** → Deploy base page -2. **Add one component** → Deploy -3. **Add another component** → Deploy -4. **Repeat** until complete - -**Benefits:** -- Isolated errors (know exactly what broke) -- Faster debugging -- Build confidence with each success -- Get user feedback early - -**Anti-pattern:** Building entire complex page → one giant error cascade. +**All required regions must have at least one component.** --- -## Adding Components to Existing FlexiPages +## Deprecated Components -### Workflow - -When user provides an existing FlexiPage file path: - -1. **Read the file** using native file I/O -2. **Parse XML** to extract: - - Existing component identifiers - - Available regions (parse from file, don't assume names) - - Existing facets -3. **Use MCP actions** for discovery: - - DISCOVER_UI_COMPONENTS (find available components) - - GET_UI_COMPONENT_SCHEMAS (understand properties and get additional documentation) - - GET_DATA_SOURCE_VALUES (validate data source values) -4. **Generate component XML** (apply all rules from "Critical XML Rules" section) -5. **Insert** into appropriate region -6. **Write** modified XML back to file -7. **Deploy**: `sf project deploy start --source-dir force-app/...` +**DO NOT USE:** +- `force:detailPanel` → use `flexipage:fieldSection` +- `force:highlightsPanel` → use `record_flexipage:dynamicHighlights` --- -### Generating Unique Identifiers - -**Algorithm**: -``` -1. Extract all existing values from XML -2. Generate base name: {componentType}_{context} - Examples: "relatedList_contacts", "richText_header", "tabs_main" -3. Find first available number: - - Try "{base}_1" - - If exists, try "{base}_2", "{base}_3", etc. - - Use first available -``` - -**Examples**: -- First contacts related list: `relatedList_contacts_1` -- Second contacts related list: `relatedList_contacts_2` -- Rich text in header: `richText_header_1` -- Field section: `fieldSection_details_1` - -**Facet Naming - Two Patterns**: - -1. **Named facets** (for major content areas): - - `detailTabContent` (detail tab content) - - `maintabs` (main tab container) - - `sidebartabs` (sidebar tab container) - - Use when facet represents meaningful content area - -2. **UUID facets** (for internal structure): - - Format: `Facet-{8hex}-{4hex}-{4hex}-{4hex}-{12hex}` - - Example: `Facet-66d5a4b3-bf14-4665-ba75-1ceaa71b2cde` - - Use for field section columns, nested containers, anonymous slots - ---- - -### Region Selection - -**Parse regions from file** - don't hardcode names. Templates vary: -- `flexipage:recordHomeTemplateDesktop` → `header`, `main`, `sidebar` -- `runtime_service_fieldservice:...` → `header`, `main`, `footer` -- Others may have different region names - -**Default placement**: End of target region (after last ``) - -**Insertion pattern**: -```xml - - main - Region - - - - - - -``` - ---- - -### Container Components with Facets - -Components like tabs, accordions, field sections require facets. - -**Pattern**: -```xml - - - - - flexipage:tabset2 - tabs_main_1 - - tabs - tab1_content - tab2_content - - - - main - Region - - - - - - tab1_content - Facet - - - - - tab2_content - Facet - -``` - -**Critical**: Facet regions are siblings of template regions at the same level, not nested inside them. - ---- - -## Required Metadata Structure +## Required Metadata ```xml - - - + ... Page Label - - RecordPage + + RecordPage|AppPage|HomePage Object__c ``` -**Page Types:** -- `RecordPage` - requires `` -- `AppPage` - no sobjectType -- `HomePage` - no sobjectType +## Naming Conventions +- NO `__c` suffix in page names and *.flexipage-meta.xml file names: "Volunteer_Record_Page.flexipage-meta.xml" not "Volunteer__c_Record_Page.flexipage-meta.xml" +- Unique component identifiers +- Exact field API names from Salesforce ---- - -## Validation Checklist - -Before deploying: -- [ ] Used CLI to bootstrap (don't start from scratch) -- [ ] All field references use `Record.{Field}` format -- [ ] Each fieldInstance has `fieldInstanceProperties` with `uiBehavior` -- [ ] Each fieldInstance in own `` wrapper -- [ ] Template regions use `Region` -- [ ] Component facets use `Facet` -- [ ] Property values with HTML/XML are manually encoded +## Validation Before Deployment +- [ ] **Using incremental deployment** (start minimal, add iteratively) +- [ ] **Reviewed org FlexiPages** (force-app/main/default/flexipages/) or static examples for structural reference +- [ ] All fields: `Record.{Field}` format +- [ ] Every fieldInstance has fieldInstanceProperties +- [ ] Each fieldInstance in own itemInstances +- [ ] **Template regions (header, main, sidebar): `type="Region"`** +- [ ] **Component facets: `type="Facet"`** +- [ ] **Property values with HTML/XML tags are XML-encoded** +- [ ] Component knowledge followed (if available) +- [ ] Template regions populated - [ ] No `` tags in regions -- [ ] No `__c` suffix in page names -- [ ] Each Facet referenced by exactly one component property - ---- - -## Quick Reference: CLI Command - -```bash -# RecordPage with fields -sf template generate flexipage \ - --name Account_Custom_Page \ - --template RecordPage \ - --sobject Account \ - --primary-field Name \ - --secondary-fields Phone,Industry,AnnualRevenue \ - --detail-fields Street,City,State,Name,Phone,Email - -# AppPage -sf template generate flexipage \ - --name Sales_Dashboard \ - --template AppPage \ - --label "Sales Dashboard" - -# HomePage -sf template generate flexipage \ - --name Custom_Home \ - --template HomePage \ - --description "Custom home for sales team" -``` - -**All templates support:** -- `--output-dir` (default: current directory) -- `--api-version` (default: latest) -- `--label` (default: page name) -- `--description` +- [ ] No deprecated components