scc-universal 1.1.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 (271) hide show
  1. package/.claude-plugin/plugin.json +44 -0
  2. package/.cursor/agents/deep-researcher.md +142 -0
  3. package/.cursor/agents/doc-updater.md +219 -0
  4. package/.cursor/agents/eval-runner.md +335 -0
  5. package/.cursor/agents/learning-engine.md +210 -0
  6. package/.cursor/agents/loop-operator.md +245 -0
  7. package/.cursor/agents/refactor-cleaner.md +119 -0
  8. package/.cursor/agents/sf-admin-agent.md +127 -0
  9. package/.cursor/agents/sf-agentforce-agent.md +126 -0
  10. package/.cursor/agents/sf-apex-agent.md +117 -0
  11. package/.cursor/agents/sf-architect.md +426 -0
  12. package/.cursor/agents/sf-aura-reviewer.md +369 -0
  13. package/.cursor/agents/sf-bugfix-agent.md +101 -0
  14. package/.cursor/agents/sf-flow-agent.md +155 -0
  15. package/.cursor/agents/sf-integration-agent.md +141 -0
  16. package/.cursor/agents/sf-lwc-agent.md +123 -0
  17. package/.cursor/agents/sf-review-agent.md +357 -0
  18. package/.cursor/agents/sf-visualforce-reviewer.md +465 -0
  19. package/.cursor/hooks/adapter.js +81 -0
  20. package/.cursor/hooks/after-file-edit.js +26 -0
  21. package/.cursor/hooks/after-mcp-execution.js +12 -0
  22. package/.cursor/hooks/after-shell-execution.js +30 -0
  23. package/.cursor/hooks/after-tab-file-edit.js +12 -0
  24. package/.cursor/hooks/before-mcp-execution.js +11 -0
  25. package/.cursor/hooks/before-read-file.js +13 -0
  26. package/.cursor/hooks/before-shell-execution.js +29 -0
  27. package/.cursor/hooks/before-submit-prompt.js +23 -0
  28. package/.cursor/hooks/pre-compact.js +7 -0
  29. package/.cursor/hooks/session-end.js +10 -0
  30. package/.cursor/hooks/session-start.js +10 -0
  31. package/.cursor/hooks/stop.js +18 -0
  32. package/.cursor/hooks/subagent-start.js +10 -0
  33. package/.cursor/hooks/subagent-stop.js +10 -0
  34. package/.cursor/hooks.json +107 -0
  35. package/.cursor/skills/aside/SKILL.md +115 -0
  36. package/.cursor/skills/checkpoint/SKILL.md +50 -0
  37. package/.cursor/skills/configure-scc/SKILL.md +160 -0
  38. package/.cursor/skills/continuous-agent-loop/SKILL.md +260 -0
  39. package/.cursor/skills/mcp-server-patterns/SKILL.md +142 -0
  40. package/.cursor/skills/model-route/SKILL.md +81 -0
  41. package/.cursor/skills/prompt-optimizer/SKILL.md +366 -0
  42. package/.cursor/skills/refactor-clean/SKILL.md +133 -0
  43. package/.cursor/skills/resume-session/SKILL.md +111 -0
  44. package/.cursor/skills/save-session/SKILL.md +183 -0
  45. package/.cursor/skills/search-first/SKILL.md +140 -0
  46. package/.cursor/skills/security-scan/SKILL.md +142 -0
  47. package/.cursor/skills/sessions/SKILL.md +124 -0
  48. package/.cursor/skills/sf-agentforce-development/SKILL.md +449 -0
  49. package/.cursor/skills/sf-apex-async-patterns/SKILL.md +324 -0
  50. package/.cursor/skills/sf-apex-best-practices/SKILL.md +421 -0
  51. package/.cursor/skills/sf-apex-constraints/SKILL.md +79 -0
  52. package/.cursor/skills/sf-apex-cursor/SKILL.md +336 -0
  53. package/.cursor/skills/sf-apex-enterprise-patterns/SKILL.md +344 -0
  54. package/.cursor/skills/sf-apex-testing/SKILL.md +407 -0
  55. package/.cursor/skills/sf-api-design/SKILL.md +237 -0
  56. package/.cursor/skills/sf-approval-processes/SKILL.md +312 -0
  57. package/.cursor/skills/sf-aura-development/SKILL.md +260 -0
  58. package/.cursor/skills/sf-build-fix/SKILL.md +120 -0
  59. package/.cursor/skills/sf-data-modeling/SKILL.md +274 -0
  60. package/.cursor/skills/sf-debugging/SKILL.md +362 -0
  61. package/.cursor/skills/sf-deployment/SKILL.md +291 -0
  62. package/.cursor/skills/sf-deployment-constraints/SKILL.md +153 -0
  63. package/.cursor/skills/sf-devops-ci-cd/SKILL.md +322 -0
  64. package/.cursor/skills/sf-docs-lookup/SKILL.md +100 -0
  65. package/.cursor/skills/sf-e2e-testing/SKILL.md +321 -0
  66. package/.cursor/skills/sf-experience-cloud/SKILL.md +248 -0
  67. package/.cursor/skills/sf-flow-development/SKILL.md +376 -0
  68. package/.cursor/skills/sf-governor-limits/SKILL.md +319 -0
  69. package/.cursor/skills/sf-harness-audit/SKILL.md +139 -0
  70. package/.cursor/skills/sf-help/SKILL.md +156 -0
  71. package/.cursor/skills/sf-integration/SKILL.md +479 -0
  72. package/.cursor/skills/sf-lwc-constraints/SKILL.md +128 -0
  73. package/.cursor/skills/sf-lwc-development/SKILL.md +302 -0
  74. package/.cursor/skills/sf-lwc-testing/SKILL.md +387 -0
  75. package/.cursor/skills/sf-metadata-management/SKILL.md +285 -0
  76. package/.cursor/skills/sf-platform-events-cdc/SKILL.md +372 -0
  77. package/.cursor/skills/sf-quickstart/SKILL.md +170 -0
  78. package/.cursor/skills/sf-security/SKILL.md +330 -0
  79. package/.cursor/skills/sf-security-constraints/SKILL.md +125 -0
  80. package/.cursor/skills/sf-soql-constraints/SKILL.md +129 -0
  81. package/.cursor/skills/sf-soql-optimization/SKILL.md +353 -0
  82. package/.cursor/skills/sf-tdd-workflow/SKILL.md +332 -0
  83. package/.cursor/skills/sf-testing-constraints/SKILL.md +198 -0
  84. package/.cursor/skills/sf-trigger-constraints/SKILL.md +88 -0
  85. package/.cursor/skills/sf-trigger-frameworks/SKILL.md +343 -0
  86. package/.cursor/skills/sf-visualforce-development/SKILL.md +259 -0
  87. package/.cursor/skills/strategic-compact/SKILL.md +205 -0
  88. package/.cursor/skills/update-docs/SKILL.md +162 -0
  89. package/.cursor/skills/update-platform-docs/SKILL.md +86 -0
  90. package/.cursor-plugin/plugin.json +26 -0
  91. package/LICENSE +21 -0
  92. package/README.md +522 -0
  93. package/agents/deep-researcher.md +145 -0
  94. package/agents/doc-updater.md +222 -0
  95. package/agents/eval-runner.md +340 -0
  96. package/agents/learning-engine.md +211 -0
  97. package/agents/loop-operator.md +247 -0
  98. package/agents/refactor-cleaner.md +122 -0
  99. package/agents/sf-admin-agent.md +131 -0
  100. package/agents/sf-agentforce-agent.md +132 -0
  101. package/agents/sf-apex-agent.md +124 -0
  102. package/agents/sf-architect.md +435 -0
  103. package/agents/sf-aura-reviewer.md +372 -0
  104. package/agents/sf-bugfix-agent.md +105 -0
  105. package/agents/sf-flow-agent.md +159 -0
  106. package/agents/sf-integration-agent.md +146 -0
  107. package/agents/sf-lwc-agent.md +127 -0
  108. package/agents/sf-review-agent.md +366 -0
  109. package/agents/sf-visualforce-reviewer.md +468 -0
  110. package/assets/logo.svg +18 -0
  111. package/docs/ARCHITECTURE.md +133 -0
  112. package/docs/authoring-guide.md +373 -0
  113. package/docs/hook-development.md +578 -0
  114. package/docs/token-optimization.md +139 -0
  115. package/docs/workflow-examples.md +645 -0
  116. package/examples/agentforce-action/README.md +227 -0
  117. package/examples/apex-trigger-handler/README.md +114 -0
  118. package/examples/devops-pipeline/README.md +325 -0
  119. package/examples/flow-automation/README.md +188 -0
  120. package/examples/integration-pattern/README.md +416 -0
  121. package/examples/lwc-component/README.md +180 -0
  122. package/examples/platform-events/README.md +492 -0
  123. package/examples/scratch-org-setup/README.md +138 -0
  124. package/examples/security-audit/README.md +244 -0
  125. package/examples/visualforce-migration/README.md +314 -0
  126. package/hooks/hooks.json +338 -0
  127. package/hooks/memory-persistence/README.md +73 -0
  128. package/manifests/install-modules.json +217 -0
  129. package/manifests/install-profiles.json +17 -0
  130. package/mcp-configs/mcp-servers.json +19 -0
  131. package/package.json +89 -0
  132. package/schemas/hooks.schema.json +123 -0
  133. package/schemas/install-modules.schema.json +76 -0
  134. package/schemas/install-profiles.schema.json +28 -0
  135. package/schemas/install-state.schema.json +73 -0
  136. package/schemas/package-manager.schema.json +18 -0
  137. package/schemas/plugin.schema.json +112 -0
  138. package/schemas/scc-install-config.schema.json +29 -0
  139. package/schemas/state-store.schema.json +111 -0
  140. package/scripts/cli/install-apply.js +170 -0
  141. package/scripts/cli/uninstall.js +193 -0
  142. package/scripts/hooks/check-console-log.js +101 -0
  143. package/scripts/hooks/check-hook-enabled.js +17 -0
  144. package/scripts/hooks/check-platform-docs-age.js +48 -0
  145. package/scripts/hooks/cost-tracker.js +78 -0
  146. package/scripts/hooks/doc-file-warning.js +63 -0
  147. package/scripts/hooks/evaluate-session.js +98 -0
  148. package/scripts/hooks/governor-check.js +220 -0
  149. package/scripts/hooks/learning-observe.sh +206 -0
  150. package/scripts/hooks/mcp-health-check.js +588 -0
  151. package/scripts/hooks/post-bash-build-complete.js +34 -0
  152. package/scripts/hooks/post-bash-pr-created.js +43 -0
  153. package/scripts/hooks/post-edit-console-warn.js +61 -0
  154. package/scripts/hooks/post-edit-format.js +79 -0
  155. package/scripts/hooks/post-edit-typecheck.js +98 -0
  156. package/scripts/hooks/post-write.js +168 -0
  157. package/scripts/hooks/pre-bash-git-push-reminder.js +35 -0
  158. package/scripts/hooks/pre-bash-tmux-reminder.js +47 -0
  159. package/scripts/hooks/pre-compact.js +51 -0
  160. package/scripts/hooks/pre-tool-use.js +163 -0
  161. package/scripts/hooks/pre-write-doc-warn.js +9 -0
  162. package/scripts/hooks/quality-gate.js +251 -0
  163. package/scripts/hooks/run-with-flags-shell.sh +32 -0
  164. package/scripts/hooks/run-with-flags.js +135 -0
  165. package/scripts/hooks/session-end-marker.js +29 -0
  166. package/scripts/hooks/session-end.js +311 -0
  167. package/scripts/hooks/session-start.js +202 -0
  168. package/scripts/hooks/sfdx-scanner-check.js +142 -0
  169. package/scripts/hooks/sfdx-validate.js +119 -0
  170. package/scripts/hooks/stop-hook.js +170 -0
  171. package/scripts/hooks/suggest-compact.js +67 -0
  172. package/scripts/lib/agent-adapter.js +82 -0
  173. package/scripts/lib/apex-analysis.js +194 -0
  174. package/scripts/lib/hook-flags.js +74 -0
  175. package/scripts/lib/install-config.js +73 -0
  176. package/scripts/lib/install-executor.js +363 -0
  177. package/scripts/lib/install-state.js +121 -0
  178. package/scripts/lib/orchestration-session.js +299 -0
  179. package/scripts/lib/package-manager.js +124 -0
  180. package/scripts/lib/project-detect.js +228 -0
  181. package/scripts/lib/schema-validator.js +190 -0
  182. package/scripts/lib/skill-adapter.js +100 -0
  183. package/scripts/lib/state-store.js +376 -0
  184. package/scripts/lib/tmux-worktree-orchestrator.js +598 -0
  185. package/scripts/lib/utils.js +313 -0
  186. package/scripts/scc.js +164 -0
  187. package/skills/_reference/AGENTFORCE_PATTERNS.md +112 -0
  188. package/skills/_reference/APEX_CURSOR.md +159 -0
  189. package/skills/_reference/API_VERSIONS.md +78 -0
  190. package/skills/_reference/APPROVAL_PROCESSES.md +105 -0
  191. package/skills/_reference/ASYNC_PATTERNS.md +163 -0
  192. package/skills/_reference/AURA_COMPONENTS.md +146 -0
  193. package/skills/_reference/DATA_MIGRATION_PATTERNS.md +151 -0
  194. package/skills/_reference/DATA_MODELING.md +124 -0
  195. package/skills/_reference/DEBUGGING_TOOLS.md +140 -0
  196. package/skills/_reference/DEPLOYMENT_CHECKLIST.md +87 -0
  197. package/skills/_reference/DEPRECATIONS.md +79 -0
  198. package/skills/_reference/DOCKER_CI_PATTERNS.md +138 -0
  199. package/skills/_reference/ENTERPRISE_PATTERNS.md +122 -0
  200. package/skills/_reference/EXPERIENCE_CLOUD.md +143 -0
  201. package/skills/_reference/FLOW_PATTERNS.md +113 -0
  202. package/skills/_reference/GOVERNOR_LIMITS.md +77 -0
  203. package/skills/_reference/INTEGRATION_PATTERNS.md +105 -0
  204. package/skills/_reference/LWC_PATTERNS.md +79 -0
  205. package/skills/_reference/METADATA_TYPES.md +115 -0
  206. package/skills/_reference/NAMING_CONVENTIONS.md +84 -0
  207. package/skills/_reference/PACKAGE_DEVELOPMENT.md +150 -0
  208. package/skills/_reference/PLATFORM_EVENTS.md +121 -0
  209. package/skills/_reference/REPORTING_API.md +143 -0
  210. package/skills/_reference/SCRATCH_ORG_PATTERNS.md +126 -0
  211. package/skills/_reference/SECURITY_PATTERNS.md +127 -0
  212. package/skills/_reference/SHARING_MODEL.md +120 -0
  213. package/skills/_reference/SOQL_PATTERNS.md +119 -0
  214. package/skills/_reference/TESTING_STANDARDS.md +96 -0
  215. package/skills/_reference/TRIGGER_PATTERNS.md +114 -0
  216. package/skills/_reference/VISUALFORCE_PATTERNS.md +121 -0
  217. package/skills/aside/SKILL.md +118 -0
  218. package/skills/checkpoint/SKILL.md +53 -0
  219. package/skills/configure-scc/SKILL.md +163 -0
  220. package/skills/continuous-agent-loop/SKILL.md +264 -0
  221. package/skills/mcp-server-patterns/SKILL.md +146 -0
  222. package/skills/model-route/SKILL.md +84 -0
  223. package/skills/prompt-optimizer/SKILL.md +369 -0
  224. package/skills/refactor-clean/SKILL.md +136 -0
  225. package/skills/resume-session/SKILL.md +114 -0
  226. package/skills/save-session/SKILL.md +186 -0
  227. package/skills/search-first/SKILL.md +144 -0
  228. package/skills/security-scan/SKILL.md +146 -0
  229. package/skills/sessions/SKILL.md +127 -0
  230. package/skills/sf-agentforce-development/SKILL.md +450 -0
  231. package/skills/sf-apex-async-patterns/SKILL.md +326 -0
  232. package/skills/sf-apex-best-practices/SKILL.md +425 -0
  233. package/skills/sf-apex-constraints/SKILL.md +81 -0
  234. package/skills/sf-apex-cursor/SKILL.md +338 -0
  235. package/skills/sf-apex-enterprise-patterns/SKILL.md +348 -0
  236. package/skills/sf-apex-testing/SKILL.md +409 -0
  237. package/skills/sf-api-design/SKILL.md +238 -0
  238. package/skills/sf-approval-processes/SKILL.md +315 -0
  239. package/skills/sf-aura-development/SKILL.md +263 -0
  240. package/skills/sf-build-fix/SKILL.md +121 -0
  241. package/skills/sf-data-modeling/SKILL.md +278 -0
  242. package/skills/sf-debugging/SKILL.md +363 -0
  243. package/skills/sf-deployment/SKILL.md +295 -0
  244. package/skills/sf-deployment-constraints/SKILL.md +155 -0
  245. package/skills/sf-devops-ci-cd/SKILL.md +325 -0
  246. package/skills/sf-docs-lookup/SKILL.md +103 -0
  247. package/skills/sf-e2e-testing/SKILL.md +324 -0
  248. package/skills/sf-experience-cloud/SKILL.md +249 -0
  249. package/skills/sf-flow-development/SKILL.md +377 -0
  250. package/skills/sf-governor-limits/SKILL.md +323 -0
  251. package/skills/sf-harness-audit/SKILL.md +142 -0
  252. package/skills/sf-help/SKILL.md +159 -0
  253. package/skills/sf-integration/SKILL.md +483 -0
  254. package/skills/sf-lwc-constraints/SKILL.md +130 -0
  255. package/skills/sf-lwc-development/SKILL.md +303 -0
  256. package/skills/sf-lwc-testing/SKILL.md +388 -0
  257. package/skills/sf-metadata-management/SKILL.md +288 -0
  258. package/skills/sf-platform-events-cdc/SKILL.md +375 -0
  259. package/skills/sf-quickstart/SKILL.md +173 -0
  260. package/skills/sf-security/SKILL.md +334 -0
  261. package/skills/sf-security-constraints/SKILL.md +127 -0
  262. package/skills/sf-soql-constraints/SKILL.md +131 -0
  263. package/skills/sf-soql-optimization/SKILL.md +354 -0
  264. package/skills/sf-tdd-workflow/SKILL.md +336 -0
  265. package/skills/sf-testing-constraints/SKILL.md +200 -0
  266. package/skills/sf-trigger-constraints/SKILL.md +90 -0
  267. package/skills/sf-trigger-frameworks/SKILL.md +347 -0
  268. package/skills/sf-visualforce-development/SKILL.md +260 -0
  269. package/skills/strategic-compact/SKILL.md +208 -0
  270. package/skills/update-docs/SKILL.md +165 -0
  271. package/skills/update-platform-docs/SKILL.md +90 -0
@@ -0,0 +1,376 @@
1
+ ---
2
+ name: sf-flow-development
3
+ description: >-
4
+ Salesforce Flow development — flow types, patterns, bulkification, error handling, testing, subflows, Flow vs Apex. Use when building or reviewing Flows. Do NOT use for pure Apex or Platform Event architecture.
5
+ ---
6
+
7
+ # Salesforce Flow Development
8
+
9
+ Procedures for building, testing, and maintaining Salesforce Flows. Flow type details, governor limits, bulkification rules, and the Flow vs Apex decision matrix live in the reference file.
10
+
11
+ @../_reference/FLOW_PATTERNS.md
12
+
13
+ ## When to Use
14
+
15
+ - Building or debugging Salesforce Flows (record-triggered, screen, scheduled, autolaunched, orchestration)
16
+ - Deciding between Flow and Apex for automation
17
+ - Configuring fault paths, bulkification, or governor-safe flow patterns
18
+ - Implementing subflows, versioning, or modular flow design
19
+ - Migrating from Process Builder to Record-Triggered Flows
20
+
21
+ ---
22
+
23
+ ## Before Save: Field Updates (Recommended Pattern)
24
+
25
+ ```
26
+ Flow: ACC_SetAccountPriority (Before Save, Account, before insert OR before update)
27
+ Entry Condition: {!$Record.AnnualRevenue} >= 1000000
28
+
29
+ Steps:
30
+ 1. Assignment: {!$Record.Priority__c} = "High"
31
+ 2. Assignment: {!$Record.Tier__c} = "Enterprise"
32
+
33
+ Notes:
34
+ - No Get Records, Update Records, or Create Records elements allowed
35
+ - No DML of any kind
36
+ - Very fast — runs in memory before DB write
37
+ ```
38
+
39
+ ## After Save: Related Record Creation
40
+
41
+ ```
42
+ Flow: OPP_CreateNegotiationTask (After Save, Opportunity, after update)
43
+ Entry Condition: {!$Record.StageName} = "Negotiation"
44
+ AND {!$Record.StageName} <> {!$Record__Prior.StageName}
45
+
46
+ Steps:
47
+ 1. Get Records: User WHERE Id = {!$Record.OwnerId}
48
+ 2. Create Records: Task (
49
+ Subject = "Review negotiation checklist"
50
+ WhatId = {!$Record.Id}
51
+ OwnerId = {!$Record.OwnerId}
52
+ ActivityDate = TODAY() + 3
53
+ Priority = "High"
54
+ )
55
+ ```
56
+
57
+ ---
58
+
59
+ ## Before Save vs After Save Decision
60
+
61
+ ```
62
+ Need to update the SAME record's fields?
63
+ -> Before Save (no DML counted, faster)
64
+ Note: Before Save flows cannot use Get Records or DML elements,
65
+ but CAN access parent fields via cross-object formula references
66
+ (e.g., {!$Record.Account.Name}).
67
+
68
+ Need to create/update OTHER records?
69
+ -> After Save (can do DML on other objects)
70
+
71
+ Need to send emails or call external services?
72
+ -> After Save (outbound actions need committed record)
73
+ ```
74
+
75
+ ---
76
+
77
+ ## Bulkification Patterns
78
+
79
+ ### DML Outside the Loop (Critical)
80
+
81
+ ```
82
+ BAD:
83
+ Loop: For each Contact in {!Contacts}
84
+ |
85
+ +-> Update Records: Contact <- DML inside loop = 1 DML per record
86
+
87
+ GOOD:
88
+ Loop: For each Contact in {!Contacts}
89
+ |
90
+ +-> Assignment: Add to contactsToUpdate collection
91
+
92
+ Update Records: {!contactsToUpdate} <- Single DML for entire collection
93
+ ```
94
+
95
+ ### SOQL Outside the Loop
96
+
97
+ ```
98
+ BAD:
99
+ Loop: For each Opportunity in {!Opportunities}
100
+ |
101
+ +-> Get Records: Account WHERE Id = {!loopVar.AccountId} <- SOQL per record
102
+
103
+ GOOD:
104
+ Get Records: Account WHERE Id IN {!opportunityAccountIds} <- single query
105
+
106
+ Loop: For each Opportunity in {!Opportunities}
107
+ |
108
+ +-> (Use data from pre-fetched collection, no SOQL)
109
+
110
+ Heap warning: If pre-fetch returns 10K+ records, the collection may
111
+ exceed the heap size limit (see @../_reference/GOVERNOR_LIMITS.md). Filter aggressively, or move to Batch Apex.
112
+ ```
113
+
114
+ ---
115
+
116
+ ## Subflows: Modular Design
117
+
118
+ ```
119
+ Parent Flow: SCR_CustomerOnboarding (Screen Flow)
120
+ |
121
+ +-- Subflow: VAL_ValidateAddress (Autolaunched)
122
+ | Input: {!streetAddress}, {!city}, {!state}
123
+ | Output: {!isValidAddress}, {!normalizedAddress}
124
+ |
125
+ +-- Subflow: INT_CreateCRMAccount (Autolaunched)
126
+ | Input: {!accountData}
127
+ | Output: {!newAccountId}
128
+ |
129
+ +-- Subflow: NOT_SendWelcomeEmail (Autolaunched)
130
+ Input: {!accountId}, {!contactEmail}
131
+ ```
132
+
133
+ Variables passed between parent and subflow must be marked as available for input/output in the subflow definition.
134
+
135
+ ---
136
+
137
+ ## Error Handling: Fault Connectors
138
+
139
+ Every element that can fail should have a fault connector.
140
+
141
+ ```
142
+ [Update Records: Update Account]
143
+ |
144
+ +-(SUCCESS)-> [Next Step]
145
+ |
146
+ +-(FAULT)-> [Assignment: errorMessage =
147
+ "Failed: " + {!$Flow.FaultMessage}]
148
+ |
149
+ +-> [Screen: Display Error to User]
150
+ OR
151
+ +-> [Create Records: Error_Log__c]
152
+ OR
153
+ +-> [Custom Notification: Notify Admin]
154
+ ```
155
+
156
+ ---
157
+
158
+ ## Get Records Best Practices
159
+
160
+ ```
161
+ Element: Get Records
162
+ Object: Contact
163
+ Filter: AccountId = {!$Record.Id} AND IsActive__c = true
164
+ Store All Records: No (when you need just one) / Yes (for a collection)
165
+
166
+ Tips:
167
+ - Add filter conditions to reduce records returned
168
+ - Select only the fields you need
169
+ - Use "Only the first record" when you need a single result
170
+ - Filter on indexed fields when possible (Id, OwnerId, ExternalId__c)
171
+ ```
172
+
173
+ ---
174
+
175
+ ## Custom Labels and Custom Metadata in Flows
176
+
177
+ ### Custom Labels
178
+
179
+ ```
180
+ Formula Resource:
181
+ Name: FormattedMessage
182
+ Data Type: Text
183
+ Value: {!$Label.Welcome_Message} & " " & {!ContactRecord.FirstName}
184
+ ```
185
+
186
+ ### Custom Metadata Types
187
+
188
+ ```
189
+ Get Records:
190
+ Object: Service_Config__mdt
191
+ Filter: DeveloperName = "Production"
192
+ Fields: Endpoint_URL__c, Timeout_Ms__c
193
+ ```
194
+
195
+ ---
196
+
197
+ ## Testing Flows
198
+
199
+ ### Apex Test Coverage for Record-Triggered Flows
200
+
201
+ ```apex
202
+ @IsTest
203
+ public class OppNegotiationFlowTest {
204
+
205
+ @TestSetup
206
+ static void setup() {
207
+ Account acc = TestDataFactory.createAccount('Test Account');
208
+ insert acc;
209
+ }
210
+
211
+ @IsTest
212
+ static void testNegotiationTask_stageChanged_createsTask() {
213
+ Account acc = [SELECT Id FROM Account LIMIT 1];
214
+
215
+ Opportunity opp = new Opportunity(
216
+ Name = 'Test Opp',
217
+ AccountId = acc.Id,
218
+ StageName = 'Prospecting',
219
+ CloseDate = Date.today().addDays(30),
220
+ Amount = 50000
221
+ );
222
+ insert opp;
223
+
224
+ Test.startTest();
225
+ opp.StageName = 'Negotiation';
226
+ update opp;
227
+ Test.stopTest();
228
+
229
+ List<Task> tasks = [SELECT Subject, Priority
230
+ FROM Task WHERE WhatId = :opp.Id];
231
+ System.assertEquals(1, tasks.size());
232
+ System.assertEquals('Review negotiation checklist', tasks[0].Subject);
233
+ }
234
+
235
+ @IsTest
236
+ static void testNegotiationTask_bulk_createsTasksForAll() {
237
+ Account acc = [SELECT Id FROM Account LIMIT 1];
238
+
239
+ List<Opportunity> opps = new List<Opportunity>();
240
+ for (Integer i = 0; i < 200; i++) {
241
+ opps.add(new Opportunity(
242
+ Name = 'Bulk Opp ' + i,
243
+ AccountId = acc.Id,
244
+ StageName = 'Prospecting',
245
+ CloseDate = Date.today().addDays(30),
246
+ Amount = 1000 * i
247
+ ));
248
+ }
249
+ insert opps;
250
+
251
+ Test.startTest();
252
+ for (Opportunity opp : opps) { opp.StageName = 'Negotiation'; }
253
+ update opps;
254
+ Test.stopTest();
255
+
256
+ Integer taskCount = [SELECT COUNT() FROM Task WHERE WhatId IN :opps];
257
+ System.assertEquals(200, taskCount);
258
+ }
259
+ }
260
+ ```
261
+
262
+ ---
263
+
264
+ ## New Screen Flow Components (Spring '26)
265
+
266
+ Five native Screen Flow components that eliminate the need for custom LWC in common patterns:
267
+
268
+ | Component | Best For |
269
+ |-----------|----------|
270
+ | **Kanban Board** | Stage/status reassignment wizards, visual prioritization |
271
+ | **Message** | Confirmation prompts, warnings before destructive steps |
272
+ | **File Preview** | Document review steps in approval flows |
273
+ | **Integrated Approval** | Wizard-based approval flows where reps submit and track |
274
+ | **Editable Data Table** | Mass-edit child records within a guided wizard |
275
+
276
+ ---
277
+
278
+ ## Record-Triggered Flows on Files (Spring '26)
279
+
280
+ Record-Triggered Flows now support `ContentVersion` as a triggering object.
281
+
282
+ ```
283
+ Object: ContentVersion
284
+ Trigger: A record is created or updated
285
+ Entry Conditions:
286
+ - {!$Record.FileExtension} = 'pdf'
287
+ - {!$Record.Title} Does NOT Contain 'DRAFT'
288
+
289
+ Use cases:
290
+ - Auto-tag documents based on filename patterns
291
+ - Notify a team when a contract document is uploaded
292
+ - Create audit log when a sensitive file type is uploaded
293
+ ```
294
+
295
+ ---
296
+
297
+ ## Orchestration Flow Design
298
+
299
+ Orchestration Flows manage long-running, multi-step processes spanning hours or days.
300
+
301
+ ```
302
+ Orchestration Flow: Employee_Onboarding
303
+ +-- Stage 1: "System Setup"
304
+ | +-- Background Step: Create user account (Autolaunched Flow)
305
+ | +-- Background Step: Provision email (Autolaunched Flow)
306
+ +-- Stage 2: "HR Review"
307
+ | +-- Interactive Step: Complete onboarding form (Screen Flow -> HR Manager)
308
+ +-- Stage 3: "Equipment & Access"
309
+ | +-- Interactive Step: Order equipment (Screen Flow -> IT Team queue)
310
+ | +-- Background Step: Grant system permissions (Autolaunched Flow)
311
+ +-- Stage 4: "Orientation"
312
+ +-- Interactive Step: Schedule orientation (Screen Flow -> Employee)
313
+ ```
314
+
315
+ ### Key Design Principles
316
+
317
+ - Stages execute sequentially -- Stage 2 waits for all Stage 1 steps
318
+ - Steps within a stage can run in parallel
319
+ - Interactive steps pause the orchestration until the assigned user completes the Screen Flow
320
+ - Background steps run automatically using Autolaunched Flows
321
+ - Define fault paths on background steps to prevent stalled orchestrations
322
+
323
+ ---
324
+
325
+ ## Flow Versioning and Activation
326
+
327
+ ```
328
+ Each Flow has:
329
+ - Multiple versions (v1, v2, v3...)
330
+ - Only ONE active version at a time
331
+ - Inactive versions can be tested without activating
332
+
333
+ Deployment:
334
+ - Deploying creates a new version
335
+ - Set status: Active in Flow metadata to auto-activate:
336
+ ```
337
+
338
+ ```xml
339
+ <status>Active</status>
340
+ ```
341
+
342
+ ```bash
343
+ sf project deploy start \
344
+ --metadata "Flow:OPP_CreateNegotiationTask" \
345
+ --target-org myOrg
346
+ ```
347
+
348
+ ---
349
+
350
+ ## Process Builder Migration
351
+
352
+ ```
353
+ 1. IDENTIFY — List all active Process Builders
354
+ sf data query -q "SELECT Id, MasterLabel, ProcessType FROM Flow
355
+ WHERE ProcessType = 'Workflow' AND Status = 'Active'" --json
356
+
357
+ 2. ANALYZE — Document trigger object, criteria, and actions
358
+
359
+ 3. CREATE — Build equivalent Record-Triggered Flow:
360
+ - Before Save Flow for field updates
361
+ - After Save Flow for create records, email alerts
362
+
363
+ 4. TEST — Deploy to sandbox, test with bulk data (200+ records)
364
+
365
+ 5. DEACTIVATE — Turn off Process Builder, monitor 1-2 weeks
366
+
367
+ 6. CLEANUP — Delete via destructiveChanges.xml
368
+ ```
369
+
370
+ ---
371
+
372
+ ## Related
373
+
374
+ - Agent: `sf-flow-agent` -- for interactive, in-depth guidance
375
+ - Constraints: sf-apex-constraints (for Apex-invoked flows)
376
+ - Reference: @../_reference/FLOW_PATTERNS.md
@@ -0,0 +1,319 @@
1
+ ---
2
+ name: sf-governor-limits
3
+ description: >-
4
+ Use when hitting Salesforce governor limits in Apex — SOQL, DML, heap, CPU optimization, async offloading, bulk processing strategies. Do NOT use for general Apex or LWC patterns.
5
+ ---
6
+
7
+ # Governor Limits — Working Within Limits
8
+
9
+ Salesforce governor limits prevent any single transaction from monopolizing shared infrastructure. Hitting a limit throws `System.LimitException`, which cannot be caught. This skill covers strategies and optimization procedures. See @../_reference/GOVERNOR_LIMITS.md for the complete limits reference table.
10
+
11
+ @../_reference/GOVERNOR_LIMITS.md
12
+
13
+ ## When to Use
14
+
15
+ - A transaction throws `System.LimitException` in production or tests
16
+ - Reviewing Apex code for SOQL/DML-in-loop anti-patterns before deployment
17
+ - Batch or trigger jobs intermittently hitting CPU or heap limits
18
+ - Profiling a large data operation processing 200+ records
19
+ - Optimizing a slow trigger handler or service class for bulk safety
20
+ - Preparing for an ISV security review that checks governor limit compliance
21
+
22
+ ## Checking Limits Programmatically
23
+
24
+ The `Limits` class provides real-time limit consumption. Use it defensively before expensive operations.
25
+
26
+ ```apex
27
+ public class LimitAwareProcessor {
28
+ public void processIfSafe(List<Account> accounts) {
29
+ Integer soqlRemaining = Limits.getLimitQueries() - Limits.getQueries();
30
+ if (soqlRemaining < 5) {
31
+ System.debug(LoggingLevel.WARN,
32
+ 'Low SOQL budget: ' + Limits.getQueries() + '/' +
33
+ Limits.getLimitQueries() + '. Deferring to async.');
34
+ if (Limits.getQueueableJobs() < Limits.getLimitQueueableJobs()
35
+ && !System.isBatch() && !System.isFuture()) {
36
+ System.enqueueJob(new AccountProcessorJob(extractIds(accounts)));
37
+ }
38
+ return;
39
+ }
40
+
41
+ Integer dmlRemaining = Limits.getLimitDmlStatements() - Limits.getDmlStatements();
42
+ if (dmlRemaining < 3) {
43
+ throw new LimitSafetyException(
44
+ 'Insufficient DML budget. ' +
45
+ Limits.getDmlStatements() + '/' + Limits.getLimitDmlStatements() + ' used.'
46
+ );
47
+ }
48
+
49
+ Integer heapUsed = Limits.getHeapSize();
50
+ Integer heapLimit = Limits.getLimitHeapSize();
51
+ if (heapUsed > heapLimit * 0.75) {
52
+ System.debug(LoggingLevel.WARN, 'Heap at 75% — skipping optional enrichment.');
53
+ }
54
+
55
+ processInternal(accounts);
56
+ }
57
+
58
+ public class LimitSafetyException extends Exception {}
59
+ }
60
+ ```
61
+
62
+ ---
63
+
64
+ ## SOQL Limit Strategies
65
+
66
+ ### Query Once, Store in Map
67
+
68
+ The most impactful single optimization in Salesforce development.
69
+
70
+ ```apex
71
+ public void processAccounts(List<Account> accounts) {
72
+ Set<Id> accountIds = new Set<Id>();
73
+ for (Account acc : accounts) accountIds.add(acc.Id);
74
+
75
+ Map<Id, List<Contact>> contactsByAccountId = new Map<Id, List<Contact>>();
76
+ for (Contact con : [SELECT Id, Email, AccountId FROM Contact WHERE AccountId IN :accountIds]) {
77
+ if (!contactsByAccountId.containsKey(con.AccountId)) {
78
+ contactsByAccountId.put(con.AccountId, new List<Contact>());
79
+ }
80
+ contactsByAccountId.get(con.AccountId).add(con);
81
+ }
82
+
83
+ for (Account acc : accounts) {
84
+ List<Contact> contacts = contactsByAccountId.get(acc.Id);
85
+ if (contacts != null) sendEmailsToContacts(contacts);
86
+ }
87
+ }
88
+ ```
89
+
90
+ ### Use Aggregate Queries
91
+
92
+ ```apex
93
+ // 1 query instead of 3
94
+ Map<String, Integer> countsByType = new Map<String, Integer>();
95
+ for (AggregateResult ar : [
96
+ SELECT Type, COUNT(Id) cnt FROM Account WHERE Type != null GROUP BY Type
97
+ ]) {
98
+ countsByType.put((String) ar.get('Type'), (Integer) ar.get('cnt'));
99
+ }
100
+ ```
101
+
102
+ ---
103
+
104
+ ## DML Limit Strategies
105
+
106
+ ### Collect Records, Single DML After Loop
107
+
108
+ ```apex
109
+ public void setDefaultTitle(List<Contact> contacts) {
110
+ List<Contact> toUpdate = new List<Contact>();
111
+ for (Contact con : contacts) {
112
+ if (String.isBlank(con.Title)) {
113
+ toUpdate.add(new Contact(Id = con.Id, Title = 'Business Contact'));
114
+ }
115
+ }
116
+ if (!toUpdate.isEmpty()) {
117
+ update toUpdate; // 1 DML regardless of list size
118
+ }
119
+ }
120
+ ```
121
+
122
+ ### Partial Success DML
123
+
124
+ ```apex
125
+ List<Database.SaveResult> results = Database.insert(accounts, false);
126
+ List<String> errors = new List<String>();
127
+ for (Integer i = 0; i < results.size(); i++) {
128
+ if (!results[i].isSuccess()) {
129
+ for (Database.Error err : results[i].getErrors()) {
130
+ errors.add(accounts[i].Name + ': ' + err.getMessage());
131
+ }
132
+ }
133
+ }
134
+ if (!errors.isEmpty()) ErrorLogger.log(errors);
135
+ ```
136
+
137
+ ### Unit of Work Pattern
138
+
139
+ For complex transactions creating related records across multiple objects, collect all records and commit once to minimize DML statements.
140
+
141
+ ```apex
142
+ SimpleUnitOfWork uow = new SimpleUnitOfWork();
143
+ Account acc = new Account(Name = 'New Customer');
144
+ uow.registerNew(acc);
145
+ Contact primary = new Contact(LastName = 'Primary');
146
+ uow.registerNew(primary, Contact.AccountId, acc);
147
+ uow.commitWork(); // Minimal DML: inserts parent first, resolves IDs, then children
148
+ ```
149
+
150
+ ---
151
+
152
+ ## Heap Limit Strategies
153
+
154
+ ### Select Minimal Fields
155
+
156
+ ```apex
157
+ // Use aggregate for count — do not load full sObjects just to count
158
+ Integer count = [SELECT COUNT() FROM Account];
159
+
160
+ // Select only fields the calling code needs
161
+ List<Account> accounts = [SELECT Id, Name FROM Account WHERE Id IN :accountIds];
162
+ ```
163
+
164
+ ### Use Maps Instead of Parallel Lists
165
+
166
+ ```apex
167
+ // Single data structure instead of two synchronized lists
168
+ Map<Id, String> accountNameById = new Map<Id, String>();
169
+ for (Account acc : accounts) {
170
+ accountNameById.put(acc.Id, acc.Name);
171
+ }
172
+ ```
173
+
174
+ ### Nullify Large References When Done
175
+
176
+ ```apex
177
+ List<SObject> largeDataSet = loadLargeDataSet();
178
+ List<String> results = extractResults(largeDataSet);
179
+ largeDataSet = null; // Eligible for garbage collection
180
+ saveResults(results);
181
+ ```
182
+
183
+ ---
184
+
185
+ ## CPU Time Strategies
186
+
187
+ ### Use Maps Instead of Nested Loops
188
+
189
+ ```apex
190
+ // O(n) using Set lookup instead of O(n^2) nested loop
191
+ Set<Id> validAccountIds = new Set<Id>(new Map<Id, Account>(validAccounts).keySet());
192
+ List<Contact> orphaned = new List<Contact>();
193
+ for (Contact con : contacts) {
194
+ if (!validAccountIds.contains(con.AccountId)) {
195
+ orphaned.add(con);
196
+ }
197
+ }
198
+ ```
199
+
200
+ ### Use String.join Instead of Concatenation in Loops
201
+
202
+ ```apex
203
+ List<String> names = new List<String>();
204
+ for (Account acc : accounts) names.add(acc.Name);
205
+ String output = String.join(names, ', '); // One allocation
206
+ ```
207
+
208
+ ### Offload to Async When CPU Is High
209
+
210
+ ```apex
211
+ if (Limits.getCpuTime() > 8000) { // 8 of 10 seconds used
212
+ System.enqueueJob(new AccountProcessorJob(
213
+ new List<Id>(new Map<Id, Account>(accounts).keySet())
214
+ ));
215
+ return;
216
+ }
217
+ performExpensiveProcessing(accounts);
218
+ ```
219
+
220
+ ---
221
+
222
+ ## Callout Limit Strategies
223
+
224
+ ### @future(callout=true) from Triggers
225
+
226
+ Triggers cannot make synchronous callouts. Use @future to defer.
227
+
228
+ ```apex
229
+ public class AccountERPSyncService {
230
+ @future(callout=true)
231
+ public static void syncToERP(List<Id> accountIds) {
232
+ List<Account> accounts = [
233
+ SELECT Id, Name, External_Id__c FROM Account WHERE Id IN :accountIds
234
+ ];
235
+ for (Account acc : accounts) ERPClient.syncAccount(acc);
236
+ }
237
+ }
238
+ ```
239
+
240
+ ### Queueable for Callout Chains
241
+
242
+ ```apex
243
+ public class SequentialCalloutJob implements Queueable, Database.AllowsCallouts {
244
+ private final List<Id> accountIds;
245
+ private final Integer currentIndex;
246
+
247
+ public SequentialCalloutJob(List<Id> accountIds) { this(accountIds, 0); }
248
+ private SequentialCalloutJob(List<Id> accountIds, Integer startIndex) {
249
+ this.accountIds = accountIds;
250
+ this.currentIndex = startIndex;
251
+ }
252
+
253
+ public void execute(QueueableContext ctx) {
254
+ final Integer CALLOUTS_PER_JOB = 90;
255
+ Integer end = Math.min(currentIndex + CALLOUTS_PER_JOB, accountIds.size());
256
+ for (Integer i = currentIndex; i < end; i++) {
257
+ ERPClient.syncAccount(accountIds[i]);
258
+ }
259
+ if (end < accountIds.size()) {
260
+ System.enqueueJob(new SequentialCalloutJob(accountIds, end));
261
+ }
262
+ }
263
+ }
264
+ ```
265
+
266
+ ---
267
+
268
+ ## Async Decision Tree
269
+
270
+ ```
271
+ User action that can complete in < 5s? → Synchronous
272
+ Processing > 200 records? → Batch Apex
273
+ Callouts from a trigger? → @future(callout=true) or Queueable
274
+ CPU exceeding 8000ms regularly? → Profile first; then Queueable
275
+ Recurring scheduled operation? → Schedulable wrapping Batch/Queueable
276
+ ```
277
+
278
+ ---
279
+
280
+ ## Testing at Limits
281
+
282
+ ```apex
283
+ @isTest
284
+ static void testTrigger_200RecordBulkInsert_noLimitException() {
285
+ List<Account> accounts = new List<Account>();
286
+ for (Integer i = 0; i < 200; i++) {
287
+ accounts.add(new Account(Name = 'Bulk Test ' + i, Type = 'Customer'));
288
+ }
289
+
290
+ Test.startTest(); // Resets governor limit counters
291
+ insert accounts;
292
+ Test.stopTest();
293
+
294
+ System.assertEquals(200,
295
+ [SELECT COUNT() FROM Account WHERE Type = 'Customer'],
296
+ 'All 200 accounts should be inserted');
297
+ }
298
+
299
+ @isTest
300
+ static void testService_queriesStayWithinLimits() {
301
+ List<Account> accounts = TestDataFactory.createAccounts(50);
302
+
303
+ Test.startTest();
304
+ Integer queriesBefore = Limits.getQueries();
305
+ AccountService.processAll(new Map<Id, Account>(accounts).keySet());
306
+ Integer queriesUsed = Limits.getQueries() - queriesBefore;
307
+ Test.stopTest();
308
+
309
+ System.assert(queriesUsed <= 5,
310
+ 'processAll() should use at most 5 SOQL queries. Actual: ' + queriesUsed);
311
+ }
312
+ ```
313
+
314
+ ---
315
+
316
+ ## Related
317
+
318
+ - **Agent**: `sf-apex-agent` — For interactive, in-depth guidance
319
+ - **Constraints**: `sf-apex-constraints` — Hard rules for Apex governor compliance