@salesforce/afv-skills 1.48.0 → 1.50.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 (31) hide show
  1. package/package.json +1 -1
  2. package/skills/education-cloud-multi-campus-configure/SKILL.md +0 -5
  3. package/skills/field-service-data-capture-form-deployer-configure/SKILL.md +180 -0
  4. package/skills/field-service-data-capture-form-deployer-configure/examples/inventory-transfer-spec.json +135 -0
  5. package/skills/field-service-data-capture-form-deployer-configure/examples/sample-spec.json +140 -0
  6. package/skills/field-service-data-capture-form-deployer-configure/examples/sectioned-spec.json +64 -0
  7. package/skills/field-service-data-capture-form-deployer-configure/references/field-types.md +297 -0
  8. package/skills/field-service-data-capture-form-deployer-configure/references/flow-metadata-json.md +243 -0
  9. package/skills/field-service-data-capture-form-deployer-configure/references/post-screen-automation.md +127 -0
  10. package/skills/field-service-data-capture-form-designer-configure/SKILL.md +110 -0
  11. package/skills/field-service-data-capture-form-designer-configure/references/extraction-from-image.md +244 -0
  12. package/skills/field-service-data-capture-form-designer-configure/references/extraction-from-prompt.md +222 -0
  13. package/skills/field-service-data-capture-form-editor-configure/SKILL.md +134 -0
  14. package/skills/field-service-data-capture-reference-configure/SKILL.md +762 -0
  15. package/skills/field-service-data-capture-reference-configure/examples/DataCapture_Showcase.flow-meta.xml +2022 -0
  16. package/skills/field-service-data-capture-reference-configure/examples/Data_Capture_All_Components.flow-meta.xml +2170 -0
  17. package/skills/field-service-data-capture-reference-configure/examples/Repeater_with_prepopulation.flow-meta.xml +231 -0
  18. package/skills/field-service-foundation-setup-designer-get/SKILL.md +135 -0
  19. package/skills/field-service-mobile-branding-configure/SKILL.md +133 -0
  20. package/skills/field-service-mobile-branding-configure/examples/dark-blue-scheme.json +16 -0
  21. package/skills/field-service-mobile-branding-configure/examples/salesforce-default-scheme.json +16 -0
  22. package/skills/field-service-mobile-branding-configure/references/color-fields.md +66 -0
  23. package/skills/field-service-mobile-branding-configure/references/contrast-validation.md +55 -0
  24. package/skills/field-service-mobile-branding-configure/references/derivation-methodology.md +83 -0
  25. package/skills/field-service-objective-designer-configure/SKILL.md +342 -0
  26. package/skills/field-service-prework-brief-deployer-configure/SKILL.md +83 -0
  27. package/skills/field-service-scheduling-policy-designer-query/SKILL.md +121 -0
  28. package/skills/field-service-setup-orchestrator-get/SKILL.md +48 -0
  29. package/skills/field-service-sobject-create-configure/SKILL.md +56 -0
  30. package/skills/field-service-voice-to-form-configure/SKILL.md +650 -0
  31. package/skills/field-service-work-rule-designer-configure/SKILL.md +303 -0
@@ -0,0 +1,231 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Flow xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <areMetricsLoggedToDataCloud>false</areMetricsLoggedToDataCloud>
4
+ <customProperties>
5
+ <name>IsLlmTargetable</name>
6
+ <value>
7
+ <stringValue>{&quot;value&quot;:&quot;false&quot;}</stringValue>
8
+ </value>
9
+ </customProperties>
10
+ <environments>Offline</environments>
11
+ <interviewLabel>Repeater with prepopulation (joost) {!$Flow.CurrentDateTime}</interviewLabel>
12
+ <label>Repeater with prepopulation (joost)</label>
13
+ <loops>
14
+ <name>Loop_Through_Repeater</name>
15
+ <label>Loop Through Repeater</label>
16
+ <locationX>0</locationX>
17
+ <locationY>0</locationY>
18
+ <collectionReference>accountRepeater.AllItems</collectionReference>
19
+ <iterationOrder>Asc</iterationOrder>
20
+ <nextValueConnector>
21
+ <targetReference>Repeater_Output_Screen</targetReference>
22
+ </nextValueConnector>
23
+ </loops>
24
+ <processMetadataValues>
25
+ <name>BuilderType</name>
26
+ <value>
27
+ <stringValue>LightningFlowBuilder</stringValue>
28
+ </value>
29
+ </processMetadataValues>
30
+ <processMetadataValues>
31
+ <name>CanvasMode</name>
32
+ <value>
33
+ <stringValue>AUTO_LAYOUT_CANVAS</stringValue>
34
+ </value>
35
+ </processMetadataValues>
36
+ <processMetadataValues>
37
+ <name>OriginBuilderType</name>
38
+ <value>
39
+ <stringValue>LightningFlowBuilder</stringValue>
40
+ </value>
41
+ </processMetadataValues>
42
+ <processType>DataCaptureFlow</processType>
43
+ <recordLookups>
44
+ <name>Get_3_ServiceResources</name>
45
+ <label>Get 3 Service Resources</label>
46
+ <locationX>0</locationX>
47
+ <locationY>0</locationY>
48
+ <assignNullValuesIfNoRecordsFound>false</assignNullValuesIfNoRecordsFound>
49
+ <connector>
50
+ <targetReference>Screen_Repeater</targetReference>
51
+ </connector>
52
+ <getFirstRecordOnly>false</getFirstRecordOnly>
53
+ <limit>
54
+ <numberValue>3.0</numberValue>
55
+ </limit>
56
+ <object>ServiceResource</object>
57
+ <storeOutputAutomatically>true</storeOutputAutomatically>
58
+ </recordLookups>
59
+ <screens>
60
+ <name>Repeater_Output_Screen</name>
61
+ <label>Repeater Output Screen</label>
62
+ <locationX>0</locationX>
63
+ <locationY>0</locationY>
64
+ <allowBack>true</allowBack>
65
+ <allowFinish>true</allowFinish>
66
+ <allowPause>true</allowPause>
67
+ <connector>
68
+ <targetReference>Loop_Through_Repeater</targetReference>
69
+ </connector>
70
+ <fields>
71
+ <name>display_info_2</name>
72
+ <fieldText>&lt;p&gt;ServiceResource Id:{!Loop_Through_Repeater.UniqueField__Id}&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255);&quot;&gt;Resource Type: {!Loop_Through_Repeater.description.value}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Name: {!Loop_Through_Repeater.name.value}&lt;/p&gt;</fieldText>
73
+ <fieldType>DisplayText</fieldType>
74
+ <styleProperties>
75
+ <verticalAlignment>
76
+ <stringValue>top</stringValue>
77
+ </verticalAlignment>
78
+ <width>
79
+ <stringValue>12</stringValue>
80
+ </width>
81
+ </styleProperties>
82
+ </fields>
83
+ <showFooter>true</showFooter>
84
+ <showHeader>true</showHeader>
85
+ </screens>
86
+ <screens>
87
+ <name>Screen_Repeater</name>
88
+ <label>Screen Repeater</label>
89
+ <locationX>0</locationX>
90
+ <locationY>0</locationY>
91
+ <allowBack>true</allowBack>
92
+ <allowFinish>true</allowFinish>
93
+ <allowPause>true</allowPause>
94
+ <connector>
95
+ <targetReference>Loop_Through_Repeater</targetReference>
96
+ </connector>
97
+ <fields>
98
+ <name>accountRepeater</name>
99
+ <fieldType>Repeater</fieldType>
100
+ <fields>
101
+ <name>account_info</name>
102
+ <fieldText>&lt;p&gt;Id: {!Get_3_ServiceResources[$EachItem].Id}&lt;/p&gt;</fieldText>
103
+ <fieldType>DisplayText</fieldType>
104
+ <styleProperties>
105
+ <verticalAlignment>
106
+ <stringValue>top</stringValue>
107
+ </verticalAlignment>
108
+ <width>
109
+ <stringValue>12</stringValue>
110
+ </width>
111
+ </styleProperties>
112
+ </fields>
113
+ <fields>
114
+ <name>name</name>
115
+ <extensionName>runtime_service_fieldservice:dcTextInput</extensionName>
116
+ <fieldType>ComponentInstance</fieldType>
117
+ <inputParameters>
118
+ <name>label</name>
119
+ <value>
120
+ <stringValue>Name</stringValue>
121
+ </value>
122
+ </inputParameters>
123
+ <inputParameters>
124
+ <name>required</name>
125
+ <value>
126
+ <booleanValue>false</booleanValue>
127
+ </value>
128
+ </inputParameters>
129
+ <inputParameters>
130
+ <name>value</name>
131
+ <value>
132
+ <elementReference>Get_3_ServiceResources[$EachItem].Name</elementReference>
133
+ </value>
134
+ </inputParameters>
135
+ <inputsOnNextNavToAssocScrn>UseStoredValues</inputsOnNextNavToAssocScrn>
136
+ <isRequired>true</isRequired>
137
+ <storeOutputAutomatically>true</storeOutputAutomatically>
138
+ <styleProperties>
139
+ <verticalAlignment>
140
+ <stringValue>top</stringValue>
141
+ </verticalAlignment>
142
+ <width>
143
+ <stringValue>12</stringValue>
144
+ </width>
145
+ </styleProperties>
146
+ </fields>
147
+ <fields>
148
+ <name>description</name>
149
+ <extensionName>runtime_service_fieldservice:dcLongText</extensionName>
150
+ <fieldType>ComponentInstance</fieldType>
151
+ <inputParameters>
152
+ <name>label</name>
153
+ <value>
154
+ <stringValue>Resource Type</stringValue>
155
+ </value>
156
+ </inputParameters>
157
+ <inputParameters>
158
+ <name>value</name>
159
+ <value>
160
+ <elementReference>Get_3_ServiceResources[$EachItem].ResourceType</elementReference>
161
+ </value>
162
+ </inputParameters>
163
+ <inputsOnNextNavToAssocScrn>UseStoredValues</inputsOnNextNavToAssocScrn>
164
+ <isRequired>true</isRequired>
165
+ <storeOutputAutomatically>true</storeOutputAutomatically>
166
+ <styleProperties>
167
+ <verticalAlignment>
168
+ <stringValue>top</stringValue>
169
+ </verticalAlignment>
170
+ <width>
171
+ <stringValue>12</stringValue>
172
+ </width>
173
+ </styleProperties>
174
+ </fields>
175
+ <inputParameters>
176
+ <name>collection</name>
177
+ <value>
178
+ <elementReference>Get_3_ServiceResources</elementReference>
179
+ </value>
180
+ </inputParameters>
181
+ <isRequired>false</isRequired>
182
+ <styleProperties>
183
+ <verticalAlignment>
184
+ <stringValue>top</stringValue>
185
+ </verticalAlignment>
186
+ <width>
187
+ <stringValue>12</stringValue>
188
+ </width>
189
+ </styleProperties>
190
+ </fields>
191
+ <showFooter>true</showFooter>
192
+ <showHeader>true</showHeader>
193
+ </screens>
194
+ <start>
195
+ <locationX>0</locationX>
196
+ <locationY>0</locationY>
197
+ <connector>
198
+ <targetReference>Get_3_ServiceResources</targetReference>
199
+ </connector>
200
+ </start>
201
+ <status>Draft</status>
202
+ <variables>
203
+ <name>accountRecords</name>
204
+ <dataType>SObject</dataType>
205
+ <isCollection>true</isCollection>
206
+ <isInput>false</isInput>
207
+ <isOutput>false</isOutput>
208
+ <objectType>Account</objectType>
209
+ </variables>
210
+ <variables>
211
+ <name>parentObjectType</name>
212
+ <dataType>String</dataType>
213
+ <isCollection>false</isCollection>
214
+ <isInput>true</isInput>
215
+ <isOutput>false</isOutput>
216
+ </variables>
217
+ <variables>
218
+ <name>parentRecordId</name>
219
+ <dataType>String</dataType>
220
+ <isCollection>false</isCollection>
221
+ <isInput>true</isInput>
222
+ <isOutput>false</isOutput>
223
+ </variables>
224
+ <variables>
225
+ <name>recordId</name>
226
+ <dataType>String</dataType>
227
+ <isCollection>false</isCollection>
228
+ <isInput>true</isInput>
229
+ <isOutput>false</isOutput>
230
+ </variables>
231
+ </Flow>
@@ -0,0 +1,135 @@
1
+ ---
2
+ name: field-service-foundation-setup-designer-get
3
+ description: "Creates Field Service foundation data — Work Types, Skills, Service Territories, and Operating Hours. Accepts existing data in any format or designs from scratch, and confirms the design with the user. Use this skill when a user wants to create, design, or set up Field Service foundation data."
4
+ user-invocable: false
5
+ metadata:
6
+ version: "1.0"
7
+ domains: ["Field Service"]
8
+ ---
9
+
10
+ # Field Service Foundation Setup Designer
11
+
12
+ **Design or refine Field Service foundation data — Work Types, Skills, Service Territories, Operating Hours, and other associated Field Service objects — through structured interviews. Starting from scratch or from existing recommendations.**
13
+
14
+ This skill runs a design conversation — it does not call Salesforce APIs directly. It collects the design through a structured conversation, whether starting from scratch or working from existing data, and confirms the final design with the user. This skill covers two design workflows in sequence (or independently):
15
+
16
+ 1. **Work Types & Skills** — 6-question interview
17
+ 2. **Service Territories & Operating Hours** — 3-question interview
18
+
19
+ ## Entry point
20
+
21
+ - **Starting from scratch** → run the full interview phases below to build the design.
22
+ - **Have existing data** — this includes scraped/read source output, JSON or text provided by the user, or any other external source brought into context. Show a plain-English summary of the proposed configuration as a starting reference, then immediately ask: "Would you like to go through a guided design interview to refine this, or proceed directly with this configuration?" Wait for the answer before doing anything else.
23
+ - **Ready to create** → show a plain-English summary of the records to be created (not raw JSON or skill names), ask for explicit confirmation, then proceed only after the user confirms.
24
+
25
+ Never expose internal skill names, SOR IDs, or tool references to the user.
26
+
27
+ ## When to use
28
+
29
+ - Starting Field Service setup from scratch — no existing Work Types or Territories yet
30
+ - When initial recommendations need adjustment for either work types or territories (or both)
31
+ - To explore different granularity levels (Work Types) or territory models (Territories)
32
+ - When customer provides additional context about their business or coverage areas
33
+ - During discovery sessions to design or iterate on the foundation data model
34
+
35
+ ## Design principles
36
+
37
+ 1. **Structured questions with consistent intent**
38
+ - Questions based on Work Type Implementation Guide and Service Territory Design Guide
39
+ - Adapt examples to customer's business context
40
+ - Intent stays consistent, wording adapts intelligently
41
+
42
+ 2. **Brief answers must work**
43
+ - "No", "Yes", "No we don't" are complete answers
44
+ - Progress to next question immediately
45
+ - No explanations required
46
+
47
+ 3. **Smart question adaptation**
48
+ - Check if topic already covered
49
+ - If covered: brief confirmatory question
50
+ - If not covered + business context: customize examples
51
+ - If not covered + no context: exact structured question
52
+
53
+ 4. **Question format** (three or four parts):
54
+ ```markdown
55
+ **Recommendation:** [Only include when context is sufficient. Lead with the best-fit option given what's known, then briefly note alternatives with the condition under which they'd apply instead — not a flat menu of equal choices, but a ranked steer. Omit entirely when confidence is low.]
56
+
57
+ **Question:** [The actual question — or a lighter "does this fit?" when a Recommendation is present]
58
+
59
+ **Why I'm asking:** [1-2 sentences: why this matters]
60
+
61
+ **Impact:** [1-2 sentences: how their answer affects the design]
62
+ ```
63
+
64
+ ## How it works
65
+
66
+ ### Pre-phase: Source ingestion (if provided)
67
+
68
+ If no source has been provided, creatively ask the user whether they have a website or document that describes their business or Field Service operation — framing it as something that would help build a more accurate and tailored starting recommendation rather than a generic one.
69
+
70
+ If the user provides a URL, fetch it. Extract Field Service-relevant signals: industry, service types, geographic coverage, team and skill structure. Use these to generate an initial recommendation covering Work Types, Skills, Service Territories, and Operating Hours — which feeds into the refinement interview rather than starting from nothing.
71
+
72
+ ### Phase 1: Work Types & Skills
73
+
74
+ 1. **Accept input**: Takes existing data in any format (JSON, CSV, free-form text), or starts fresh if nothing is provided.
75
+ 2. **Interview**: Cover these topics — service line granularity, equipment size/type variations, brand/model specificity, service tiers and site types, parts tracking, duration accuracy.
76
+ 3. **Output**: Designed Work Types and Skills as JSON + change log.
77
+
78
+ ### Phase 2: Service Territories & Operating Hours
79
+
80
+ 1. **Accept input**: Same as Phase 1.
81
+ 2. **Interview**: Cover these topics — territory structure (geographic/functional/hybrid), geographic boundaries (if applicable), functional team geographic constraints (if applicable).
82
+ 3. **Output**: Designed Service Territories and Operating Hours as JSON + change log.
83
+
84
+
85
+ ## Inputs
86
+
87
+ - **Source material** (optional): A URL the agent will fetch to extract business context and generate an initial recommendation. Takes precedence over manually pasted data when both are provided.
88
+ - **Existing data** (optional): Work Types/Skills and/or Service Territories/Operating Hours in any format — JSON, CSV, free-form text, or pasted output from a prior session. If nothing is provided, recommendations are built entirely through the interview.
89
+ - **Business context** (optional): Additional context to tailor interview questions to the customer's industry or service model.
90
+
91
+ ## Outputs
92
+
93
+ - Designed or refined Work Types with metadata
94
+ - Skills inventory organized by category
95
+ - Designed or refined Service Territories with structure
96
+ - Operating Hours organized by timezone
97
+ - Combined JSON export (Salesforce API-ready, for deployment via `sfs-sobject-create`)
98
+ - Markdown summary with change log
99
+ - Before/after comparison (when refining existing data)
100
+
101
+ ## Granularity Levels Reference (Work Types)
102
+
103
+ From Work Type Implementation Guide:
104
+
105
+ | Level | When to Use | Example |
106
+ |-------|-------------|---------|
107
+ | **High-Level** | Simple service models, quick setup | "Installation", "Repair", "Maintenance" |
108
+ | **Mid-Level** | Equipment-specific service | "HVAC Installation", "HVAC Repair" |
109
+ | **Detailed** | Brand-specific service needs | "HVAC Installation (Carrier)", "HVAC Installation (Trane)" |
110
+ | **Hyper-Specific** | SLA/site variations | "HVAC Repair (Carrier) - Hospital" |
111
+
112
+ **Best practice:** Start with simplest model possible, increase granularity only when necessary.
113
+
114
+ ## Territory Models Reference (Service Territories)
115
+
116
+ From Service Territory Design Guide:
117
+
118
+ | Model | When to Use | Example |
119
+ |-------|-------------|---------|
120
+ | **Geographic** | Location-based coverage, reduce travel time | "Northern California", "Southwest Region" |
121
+ | **Functional** | Specialized service types, skill-based assignment | "Fire Safety Team", "Commercial HVAC Team" |
122
+ | **Hybrid** | Combined benefits, specialized teams with regional boundaries | "Northern CA - Fire Safety", "Southwest - Commercial HVAC" |
123
+
124
+ **Best practice:** Start with simplest model possible, increase complexity only when necessary.
125
+
126
+ ---
127
+
128
+ ## Output format
129
+
130
+ Generate the output JSON payload from interview answers using this mapping:
131
+
132
+ - `WorkType` → `SkillRequirement` (junction → `Skill`)
133
+ - `WorkType` → `ProductRequired` (junction → `Product2`)
134
+ - `OperatingHours` → `TimeSlot` (parent-child)
135
+ - `ServiceTerritory` → `OperatingHours` (lookup)
@@ -0,0 +1,133 @@
1
+ ---
2
+ name: field-service-mobile-branding-configure
3
+ description: "Derive a Field Service mobile app color scheme from a brand source (URL, hex codes, brand-guide paste, or color description), validate WCAG AA contrast in both light and dark mode, and apply the 14-field scheme to the org-default FieldServiceMobileSettings record. Trigger phrases include 'brand the mobile app', 'apply branding to Field Service mobile', 'update the mobile app colors', 'use this brand guide for the app', 'set the color scheme for the mobile app'. Do NOT use this skill for Dispatcher console / Gantt branding, Experience Cloud BrandingSet records, or scheduling policy colors — out of scope."
4
+ user-invocable: false
5
+ metadata:
6
+ version: "1.0"
7
+ domains: ["Field Service"]
8
+ ---
9
+
10
+ # Field Service Mobile Branding
11
+
12
+ This skill ingests a brand source and produces a 14-field color scheme that gets applied to the org-default `FieldServiceMobileSettings` record (`DeveloperName='Field_Service_Mobile_Settings'`, `IsDefault=true`). Confirmation with the user happens between derivation and apply — never apply without approval.
13
+
14
+ > **Source:** This skill was authored by Chad Barbour and is mirrored from an
15
+ > upstream Field Service assets repository.
16
+ > Methodology, color tables, and contrast checks are unchanged from upstream — refresh from upstream when content changes there.
17
+
18
+ > **Runtime contract:** every org interaction in this skill is a single REST
19
+ > call dispatched through the Codey runtime (`execute_api` locally / the hosted
20
+ > Headless 360 MCP in shared surfaces). This skill has **no dependency on the
21
+ > execution environment** — no `sf` CLI, no shell scripts, no local Python, no
22
+ > temp files. Colors are derived and validated by the agent inline, then
23
+ > written with one sObject PATCH. Do not shell out.
24
+
25
+ ## Input contract
26
+
27
+ One of:
28
+
29
+ - A website URL — fetch with `WebFetch`, extract dominant brand colors.
30
+ - A brand-guide paste or document — parse for hex codes and named colors.
31
+ - Direct hex codes — accept as-is.
32
+ - A color description (e.g. "we're a red and white company") — ask for at least one specific hex code or URL before proceeding.
33
+
34
+ See [reference/derivation-methodology.md](reference/derivation-methodology.md) for the four ingestion cases (A–D) in detail.
35
+
36
+ ## Output
37
+
38
+ A 14-field color scheme written to the org-default `FieldServiceMobileSettings` record via a single sObject PATCH (`PATCH /services/data/vXX.0/sobjects/FieldServiceMobileSettings/{id}`). Color changes appear on devices after the metadata cache refreshes (default: 7 days, force-refreshable from app Settings).
39
+
40
+ ## Workflow
41
+
42
+ ### 1. Confirm the target org
43
+
44
+ **Before fetching the brand source**, confirm the org is reachable with a cheap auth probe — dispatch `SELECT Id FROM Organization LIMIT 1` (`GET /services/data/vXX.0/query`):
45
+
46
+ - 2xx with `totalSize=1` → the session token is live; continue.
47
+ - 401/403 → the org needs re-authentication. Surface that to the user and **stop**; do not proceed to apply.
48
+
49
+ Then ask: "Which org should I apply this to?" and wait for explicit confirmation before proceeding. Do not assume a default — even if the user mentioned an org name in their request, confirm it explicitly so there are no surprises. (The Codey runtime resolves the connected org; this skill does not manage org aliases.)
50
+
51
+ ### 2. Ingest the brand source
52
+
53
+ Follow the cases (A–D) in [reference/derivation-methodology.md](reference/derivation-methodology.md). At the end of this step you should have two anchors:
54
+
55
+ - **Primary brand color** — for non-interactive surfaces and the navbar.
56
+ - **Secondary/interactive color** — for buttons, links, FAB.
57
+
58
+ ### 3. Derive the full 14-field scheme
59
+
60
+ Apply the derivation rules in [reference/derivation-methodology.md](reference/derivation-methodology.md) and the field semantics in [reference/color-fields.md](reference/color-fields.md).
61
+
62
+ Hold the scheme in memory as a flat object whose keys match the 14 `FieldServiceMobileSettings` color fields. Use [examples/salesforce-default-scheme.json](examples/salesforce-default-scheme.json) as a template. Before continuing, self-check that all 14 fields are present and every value matches `^#[0-9A-Fa-f]{6}$` (6-digit hex, `#` prefix — 3-digit shorthand and missing `#` are invalid); fix any that don't before proposing.
63
+
64
+ ### 4. Validate contrast (light + dark mode)
65
+
66
+ Compute the WCAG AA contrast ratio for each pair in [reference/contrast-validation.md](reference/contrast-validation.md) **inline** — this is deterministic arithmetic on the hex values you already hold, not an external tool. For each `#RRGGBB` pair:
67
+
68
+ 1. Normalize each channel: `r = R/255, g = G/255, b = B/255`.
69
+ 2. Linearize each channel: `c ≤ 0.03928 → c/12.92`, else `((c+0.055)/1.055)^2.4`.
70
+ 3. Relative luminance: `L = 0.2126·r + 0.7152·g + 0.0722·b`.
71
+ 4. Contrast ratio: `(L_lighter + 0.05) / (L_darker + 0.05)`.
72
+
73
+ Evaluate all 5 light-mode pairs and all 5 dark-mode pairs from [reference/contrast-validation.md](reference/contrast-validation.md); a pair PASSES at `≥ 4.5:1` (WCAG AA, normal text). Surface any FAIL pairs to the user with a suggested fix in step 5. Note that brand colors are fixed across both modes, so a passing light-mode scheme can still fail dark-mode pairs.
74
+
75
+ ### 5. Present proposal & confirm
76
+
77
+ Show the user:
78
+
79
+ - A `Brand & Navigation` / `Contrast Scale` / `Feedback Colors` table of all 14 fields with their hex values and roles.
80
+ - The light-mode and dark-mode contrast results from step 4, with FAIL pairs flagged.
81
+ - The target org alias.
82
+
83
+ Ask the user to confirm before applying. Use the suggested fixes in [reference/contrast-validation.md](reference/contrast-validation.md) when proposing alternatives for failing pairs.
84
+
85
+ ### 6. Apply to org
86
+
87
+ Apply only after the user has approved the proposal in step 5. Three REST calls:
88
+
89
+ 1. **Confirm FLS (optional but recommended).** `GET /services/data/vXX.0/sobjects/FieldServiceMobileSettings/describe` and confirm each of the 14 color fields has `updateable: true`. A field with `updateable: false` (or a filtered describe) is the earliest signal the running user lacks edit access — surface that before attempting the PATCH.
90
+
91
+ 2. **Resolve the org-default record.** `GET /services/data/vXX.0/query` with `SELECT Id FROM FieldServiceMobileSettings WHERE DeveloperName = 'Field_Service_Mobile_Settings' AND IsDefault = true LIMIT 1`. `totalSize = 0` means Field Service Mobile is not provisioned — surface the error and stop (see step 7). Otherwise take `records[0].Id`.
92
+
93
+ 3. **Write the scheme.** `PATCH /services/data/vXX.0/sobjects/FieldServiceMobileSettings/{id}` with a flat JSON body of the 14 color fields. Merge semantics — only fields in the body are written. Do **not** send `IsDefault` (not updateable). A 204 (no body) is success; then GET the record back to confirm the values landed.
94
+
95
+ ### 7. Report back
96
+
97
+ On success, print:
98
+
99
+ - `FieldServiceMobileSettings` record id.
100
+ - Timestamp of the update.
101
+ - Reminder that the metadata cache is 7 days by default — devices won't show the new scheme until the cache refreshes or a tech force-refreshes from app Settings.
102
+
103
+ If the apply fails because no `Field_Service_Mobile_Settings` record exists, surface the error and stop — Field Service Mobile may not be set up in the org. Direct the user to Setup → Field Service Mobile Settings to bootstrap the default record, then retry.
104
+
105
+ ## Scope
106
+
107
+ **Generated automatically:**
108
+
109
+ - The full 14-field color scheme derived from one or two brand anchors plus optional brand neutrals and semantic colors.
110
+ - Light-mode and dark-mode WCAG AA contrast validation across 5 light-mode + 5 dark-mode pairs, computed inline by the agent.
111
+ - Apply via a single sObject PATCH against the org-default `FieldServiceMobileSettings` record.
112
+
113
+ **Out of scope:**
114
+
115
+ - Splash screen, profile tab background image, push notification icon — Setup-only uploads.
116
+ - Per-profile `FieldServiceMobileSettings` records (multi-config orgs) — this skill targets the single `IsDefault=true` record. If the org has multiple records, query first and confirm which `DeveloperName` to update.
117
+ - Dispatcher console / Gantt colors (`FSLQA__GanttPalette__c`).
118
+ - `BrandingSet` metadata (Experience Cloud / Lightning App branding — does not theme the FS mobile app).
119
+
120
+ ## Files in this skill
121
+
122
+ - `reference/color-fields.md` — the 14 fields, descriptions, defaults, JSON schema.
123
+ - `reference/contrast-validation.md` — light + dark mode pair definitions, formulas, common fixes.
124
+ - `reference/derivation-methodology.md` — translating brand sources into a full scheme, edge cases.
125
+ - `examples/salesforce-default-scheme.json` — the out-of-the-box Salesforce purple/blue scheme.
126
+ - `examples/dark-blue-scheme.json` — Salesforce-themed dark blue scheme (also serves as a contrast-warnings example).
127
+
128
+ Contrast validation and scheme derivation are performed by the agent inline (see steps 3–4); there are no executable scripts in this skill. Org writes are single REST calls dispatched through the Codey runtime.
129
+
130
+ ## Related skills
131
+
132
+ - `configure-field-service-mobile` — page layouts, permissions, and `FieldServiceSettings` toggles. This skill defers branding to here, and this skill defers structural mobile config to it.
133
+ - `fs-data-capture-form-deployer` — generates and deploys Data Capture Flow metadata.
@@ -0,0 +1,16 @@
1
+ {
2
+ "NavbarBackgroundColor": "#0F4C81",
3
+ "NavbarInvertedColor": "#FFFFFF",
4
+ "PrimaryBrandColor": "#0F4C81",
5
+ "SecondaryBrandColor": "#1589EE",
6
+ "BrandInvertedColor": "#FFFFFF",
7
+ "ContrastPrimaryColor": "#16325C",
8
+ "ContrastSecondaryColor": "#54698D",
9
+ "ContrastTertiaryColor": "#9FAAB5",
10
+ "ContrastQuaternaryColor": "#DDDBDA",
11
+ "ContrastQuinaryColor": "#F4F6F9",
12
+ "ContrastInvertedColor": "#FFFFFF",
13
+ "FeedbackPrimaryColor": "#C23934",
14
+ "FeedbackSecondaryColor": "#04844B",
15
+ "FeedbackSelectedColor": "#FFFFFF"
16
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "NavbarBackgroundColor": "#803ABE",
3
+ "NavbarInvertedColor": "#FFFFFF",
4
+ "PrimaryBrandColor": "#803ABE",
5
+ "SecondaryBrandColor": "#2A7AB0",
6
+ "BrandInvertedColor": "#FFFFFF",
7
+ "ContrastPrimaryColor": "#000000",
8
+ "ContrastSecondaryColor": "#444444",
9
+ "ContrastTertiaryColor": "#9FAAB5",
10
+ "ContrastQuaternaryColor": "#E6E6EB",
11
+ "ContrastQuinaryColor": "#EEEEEE",
12
+ "ContrastInvertedColor": "#FFFFFF",
13
+ "FeedbackPrimaryColor": "#C23934",
14
+ "FeedbackSecondaryColor": "#13C4A3",
15
+ "FeedbackSelectedColor": "#FFFFFF"
16
+ }
@@ -0,0 +1,66 @@
1
+ # Color Fields
2
+
3
+ The `FieldServiceMobileSettings` sObject has **14 color fields**, all hex strings (`#RRGGBB`). The org-default record has `IsDefault = true` and `DeveloperName = 'Field_Service_Mobile_Settings'`. There is one default record per org.
4
+
5
+ Color values are **light-mode** values. Dark mode inverts the contrast scale automatically — see [contrast-validation.md](contrast-validation.md).
6
+
7
+ ## Brand & Navigation
8
+
9
+ | Field | Description | Salesforce default |
10
+ |---|---|---|
11
+ | `NavbarBackgroundColor` | The color of the top bar in the app | `#803ABE` |
12
+ | `NavbarInvertedColor` | The secondary color of the top bar in the app | `#FFFFFF` |
13
+ | `PrimaryBrandColor` | The color of **non-interactive** areas in the app | `#803ABE` |
14
+ | `SecondaryBrandColor` | The color of **interactive** areas in the app | `#2A7AB0` |
15
+ | `BrandInvertedColor` | The color of toasts and the contrast color for the floating action button | `#FFFFFF` |
16
+
17
+ ## Contrast Scale
18
+
19
+ | Field | Description | Salesforce default |
20
+ |---|---|---|
21
+ | `ContrastPrimaryColor` | The color of primary text | `#000000` |
22
+ | `ContrastSecondaryColor` | The color of secondary text | `#444444` |
23
+ | `ContrastTertiaryColor` | The color of icons on the settings screen and primary lines delineating UI areas | `#9FAAB5` |
24
+ | `ContrastQuaternaryColor` | The color of some graphics and secondary lines delineating UI areas | `#E6E6EB` |
25
+ | `ContrastQuinaryColor` | The color of the background behind cards in the UI | `#EEEEEE` |
26
+ | `ContrastInvertedColor` | The color of card backgrounds in the UI | `#FFFFFF` |
27
+
28
+ ## Feedback / Status Colors
29
+
30
+ | Field | Description | Salesforce default |
31
+ |---|---|---|
32
+ | `FeedbackPrimaryColor` | The color of error messages | `#C23934` |
33
+ | `FeedbackSecondaryColor` | The color of success messages or progress icons | `#13C4A3` |
34
+ | `FeedbackSelectedColor` | The color indicating the user's current selection | `#FFFFFF` |
35
+
36
+ ## Key distinctions
37
+
38
+ - `PrimaryBrandColor` = non-interactive colored areas (schedule icon dot, section labels, decorative elements).
39
+ - `SecondaryBrandColor` = interactive elements (buttons, links, GET DIRECTIONS, floating action button background).
40
+ - `NavbarBackgroundColor` and `PrimaryBrandColor` are typically the same color.
41
+ - `ContrastInvertedColor` = card backgrounds (usually white), not just inverted text.
42
+
43
+ ## JSON spec shape
44
+
45
+ The skill consumes a flat JSON object whose keys match the 14 field names exactly:
46
+
47
+ ```json
48
+ {
49
+ "NavbarBackgroundColor": "#0070D2",
50
+ "NavbarInvertedColor": "#FFFFFF",
51
+ "PrimaryBrandColor": "#0070D2",
52
+ "SecondaryBrandColor": "#1589EE",
53
+ "BrandInvertedColor": "#FFFFFF",
54
+ "ContrastPrimaryColor": "#000000",
55
+ "ContrastSecondaryColor": "#444444",
56
+ "ContrastTertiaryColor": "#9FAAB5",
57
+ "ContrastQuaternaryColor": "#E6E6EB",
58
+ "ContrastQuinaryColor": "#EEEEEE",
59
+ "ContrastInvertedColor": "#FFFFFF",
60
+ "FeedbackPrimaryColor": "#C23934",
61
+ "FeedbackSecondaryColor": "#13C4A3",
62
+ "FeedbackSelectedColor": "#FFFFFF"
63
+ }
64
+ ```
65
+
66
+ Hex must be 6 digits with the `#` prefix. 3-digit shorthand and missing `#` are invalid — the agent rejects them during the step-3 self-check before proposing or applying.
@@ -0,0 +1,55 @@
1
+ # Contrast Validation
2
+
3
+ The Field Service mobile app supports both light and dark mode. The `FieldServiceMobileSettings` color fields apply to **light mode**. Dark mode inverts the contrast scale automatically — but brand and feedback colors remain fixed. A scheme that passes in light mode can fail in dark mode if the brand colors clash with dark backgrounds.
4
+
5
+ The agent computes contrast ratios for the pairs below inline (the formulas are at the bottom of this file) and reports pass/fail against WCAG AA (`4.5:1` for normal text). Surface any failures to the user before applying.
6
+
7
+ ## Light mode pairs
8
+
9
+ | Pair | Foreground | Background |
10
+ |---|---|---|
11
+ | Navbar text on navbar bg | `NavbarInvertedColor` | `NavbarBackgroundColor` |
12
+ | Toast/FAB text on brand bg | `BrandInvertedColor` | `PrimaryBrandColor` |
13
+ | Selected indicator on interactive | `FeedbackSelectedColor` | `SecondaryBrandColor` |
14
+ | Primary text on card bg | `ContrastPrimaryColor` | `ContrastInvertedColor` |
15
+ | Secondary text on card bg | `ContrastSecondaryColor` | `ContrastInvertedColor` |
16
+
17
+ ## Dark mode pairs
18
+
19
+ In dark mode, the app inverts the contrast scale: card backgrounds become dark (`ContrastPrimaryColor`), and text becomes light (`ContrastInvertedColor`). Brand and feedback colors do **not** change.
20
+
21
+ | Pair | Effective foreground | Effective background |
22
+ |---|---|---|
23
+ | Primary text on dark card bg | `ContrastInvertedColor` | `ContrastPrimaryColor` |
24
+ | Secondary brand (interactive) on dark bg | `SecondaryBrandColor` | `ContrastPrimaryColor` |
25
+ | Feedback error on dark bg | `FeedbackPrimaryColor` | `ContrastPrimaryColor` |
26
+ | Feedback success on dark bg | `FeedbackSecondaryColor` | `ContrastPrimaryColor` |
27
+ | Navbar (unchanged in dark mode) | `NavbarInvertedColor` | `NavbarBackgroundColor` |
28
+
29
+ ## Dark mode risk factors to flag
30
+
31
+ - A **very light secondary brand color** (e.g. pastel yellow, light teal) may wash out against a dark-mode card bg — check `SecondaryBrandColor` on `ContrastPrimaryColor`.
32
+ - A **light primary brand color** (e.g. CAT yellow `#FFCD11`) will have reduced contrast against light backgrounds when used as a label color in dark mode. Flag if luminance > 0.4.
33
+ - **Feedback colors** — standard red and teal/green are generally safe in dark mode. Verify if the brand specifies non-standard semantic colors.
34
+
35
+ ## Luminance & contrast formulas
36
+
37
+ For `#RRGGBB`:
38
+
39
+ 1. Normalize: `r = R/255, g = G/255, b = B/255`
40
+ 2. Linearize each channel: if `c ≤ 0.03928 → c/12.92`, else `((c+0.055)/1.055)^2.4`
41
+ 3. Relative luminance: `L = 0.2126·r + 0.7152·g + 0.0722·b`
42
+ 4. Contrast ratio: `(L_lighter + 0.05) / (L_darker + 0.05)`
43
+
44
+ WCAG AA threshold for normal text: **4.5:1**.
45
+
46
+ ## Common fixes for failures
47
+
48
+ | Failure | Suggested fix |
49
+ |---|---|
50
+ | Navbar pair fails (light navbar) | Use a darker brand neutral for `NavbarBackgroundColor` |
51
+ | `FeedbackSelectedColor` on `SecondaryBrandColor` fails (light interactive) | Use `#1C1C1C` or darkest brand neutral for `FeedbackSelectedColor` |
52
+ | `BrandInvertedColor` on `PrimaryBrandColor` fails (light primary) | Switch `BrandInvertedColor` to `#000000` or darkest neutral |
53
+ | `SecondaryBrandColor` on `ContrastPrimaryColor` fails in dark mode | Pick a darker variant of the interactive color, or accept reduced contrast and note it in the proposal |
54
+
55
+ Each suggested fix should specify which mode (light, dark, or both) it affects, so the user can weigh tradeoffs before applying.