SKILL.md
$28
CRITICAL: Orchestration Order
sf-industry-commoncore-omnistudio-analyze → sf-industry-commoncore-datamapper → sf-industry-commoncore-integration-procedure → sf-industry-commoncore-omniscript → sf-industry-commoncore-flexcard (you are here: sf-industry-commoncore-omniscript)
OmniScripts consume Integration Procedures and DataRaptors. Build those FIRST. FlexCards may launch OmniScripts — build FlexCards AFTER. Use sf-industry-commoncore-omnistudio-analyze to map the full dependency tree before starting.
Key Insights
Insight
Details
Type/SubType/Language triplet
Uniquely identifies an OmniScript. All three values are required and form the composite key. Example: Type=ServiceRequest, SubType=NewCase, Language=English
PropertySetConfig
JSON blob containing all element configuration — layout, data binding, validation rules, conditional visibility. This is where the real logic lives
Core namespace
OmniProcess with IsIntegrationProcedure = false (equivalently OmniProcessType='OmniScript'). Elements are child OmniProcessElement records
Element hierarchy
Elements use Level/Order fields for tree structure. Level 0 = Steps, Level 1+ = elements within steps. Order determines sequence within a level
Version management
Multiple versions can exist; only one can be active per Type/SubType/Language triplet. Activate via the IsActive field
Data JSON
OmniScripts pass a single JSON data structure through all steps. Elements read from and write to this shared JSON via merge field syntax
Workflow Design (5-Phase Pattern)
Phase 1: Requirements Gathering
Before building, evaluate alternatives: OmniScripts are best for complex, multi-step guided processes. For simple single-screen data entry, consider Screen Flows. For data display without interaction, consider FlexCards.
Ask the user to gather:
- Type: The process category (e.g.,
ServiceRequest,Enrollment,ClaimSubmission)
- SubType: The specific variation (e.g.,
NewCase,UpdateAddress,FileAppeal)
- Language: Typically
Englishunless multi-language support is required
- Purpose: What business process this OmniScript guides the user through
- Target org: Org alias for deployment
- Data sources: Which objects/APIs need to be queried or updated
Then: Check existing OmniScripts to avoid duplication, identify reusable Integration Procedures or DataRaptors, and map the dependency chain.
Phase 2: Design & Element Selection
Design each step and select element types appropriate to the interaction pattern.
#### Container Elements
Element Type
Purpose
Key Config
Step
Top-level container for a group of UI elements; each Step is a page in the wizard
chartLabel, knowledgeOptions, show (conditional visibility)
Conditional Block
Show/hide a group of elements based on conditions
conditionType, show expression
Loop Block
Iterate over a data list and render elements for each item
loopData (JSON path to array)
Edit Block
Inline editing container for tabular data
editFields, dataSource
#### Input Elements
Element Type
Purpose
Key Config
Text
Single-line text input
label, placeholder, pattern (regex validation)
Text Area
Multi-line text input
label, maxLength, rows
Number
Numeric input with optional formatting
label, min, max, step, format
Date
Date picker
label, dateFormat, minDate, maxDate
Date/Time
Date and time picker
label, dateFormat, timeFormat
Checkbox
Boolean toggle
label, defaultValue
Radio
Radio button group for single selection
label, options (static or data-driven)
Select
Dropdown selection
label, options, optionSource (static/data)
Multi-select
Multiple item selection
label, options, maxSelections
Type Ahead
Search/autocomplete input
label, dataSource, searchField, minCharacters
Signature
Signature capture pad
label, penColor, backgroundColor
File
File upload
label, maxFileSize, allowedExtensions
Currency
Currency input with locale formatting
label, currencyCode, min, max
Email input with format validation
label, placeholder
Telephone
Phone number input with masking
label, mask, placeholder
URL
URL input with format validation
label, placeholder
Password
Masked text input
label, minLength
Range
Slider input
label, min, max, step
Time
Time picker
label, timeFormat
#### Display Elements
Element Type
Purpose
Key Config
Text Block
Static content display (HTML supported)
textContent, HTMLTemplateId
Headline
Section heading
text, level (h1-h6)
Aggregate
Calculated summary display
aggregateExpression, format
Disclosure
Expandable/collapsible content
label, defaultExpanded
Image
Image display
imageURL, altText
Chart
Data visualization
chartType, dataSource
#### Action Elements
Element Type
Purpose
Key Config
DataRaptor Extract Action
Pull data from Salesforce
bundle, inputMap, outputMap
DataRaptor Load Action
Push data to Salesforce
bundle, inputMap
Integration Procedure Action
Call server-side Integration Procedure
ipMethod (Type_SubType), inputMap, outputMap, remoteOptions
Remote Action
Call Apex @RemoteAction or REST
remoteClass, remoteMethod, inputMap
Navigate Action
Page navigation or redirection
targetType, targetId, URL
DocuSign Envelope Action
Trigger DocuSign envelope
templateId, recipientMap
Email Action
Send email
emailTemplateId, recipientMap
#### Logic Elements
Element Type
Purpose
Key Config
Set Values
Variable assignment and data transformation
elementValueMap (key-value pairs)
Validation
Input validation rules with custom messages
validationFormula, errorMessage
Formula
Calculate values using formula expressions
expression, dataType
Submit Action
Final submission of collected data
postMessage, preTransformBundle, postTransformBundle
Phase 3: Generation & Validation
# Verify no duplicate Type/SubType/Language exists
sf data query -q "SELECT Id,Name,Type,SubType,Language,IsActive,VersionNumber FROM OmniProcess WHERE Type='<Type>' AND SubType='<SubType>' AND Language='<Language>' AND OmniProcessType='OmniScript'" -o <org>
Build the OmniScript:
- Create the OmniProcess record with Type, SubType, Language, and OmniProcessType='OmniScript'
- Create OmniProcessElement child records for each Step (Level=0)
- Create OmniProcessElement child records for each element within Steps (Level=1+, ordered by Order field)
- Configure PropertySetConfig JSON for each element
- Wire action elements to their Integration Procedures / DataRaptors
Validation (STRICT MODE):
- BLOCK: Missing Type/SubType/Language, circular OmniScript embedding, broken IP/DataRaptor references, missing required PropertySetConfig fields
- WARN: Steps with no elements, input elements without validation, missing error handling on actions, unused data paths, deeply nested elements (>4 levels)
Validation Report Format (6-Category Scoring 0-120):
Score: 102/120 ---- Very Good
-- Design & Structure: 22/25 (88%)
-- Data Integration: 18/20 (90%)
-- Error Handling: 17/20 (85%)
-- Performance: 18/20 (90%)
-- User Experience: 17/20 (85%)
-- Security: 10/15 (67%)
Phase 4: Deployment
- Deploy all dependencies first: DataRaptors, Integration Procedures, referenced OmniScripts
- Retrieve or deploy OmniScript metadata:
sf project retrieve start -m OmniScript:<Name> -o <org>
sf project deploy start -m OmniScript:<Name> -o <org>
- Activate the OmniScript version after successful deployment
- Verify activation:
sf data query -q "SELECT Id,Name,Type,SubType,Language,IsActive,VersionNumber FROM OmniProcess WHERE Type='<Type>' AND SubType='<SubType>' AND OmniProcessType='OmniScript' AND IsActive=true" -o <org>
Phase 5: Testing
Walk through all paths with various data scenarios:
- Happy path: Complete all steps with valid data, verify submission
- Validation testing: Submit invalid data at each input, verify error messages
- Conditional testing: Exercise all conditional blocks and verify show/hide logic
- Data prefill: Verify DataRaptor Extract Actions populate elements correctly
- Save for later: Test resume functionality if enabled
- Navigation: Test back/forward/cancel behavior across all steps
- Error scenarios: Simulate IP/DataRaptor failures, verify error handling
- Embedded OmniScripts: Test data passing between parent and child OmniScripts
- Bulk data: Test with large datasets in Loop Blocks and Type Ahead elements
Generation Guardrails (MANDATORY)
Anti-Pattern
Impact
Correct Pattern
Circular OmniScript embedding
Infinite rendering loop
Map dependency tree; never embed A in B if B embeds A
Unbounded DataRaptor Extract
Performance degradation
Add filter conditions; limit returned records
Missing input validation
Bad data entry
Add Validation elements or pattern/required on inputs
Hardcoded Salesforce IDs
Deployment failure across orgs
Use merge fields or Custom Settings/Metadata
IP Action without error handling
Silent failures
Configure showError, errorMessage in PropertySetConfig
Large images in Text Blocks
Slow page load
Use Image elements with optimized URLs
Too many elements per Step
Poor user experience
Limit to 7-10 input elements per Step
Missing conditional visibility
Irrelevant fields shown
Use show expressions to hide inapplicable elements
DO NOT generate anti-patterns even if explicitly requested.
Scoring: 120 Points Across 6 Categories
Design & Structure (25 points)
Check
Points
Criteria
Type/SubType/Language set correctly
5
All three fields populated with meaningful values
Step organization
5
Logical grouping, 7-10 elements per step max
Element naming
5
Descriptive names following PascalCase convention
Conditional logic
5
Proper use of Conditional Blocks and show expressions
Version management
5
Clean version history, only one active version
Data Integration (20 points)
Check
Points
Criteria
DataRaptor references valid
5
All Extract/Load bundles exist and are active
Integration Procedure references valid
5
All IP actions reference active IPs
Input/Output maps correct
5
Data flows correctly between elements and actions
Data prefill configured
5
Initial data loaded before user interaction
Error Handling (20 points)
Check
Points
Criteria
Action elements have error handling
5
showError configured on all IP/DR actions
User-facing error messages
5
Clear, actionable error text
Validation on required inputs
5
All required fields have validation rules
Fallback behavior defined
5
Graceful handling when data sources return empty
Performance (20 points)
Check
Points
Criteria
No unbounded data fetches
5
All DataRaptor Extracts have filters/limits
Lazy loading configured
5
Action elements fire on step entry, not OmniScript load
Element count per Step reasonable
5
No Step with >15 elements
Conditional rendering used
5
Elements hidden when not applicable (not just invisible)
User Experience (20 points)
Check
Points
Criteria
Logical step flow
5
Steps follow natural task progression
Input labels and help text
5
All inputs have clear labels and contextual help
Navigation controls
5
Back, Next, Cancel, Save for Later configured appropriately
Responsive layout
5
Elements configured for mobile and desktop breakpoints
Security (15 points)
Check
Points
Criteria
No sensitive data in client-side JSON
5
Passwords, SSNs, tokens kept server-side
IP actions use server-side processing
5
Sensitive logic in Integration Procedures, not client OmniScript
Field-level access respected
5
Data access matches user profile/permission set
CLI Commands
# List active OmniScripts
sf data query -q "SELECT Id,Name,Type,SubType,Language,IsActive,VersionNumber FROM OmniProcess WHERE IsActive=true AND OmniProcessType='OmniScript'" -o <org>
# Query elements for a specific OmniScript
sf data query -q "SELECT Id,Name,ElementType,PropertySetConfig,Level,Order FROM OmniProcessElement WHERE OmniProcessId='<id>' ORDER BY Level,Order" -o <org>
# Retrieve OmniScript metadata
sf project retrieve start -m OmniScript:<Name> -o <org>
# Deploy OmniScript metadata
sf project deploy start -m OmniScript:<Name> -o <org>
# Check OmniScript versions
sf data query -q "SELECT Id,VersionNumber,IsActive,LastModifiedDate FROM OmniProcess WHERE Type='<Type>' AND SubType='<SubType>' AND OmniProcessType='OmniScript' ORDER BY VersionNumber DESC" -o <org>
Cross-Skill Integration
From Skill
To sf-industry-commoncore-omniscript
When
sf-industry-commoncore-omnistudio-analyze
-> sf-industry-commoncore-omniscript
"Analyze dependencies before building OmniScript"
sf-industry-commoncore-datamapper
-> sf-industry-commoncore-omniscript
"DataRaptor ready, build the OmniScript that uses it"
sf-industry-commoncore-integration-procedure
-> sf-industry-commoncore-omniscript
"IP ready, wire it into the OmniScript action"
From sf-industry-commoncore-omniscript
To Skill
When
sf-industry-commoncore-omniscript
-> sf-industry-commoncore-flexcard
"Build FlexCard that launches this OmniScript"
sf-industry-commoncore-omniscript
-> sf-deploy
"Deploy OmniScript to target org"
sf-industry-commoncore-omniscript
-> sf-industry-commoncore-omnistudio-analyze
"Map full dependency tree before deployment"
sf-industry-commoncore-omniscript
-> sf-industry-commoncore-integration-procedure
"Need a new IP for this OmniScript action"
sf-industry-commoncore-omniscript
-> sf-industry-commoncore-datamapper
"Need a DataRaptor for data prefill"
Edge Cases
Scenario
Solution
Multi-language OmniScript
Create separate versions per Language with shared Type/SubType. Use translation workbench for labels
Embedded OmniScript data passing
Map parent data JSON keys to child OmniScript input via prefillJSON. Test data round-trip
Large Loop Block datasets
Paginate or limit DataRaptor results. Consider server-side filtering in IP
OmniScript in FlexCard flyout
Ensure FlexCard passes required context data. Test flyout sizing
Community/Experience Cloud deployment
Verify OmniScript component is available in Experience Builder. Check guest user permissions
Save & Resume (Save for Later)
Configure saveNameTemplate, saveExpireInDays. Test resume with partial data
Versioning conflicts
Deactivate old version before activating new. Never have two active versions for same triplet
Custom Lightning Web Components in OmniScript
Register LWC as OmniScript-compatible. Follow omniscript-lwc namespace conventions
Debug: OmniScript not rendering -> check activation status + element hierarchy | Data not prefilling -> verify DataRaptor Extract output mapping + JSON path | IP action failing -> check IP independently first + verify input map | Steps not showing -> review conditional visibility expressions
Notes
Dependencies (required): sf-industry-commoncore-datamapper, sf-industry-commoncore-integration-procedure | Dependencies (optional): sf-deploy, sf-industry-commoncore-flexcard, sf-industry-commoncore-omnistudio-analyze | API: 66.0 | Mode: Strict (warnings block) | Scoring: Block deployment if score < 67 | Reference docs: See references/ for element types and best practices
Creating OmniScripts programmatically: Use REST API (sf api request rest --method POST --body @file.json). Required fields: Name, Type, SubType, Language, VersionNumber. OmniScripts default to IsIntegrationProcedure=false (do NOT set OmniProcessType — it is computed). The sf data create record --values flag cannot handle JSON textarea fields like PropertySetConfig. Create child OmniProcessElement records via REST API for each Step and element.
License
MIT License.
Copyright (c) 2026 David Ryan (weytani)