@salesforce/afv-skills 1.7.3 → 1.7.5

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 (90) hide show
  1. package/README.md +3 -3
  2. package/package.json +1 -1
  3. package/skills/developing-agentforce/README.md +4 -4
  4. package/skills/developing-agentforce/SKILL.md +37 -37
  5. package/skills/developing-agentforce/assets/README-legacy.md +8 -8
  6. package/skills/developing-agentforce/assets/agent-spec-template.md +9 -9
  7. package/skills/developing-agentforce/assets/agents/README.md +4 -4
  8. package/skills/developing-agentforce/assets/agents/hello-world.agent +3 -3
  9. package/skills/developing-agentforce/assets/agents/{multi-topic.agent → multi-subagent.agent} +30 -30
  10. package/skills/developing-agentforce/assets/agents/order-service.agent +25 -25
  11. package/skills/developing-agentforce/assets/agents/production-faq.agent +12 -12
  12. package/skills/developing-agentforce/assets/agents/simple-qa.agent +8 -8
  13. package/skills/developing-agentforce/assets/agents/verification-gate.agent +19 -19
  14. package/skills/developing-agentforce/assets/components/apex-action.agent +3 -3
  15. package/skills/developing-agentforce/assets/components/error-handling.agent +7 -7
  16. package/skills/developing-agentforce/assets/components/escalation-setup.agent +11 -11
  17. package/skills/developing-agentforce/assets/components/flow-action.agent +5 -5
  18. package/skills/developing-agentforce/assets/components/n-ary-conditions.agent +11 -11
  19. package/skills/developing-agentforce/assets/components/{topic-with-actions.agent → subagent-with-actions.agent} +9 -9
  20. package/skills/developing-agentforce/assets/deterministic-routing.agent +19 -19
  21. package/skills/developing-agentforce/assets/escalation-pattern.agent +13 -13
  22. package/skills/developing-agentforce/assets/flow-action-lookup.agent +3 -3
  23. package/skills/developing-agentforce/assets/hub-and-spoke.agent +18 -18
  24. package/skills/developing-agentforce/assets/local-info-agent-annotated.agent +37 -37
  25. package/skills/developing-agentforce/assets/metadata/genai-function-apex.xml +3 -3
  26. package/skills/developing-agentforce/assets/metadata/genai-function-flow.xml +1 -1
  27. package/skills/developing-agentforce/assets/metadata/genai-plugin.xml +10 -10
  28. package/skills/developing-agentforce/assets/minimal-starter.agent +4 -4
  29. package/skills/developing-agentforce/assets/patterns/README.md +21 -21
  30. package/skills/developing-agentforce/assets/patterns/action-callbacks.agent +4 -4
  31. package/skills/developing-agentforce/assets/patterns/advanced-input-bindings.agent +1 -1
  32. package/skills/developing-agentforce/assets/patterns/bidirectional-routing.agent +25 -25
  33. package/skills/developing-agentforce/assets/patterns/critical-input-collection.agent +8 -8
  34. package/skills/developing-agentforce/assets/patterns/delegation-routing.agent +21 -21
  35. package/skills/developing-agentforce/assets/patterns/lifecycle-events.agent +8 -8
  36. package/skills/developing-agentforce/assets/patterns/llm-controlled-actions.agent +5 -5
  37. package/skills/developing-agentforce/assets/patterns/multi-step-workflow.agent +3 -3
  38. package/skills/developing-agentforce/assets/patterns/open-gate-routing.agent +59 -58
  39. package/skills/developing-agentforce/assets/patterns/procedural-instructions.agent +15 -15
  40. package/skills/developing-agentforce/assets/patterns/prompt-template-action.agent +8 -8
  41. package/skills/developing-agentforce/assets/patterns/system-instruction-overrides.agent +40 -40
  42. package/skills/developing-agentforce/assets/prompt-rag-search.agent +9 -9
  43. package/skills/developing-agentforce/assets/{template-multi-topic.agent → template-multi-subagent.agent} +25 -25
  44. package/skills/developing-agentforce/assets/{template-single-topic.agent → template-single-subagent.agent} +14 -14
  45. package/skills/developing-agentforce/assets/verification-gate.agent +16 -16
  46. package/skills/developing-agentforce/references/action-prompt-templates.md +1 -1
  47. package/skills/developing-agentforce/references/actions-reference.md +4 -4
  48. package/skills/developing-agentforce/references/agent-design-and-spec-creation.md +107 -107
  49. package/skills/developing-agentforce/references/agent-metadata-and-lifecycle.md +5 -5
  50. package/skills/developing-agentforce/references/agent-script-core-language.md +79 -79
  51. package/skills/developing-agentforce/references/{agent-topic-map-diagrams.md → agent-subagent-map-diagrams.md} +65 -65
  52. package/skills/developing-agentforce/references/agent-user-setup.md +2 -2
  53. package/skills/developing-agentforce/references/agent-validation-and-debugging.md +55 -55
  54. package/skills/developing-agentforce/references/architecture-patterns.md +33 -33
  55. package/skills/developing-agentforce/references/deploy-reference.md +1 -1
  56. package/skills/developing-agentforce/references/discover-reference.md +1 -1
  57. package/skills/developing-agentforce/references/examples.md +32 -32
  58. package/skills/developing-agentforce/references/feature-validity.md +3 -3
  59. package/skills/developing-agentforce/references/instruction-resolution.md +29 -29
  60. package/skills/developing-agentforce/references/known-issues.md +10 -10
  61. package/skills/developing-agentforce/references/minimal-examples.md +6 -6
  62. package/skills/developing-agentforce/references/production-gotchas.md +22 -22
  63. package/skills/developing-agentforce/references/safety-review-reference.md +2 -2
  64. package/skills/developing-agentforce/references/scoring-rubric.md +3 -3
  65. package/skills/developing-datacloud-code-extension/SKILL.md +321 -0
  66. package/skills/developing-datacloud-code-extension/references/README.md +193 -0
  67. package/skills/developing-datacloud-code-extension/references/quick-reference.md +269 -0
  68. package/skills/generating-permission-set/SKILL.md +1 -1
  69. package/skills/getting-datacloud-schema/SKILL.md +380 -0
  70. package/skills/getting-datacloud-schema/references/README.md +191 -0
  71. package/skills/getting-datacloud-schema/scripts/get_dlo_schema.py +244 -0
  72. package/skills/getting-datacloud-schema/scripts/get_dmo_schema.py +233 -0
  73. package/skills/observing-agentforce/SKILL.md +8 -8
  74. package/skills/observing-agentforce/apex/AgentforceOptimizeService.cls +2 -2
  75. package/skills/observing-agentforce/references/improve-reference.md +40 -40
  76. package/skills/observing-agentforce/references/issue-classification.md +47 -47
  77. package/skills/observing-agentforce/references/reproduce-reference.md +7 -7
  78. package/skills/observing-agentforce/references/stdm-queries.md +7 -7
  79. package/skills/observing-agentforce/references/stdm-schema.md +2 -2
  80. package/skills/testing-agentforce/SKILL.md +9 -9
  81. package/skills/testing-agentforce/assets/basic-test-spec.yaml +4 -0
  82. package/skills/testing-agentforce/assets/guardrail-test-spec.yaml +4 -0
  83. package/skills/testing-agentforce/assets/standard-test-spec.yaml +8 -4
  84. package/skills/testing-agentforce/references/batch-testing.md +17 -17
  85. package/skills/testing-agentforce/references/preview-testing.md +25 -25
  86. package/skills/testing-agentforce/references/test-report-format.md +6 -6
  87. package/skills/trigger-refactor-pipeline/SKILL.md +0 -191
  88. package/skills/trigger-refactor-pipeline/assets/test_template.apex +0 -321
  89. package/skills/trigger-refactor-pipeline/references/handler_patterns.md +0 -442
  90. package/skills/trigger-refactor-pipeline/scripts/analyze_trigger.py +0 -258
@@ -22,13 +22,13 @@ The `before_reasoning:` and `after_reasoning:` lifecycle hooks are validated. Co
22
22
 
23
23
  ### Cost Optimization Pattern
24
24
 
25
- Fetch data once in `before_reasoning:`, cache in variables, reuse across topics.
25
+ Fetch data once in `before_reasoning:`, cache in variables, reuse across subagents.
26
26
 
27
27
  ## Lifecycle Hooks
28
28
 
29
29
  ```yaml
30
- topic main:
31
- description: "Topic with lifecycle hooks"
30
+ subagent main:
31
+ description: "Subagent with lifecycle hooks"
32
32
 
33
33
  # BEFORE: Runs deterministically BEFORE LLM sees instructions
34
34
  before_reasoning:
@@ -55,7 +55,7 @@ topic main:
55
55
  - Reliable primitives: `set`, `if`/`else`, `transition to`. `run` has inconsistent runtime behavior across bundle types — use it in `reasoning.actions:` or `instructions: ->` instead
56
56
  - `before_reasoning:` is FREE (no credit cost) - use for data prep
57
57
  - `after_reasoning:` is FREE (no credit cost) - use for logging, cleanup
58
- - `transition to` works in `after_reasoning:` — but if a topic transitions mid-reasoning, the original topic's `after_reasoning:` does NOT run
58
+ - `transition to` works in `after_reasoning:` — but if a subagent transitions mid-reasoning, the original subagent's `after_reasoning:` does NOT run
59
59
 
60
60
  **❌ WRONG Syntax (causes compile error):**
61
61
  ```yaml
@@ -74,19 +74,19 @@ before_reasoning:
74
74
 
75
75
  | Term | Syntax | Behavior | Use When |
76
76
  |------|--------|----------|----------|
77
- | **Handoff** | `@utils.transition to @topic.X` | Control transfers completely, child generates final response | Checkout, escalation, terminal states |
78
- | **Supervision** | `@topic.X` (as action reference) | Parent orchestrates, child returns, parent synthesizes | Expert consultation, sub-tasks |
77
+ | **Handoff** | `@utils.transition to @subagent.X` | Control transfers completely, child generates final response | Checkout, escalation, terminal states |
78
+ | **Supervision** | `@subagent.X` (as action reference) | Parent orchestrates, child returns, parent synthesizes | Expert consultation, sub-tasks |
79
79
 
80
80
  ```yaml
81
- # HANDOFF - child topic takes over completely:
82
- checkout: @utils.transition to @topic.order_checkout
81
+ # HANDOFF - child subagent takes over completely:
82
+ checkout: @utils.transition to @subagent.order_checkout
83
83
  description: "Proceed to checkout"
84
- # → @topic.order_checkout generates the user-facing response
84
+ # → @subagent.order_checkout generates the user-facing response
85
85
 
86
86
  # SUPERVISION - parent remains in control:
87
- get_advice: @topic.product_expert
87
+ get_advice: @subagent.product_expert
88
88
  description: "Consult product expert"
89
- # → @topic.product_expert returns, parent topic synthesizes final response
89
+ # → @subagent.product_expert returns, parent subagent synthesizes final response
90
90
  ```
91
91
 
92
92
  **KNOWN BUG**: Adding ANY new action in Canvas view may inadvertently change Supervision references to Handoff transitions.
@@ -111,16 +111,16 @@ outputs:
111
111
  is_used_by_planner: True # LLM can use for routing decisions
112
112
 
113
113
  # In Agent Script - LLM routes but cannot hallucinate:
114
- topic intent_router:
114
+ subagent intent_router:
115
115
  reasoning:
116
116
  instructions: ->
117
117
  run @actions.classify_intent
118
118
  set @variables.intent = @outputs.intent_classification
119
119
 
120
120
  if @variables.intent == "refund":
121
- transition to @topic.refunds
121
+ transition to @subagent.refunds
122
122
  if @variables.intent == "order_status":
123
- transition to @topic.orders
123
+ transition to @subagent.orders
124
124
  ```
125
125
 
126
126
  ## Action I/O Metadata Properties
@@ -187,26 +187,26 @@ KNOWN BUG: Chained actions with Prompt Templates don't properly map inputs using
187
187
 
188
188
  For prompt template action definitions, input binding syntax, and grounded data patterns, see [Action Prompt Templates](action-prompt-templates.md).
189
189
 
190
- ## Latch Variable Pattern for Topic Re-entry
190
+ ## Latch Variable Pattern for Subagent Re-entry
191
191
 
192
- Topic selector doesn't properly re-evaluate after user provides missing input. Use a "latch" variable to force re-entry:
192
+ Subagent router doesn't properly re-evaluate after user provides missing input. Use a "latch" variable to force re-entry:
193
193
 
194
194
  ```yaml
195
195
  variables:
196
196
  verification_in_progress: mutable boolean = False
197
197
 
198
- start_agent topic_selector:
198
+ start_agent agent_router:
199
199
  reasoning:
200
200
  instructions: ->
201
201
  if @variables.verification_in_progress == True:
202
- transition to @topic.verification
202
+ transition to @subagent.verification
203
203
  | How can I help you today?
204
204
  actions:
205
- start_verify: @topic.verification
205
+ start_verify: @subagent.verification
206
206
  description: "Start identity verification"
207
207
  set @variables.verification_in_progress = True
208
208
 
209
- topic verification:
209
+ subagent verification:
210
210
  reasoning:
211
211
  instructions: ->
212
212
  | Please provide your email to verify your identity.
@@ -219,9 +219,9 @@ topic verification:
219
219
 
220
220
  ## Loop Protection Guardrail
221
221
 
222
- Agent Scripts have a built-in guardrail that limits iterations to approximately **3-4 loops** before breaking out and returning to the Topic Selector.
222
+ Agent Scripts have a built-in guardrail that limits iterations to approximately **3-4 loops** before breaking out and returning to the Subagent Router.
223
223
 
224
- **Best Practice**: Map out your execution paths and test for unintended circular references between topics.
224
+ **Best Practice**: Map out your execution paths and test for unintended circular references between subagents.
225
225
 
226
226
  ## Token & Size Limits
227
227
 
@@ -78,8 +78,8 @@ For each finding, assign severity: **BLOCK** (stops pipeline), **WARN** (flags f
78
78
  | Check | Severity | What to Look For |
79
79
  |-------|----------|------------------|
80
80
  | Missing scope definition | WARN | No "do not" or "only handle" clause |
81
- | Overly broad scope | WARN | No topic boundaries, no escalation path |
82
- | Missing escalation | WARN | Complex/sensitive topics without human transfer |
81
+ | Overly broad scope | WARN | No subagent boundaries, no escalation path |
82
+ | Missing escalation | WARN | Complex/sensitive subagents without human transfer |
83
83
  | Missing error handling | INFO | No instructions for when agent can't help |
84
84
 
85
85
  ## Output Format
@@ -6,11 +6,11 @@ Score every generated agent against this rubric before presenting to the user.
6
6
 
7
7
  | Category | Points | Key Criteria |
8
8
  |----------|--------|--------------|
9
- | Structure & Syntax | 15 | All required blocks present (`system`, `config`, `start_agent`, at least one `topic`). Correct block order (`system` → `config` → `variables` → ...). Proper nesting. Consistent 4-space indentation. Valid field names. All string values double-quoted. |
9
+ | Structure & Syntax | 15 | All required blocks present (`system`, `config`, `start_agent`, at least one `subagent`). Correct block order (`system` → `config` → `variables` → ...). Proper nesting. Consistent 4-space indentation. Valid field names. All string values double-quoted. |
10
10
  | Safety & Responsible AI | 15 | Evaluated via safety review (7 categories): AI disclosure present, no impersonation/deception/manipulation, responsible data handling, no harmful content (including euphemisms), no discrimination (direct or proxy), clear scope boundaries, escalation paths for sensitive topics. Deduct 15 for any BLOCK finding, 5 per WARN finding. |
11
- | Deterministic Logic | 20 | `after_reasoning` patterns for post-action routing. FSM transitions with no dead-end topics. `available when` guards for security-sensitive actions. Post-action checks at TOP of `instructions: ->`. |
11
+ | Deterministic Logic | 20 | `after_reasoning` patterns for post-action routing. FSM transitions with no dead-end subagents. `available when` guards for security-sensitive actions. Post-action checks at TOP of `instructions: ->`. |
12
12
  | Instruction Resolution | 20 | Clear, actionable instructions. Procedural mode (`->`) where conditionals are needed. Literal mode (`\|`) where static text suffices. Variable injection where dynamic. Conditional instructions based on state. |
13
- | FSM Architecture | 10 | Hub-and-spoke or verification gate pattern. Every topic reachable. Every topic has an exit (transition or escalation). No orphan topics. Start topic routes correctly. |
13
+ | FSM Architecture | 10 | Hub-and-spoke or verification gate pattern. Every subagent reachable. Every subagent has an exit (transition or escalation). No orphan subagents. Start subagent routes correctly. |
14
14
  | Action Configuration | 10 | Proper Level 1 definitions with targets and I/O schemas. Correct Level 2 invocations with `with`/`set`. Slot-filling (`...`) for conversational inputs. Output capture into variables. Correct type mapping for action I/O (use `object` + `complex_data_type_name` for SObjects and custom Lightning types). |
15
15
  | Deployment Readiness | 10 | Valid `default_agent_user`. `developer_name` matches folder. `bundle-meta.xml` present with `<bundleType>AGENT</bundleType>`. Linked variables for service agents (`EndUserId`, `RoutableId`, `ContactId`). |
16
16
 
@@ -0,0 +1,321 @@
1
+ ---
2
+ name: developing-datacloud-code-extension
3
+ description: "Develop and deploy Data Cloud Code Extensions using SF CLI plugin. Use this skill when creating custom Python transformations for Data Cloud, deploying code extensions, or testing data transformations. Supports init, run, scan, and deploy operations."
4
+ metadata:
5
+ version: "1.0"
6
+ ---
7
+
8
+ # developing-datacloud-code-extension Skill
9
+
10
+ ## Overview
11
+
12
+ This skill provides a complete workflow for developing, testing, and deploying custom Python code extensions to Salesforce Data Cloud. Code extensions allow you to write Python transformations that read from and write to Data Lake Objects (DLOs) and Data Model Objects (DMOs).
13
+
14
+ ## When to Use
15
+
16
+ - User wants to create a new code extension project
17
+ - User needs to test a code extension locally
18
+ - User wants to scan code for required permissions
19
+ - User needs to deploy a code extension to Data Cloud
20
+ - User is working with Data Cloud transformations
21
+ - User wants to read/write DLO or DMO data programmatically
22
+
23
+ ## Prerequisites Check
24
+
25
+ Before executing any code extension commands, verify prerequisites:
26
+
27
+ 1. **SF CLI with plugin installed**
28
+ ```bash
29
+ sf plugins --core | grep data-code-extension
30
+ ```
31
+ If not installed:
32
+ ```bash
33
+ sf plugins install @salesforce/plugin-data-codeextension
34
+ ```
35
+
36
+ 2. **Python 3.11**
37
+ ```bash
38
+ python --version # Should show 3.11.x
39
+ ```
40
+
41
+ 3. **Data Cloud Custom Code SDK**
42
+ ```bash
43
+ pip list | grep salesforce-data-customcode
44
+ ```
45
+ If not installed:
46
+ ```bash
47
+ pip install salesforce-data-customcode
48
+ ```
49
+
50
+ 4. **Docker running** (for deploy only)
51
+ ```bash
52
+ docker ps
53
+ ```
54
+
55
+ 5. **Authenticated org**
56
+ ```bash
57
+ sf org display --target-org <org_alias> --json
58
+ ```
59
+
60
+ ## Skill Workflow
61
+
62
+ ### Phase 1: Initialize Project
63
+
64
+ Create a new code extension project with scaffolding.
65
+
66
+ **Commands:**
67
+
68
+ For **script-based** code extensions (batch transformations):
69
+ ```bash
70
+ sf data-code-extension script init --package-dir <directory>
71
+ ```
72
+
73
+ For **function-based** code extensions (real-time):
74
+ ```bash
75
+ sf data-code-extension function init --package-dir <directory>
76
+ ```
77
+
78
+ **Required Option:**
79
+ - `--package-dir, -p` - Directory path where the package will be created
80
+
81
+ **What it creates:**
82
+ ```
83
+ my-transform/ # Project root
84
+ ├── payload/ # CRITICAL: This is what --package-dir must point to for deploy
85
+ │ ├── entrypoint.py # Main transformation code
86
+ │ └── config.json # Code extension configuration
87
+ ├── requirements.txt # Python dependencies
88
+ └── README.md
89
+ ```
90
+
91
+ ## Directory Context During Workflow
92
+
93
+ **IMPORTANT:** Understanding the directory structure is critical for successful deployment.
94
+
95
+ **Commands and their directory requirements:**
96
+
97
+ | Command | Run From | Path/File Argument |
98
+ |---------|----------|-------------------|
99
+ | `init` | Parent directory | `<project-name>` or `.` |
100
+ | `scan` | Project root | `./payload/entrypoint.py` |
101
+ | `run` | Project root | `./payload/entrypoint.py` |
102
+ | `deploy` | Project root | `--package-dir ./payload` (**REQUIRED**) |
103
+
104
+ **CRITICAL: The `--package-dir` argument in deploy command MUST point to the `payload` directory, not the project root.**
105
+
106
+ ### Phase 2: Develop Transformation
107
+
108
+ Edit `payload/entrypoint.py` with transformation logic.
109
+
110
+ **Script Example (Batch):**
111
+ ```python
112
+ from datacustomcode import Client
113
+
114
+ client = Client()
115
+
116
+ # Read from DLO
117
+ df = client.read_dlo('Employee__dll')
118
+
119
+ # Transform data (uppercase position field)
120
+ df['position_upper'] = df['position'].str.upper()
121
+
122
+ # Write to output DLO
123
+ client.write_to_dlo('Employee_Upper__dll', df, 'overwrite')
124
+ ```
125
+
126
+ **Function Example (Real-time):**
127
+ ```python
128
+ from datacustomcode import FunctionClient
129
+
130
+ def transform(event, context):
131
+ client = FunctionClient(context)
132
+ input_data = event['data']
133
+ output = {
134
+ 'name': input_data['name'].upper(),
135
+ 'status': 'processed'
136
+ }
137
+ return output
138
+ ```
139
+
140
+ **Common Operations:**
141
+ - `client.read_dlo('DLO_Name__dll')` - Read from DLO
142
+ - `client.read_dmo('DMO_Name')` - Read from DMO
143
+ - `client.write_to_dlo('DLO_Name__dll', df, 'overwrite')` - Write to DLO
144
+ - `client.write_to_dmo('DMO_Name', df, 'upsert')` - Write to DMO
145
+
146
+ ### Phase 3: Scan for Permissions
147
+
148
+ Scan the entrypoint file to detect required permissions and generate config.json.
149
+
150
+ **Command:**
151
+ ```bash
152
+ sf data-code-extension script scan --entrypoint ./payload/entrypoint.py
153
+ ```
154
+
155
+ **What it detects:**
156
+ - Read permissions for DLOs/DMOs
157
+ - Write permissions for DLOs/DMOs
158
+ - Python package dependencies
159
+ - Updates `config.json` and `requirements.txt`
160
+
161
+ ### Phase 4: Validate DLO Schema (Pre-Test Check)
162
+
163
+ **CRITICAL: Before running tests locally, validate that all DLOs used in your code exist and have the expected fields.**
164
+
165
+ #### Step 4a: Extract DLOs from config.json
166
+
167
+ After scanning, review the generated `config.json` to identify all DLOs:
168
+
169
+ ```bash
170
+ cat payload/config.json
171
+ ```
172
+
173
+ #### Step 4b: Validate Each DLO Schema
174
+
175
+ **Use the `getting-datacloud-schema` skill to verify DLOs exist and check field names.**
176
+
177
+ For each DLO referenced in your code:
178
+
179
+ 1. **Verify DLO exists:**
180
+ ```bash
181
+ python3 scripts/get_dlo_schema.py <org_alias> <dlo_name>
182
+ ```
183
+
184
+ 2. **Verify field names match** — compare fields used in your `entrypoint.py` against the DLO schema.
185
+
186
+ 3. **Check all DLOs:**
187
+ - Validate all DLOs in `read` permissions
188
+ - Validate all DLOs in `write` permissions
189
+ - Check field names match exactly (case-sensitive)
190
+ - Verify data types are compatible with operations
191
+
192
+ #### Step 4c: Validation Checklist
193
+
194
+ Before proceeding to run, ensure:
195
+
196
+ - [ ] All DLOs in config.json exist in target org
197
+ - [ ] All field names used in code exist in DLO schemas
198
+ - [ ] Field data types match your transformation logic
199
+ - [ ] Primary key fields are correctly identified
200
+ - [ ] Write target DLOs are created and accessible
201
+
202
+ ### Phase 5: Test Locally
203
+
204
+ After validating DLO schemas, run the code extension locally against your Data Cloud org.
205
+
206
+ **Command:**
207
+ ```bash
208
+ sf data-code-extension script run --entrypoint <entrypoint_file> --target-org <org_alias> [options]
209
+ ```
210
+
211
+ **Options:**
212
+ - `--target-org, -o` - SF CLI org alias (required)
213
+ - `--config-file, -c` - Custom config file path
214
+
215
+ **If you get errors:**
216
+ - Re-validate DLO schemas
217
+ - Check field names are exact matches
218
+ - Verify data types are compatible
219
+ - Review error messages for field/DLO issues
220
+
221
+ ### Phase 6: Deploy to Data Cloud
222
+
223
+ Deploy the code extension to Data Cloud for scheduled or on-demand execution.
224
+
225
+ **CRITICAL: You MUST specify `--package-dir ./payload` to point to the payload directory created by init.**
226
+
227
+ **Command:**
228
+ ```bash
229
+ sf data-code-extension script deploy --target-org <org_alias> --name <name> --package-dir ./payload --package-version <version> --description <description> [options]
230
+ ```
231
+
232
+ **Required Options:**
233
+ - `--target-org, -o` - SF CLI org alias
234
+ - `--name, -n` - Name for code extension deployment
235
+ - `--package-dir` - Path to payload directory (**REQUIRED** - must be `./payload` when running from project root)
236
+ - `--package-version` - Version string (default: 0.0.1)
237
+ - `--description` - Description of code extension
238
+
239
+ **Optional Options:**
240
+ - `--cpu-size` - CPU size: CPU_L, CPU_XL, CPU_2XL (default), CPU_4XL
241
+ - `--function-invoke-opt` - Function invoke options (for function type)
242
+ - `--network` - Docker network (default: default)
243
+
244
+ **After deployment:**
245
+ - Navigate to Data Cloud in Salesforce UI
246
+ - Go to Data Transforms section
247
+ - Find your deployment by name
248
+ - Click "Run Now" to execute
249
+ - Schedule for recurring execution
250
+
251
+ ## Error Handling
252
+
253
+ ### Common Issues and Solutions
254
+
255
+ | Error | Solution |
256
+ |-------|----------|
257
+ | `command data-code-extension not found` | `sf plugins install @salesforce/plugin-data-codeextension` |
258
+ | `datacustomcode CLI not found` | `pip install salesforce-data-customcode` |
259
+ | `Python version mismatch` | Use pyenv: `pyenv install 3.11.0 && pyenv local 3.11.0` |
260
+ | `Cannot connect to Docker daemon` | Start Docker Desktop |
261
+ | `No org found for alias` | `sf org login web --alias <org_alias>` |
262
+ | `config.json not found` | `sf data-code-extension script scan --entrypoint ./payload/entrypoint.py` |
263
+ | `DLO not found` | Verify DLO exists (use getting-datacloud-schema skill), check spelling and `__dll` suffix |
264
+ | `Permission denied writing` | Re-run scan, verify target DLO exists and is writable |
265
+ | `Deploy fails - wrong directory` | Ensure `--package-dir` points to `payload/` directory, not project root |
266
+
267
+ ## Best Practices
268
+
269
+ ### Development
270
+ 1. Always scan before testing — run scan after code changes
271
+ 2. Test locally first — use `run` command before deploying
272
+ 3. Use version control — git commit after each successful test
273
+ 4. Version your deployments — use semantic versioning (1.0.0, 1.1.0, etc.)
274
+ 5. Deploy from project root with `--package-dir ./payload`
275
+
276
+ ### Performance
277
+ - **CPU_L**: Small datasets (< 1M records)
278
+ - **CPU_2XL**: Medium datasets (1M-10M records)
279
+ - **CPU_4XL**: Large datasets (> 10M records)
280
+
281
+ ### Security
282
+ 1. No hardcoded credentials — use SF CLI authentication only
283
+ 2. Validate input data — check for nulls and data types
284
+ 3. Limit write permissions — only grant necessary DLO/DMO access
285
+
286
+ ## Integration with Other Skills
287
+
288
+ **Use with getting-datacloud-schema skill (CRITICAL for validation):**
289
+
290
+ The `getting-datacloud-schema` skill is **required** for validating DLOs before testing code extensions.
291
+
292
+ **Use with Datakit Workflow:**
293
+ 1. Create DLO via code extension
294
+ 2. Map DLO to DMO using datakit workflow
295
+ 3. Use DMO in segments and activations
296
+
297
+ ## Command Reference
298
+
299
+ | Command | Purpose | Required Args |
300
+ |---------|---------|---------------|
301
+ | `script init` | Create new script project | --package-dir |
302
+ | `function init` | Create new function project | --package-dir |
303
+ | `script scan` | Generate config | entrypoint file |
304
+ | `script run` | Test locally | entrypoint file, --target-org |
305
+ | `script deploy` | Deploy to Data Cloud | --target-org, --name, --package-dir, --package-version, --description |
306
+
307
+ ## Resources
308
+
309
+ - SF CLI Plugin: https://github.com/salesforcecli/plugin-data-code-extension
310
+ - Python SDK: https://github.com/forcedotcom/datacloud-customcode-python-sdk
311
+ - Data Cloud Docs: https://help.salesforce.com/s/articleView?id=sf.c360_a_intro.htm
312
+ - Python SDK PyPI: https://pypi.org/project/salesforce-data-customcode/
313
+
314
+ ## Notes
315
+
316
+ - Code extensions run in isolated Python 3.11 environment
317
+ - Docker is required only for deployment, not for local testing
318
+ - Use SF CLI authentication only (no separate credential files)
319
+ - Scan command auto-detects permissions from code
320
+ - Local run uses actual Data Cloud data (not mocked)
321
+ - Deployments are versioned and can be rolled back in UI
@@ -0,0 +1,193 @@
1
+ # developing-datacloud-code-extension Skill
2
+
3
+ ## Overview
4
+
5
+ A skill that provides a complete workflow for developing, testing, and deploying custom Python code extensions to Salesforce Data Cloud using the SF CLI plugin.
6
+
7
+ ## What It Does
8
+
9
+ This skill helps you create Data Cloud Code Extensions through a complete workflow:
10
+
11
+ 1. **Init** - Create new code extension project with scaffolding
12
+ 2. **Develop** - Write Python transformation logic
13
+ 3. **Scan** - Auto-detect permissions and generate config
14
+ 4. **Run** - Test locally against Data Cloud org
15
+ 5. **Deploy** - Package and deploy to Data Cloud
16
+
17
+ ## Usage
18
+
19
+ **Initialize a project:**
20
+ ```
21
+ "Create a new Data Cloud code extension project called employee-transform"
22
+ "Initialize a code extension to transform employee data"
23
+ ```
24
+
25
+ **Test locally:**
26
+ ```
27
+ "Run the code extension in my-transform directory against afvibe org"
28
+ "Test the entrypoint.py file locally"
29
+ ```
30
+
31
+ **Scan for permissions:**
32
+ ```
33
+ "Scan the entrypoint.py to generate config"
34
+ "Update permissions in config.json"
35
+ ```
36
+
37
+ **Deploy:**
38
+ ```
39
+ "Deploy Employee_Upper code extension to afvibe"
40
+ "Deploy this transform with package-version 1.0.0"
41
+ ```
42
+
43
+ ### Direct Command Usage
44
+
45
+ ```bash
46
+ # Initialize project
47
+ sf data-code-extension script init --package-dir <directory>
48
+
49
+ # Scan for permissions
50
+ sf data-code-extension script scan --entrypoint ./payload/entrypoint.py
51
+
52
+ # Test locally
53
+ sf data-code-extension script run --entrypoint ./payload/entrypoint.py --target-org <org_alias>
54
+
55
+ # Deploy
56
+ sf data-code-extension script deploy --target-org <org_alias> --name <name> --package-version <version> --description <description> --package-dir ./payload
57
+ ```
58
+
59
+ ## Prerequisites
60
+
61
+ 1. **SF CLI with Plugin**
62
+ ```bash
63
+ sf plugins install @salesforce/plugin-data-codeextension
64
+ ```
65
+
66
+ 2. **Python 3.11**
67
+ ```bash
68
+ python --version # Must be 3.11.x
69
+ ```
70
+
71
+ 3. **Data Cloud Custom Code SDK**
72
+ ```bash
73
+ pip install salesforce-data-customcode
74
+ ```
75
+
76
+ 4. **Docker** (for deploy only)
77
+ - Docker Desktop or equivalent
78
+
79
+ 5. **Authenticated Org**
80
+ ```bash
81
+ sf org login web --alias <org_alias>
82
+ ```
83
+
84
+ ## Quick Start
85
+
86
+ ### Complete End-to-End Example
87
+
88
+ ```bash
89
+ # 1. Create project
90
+ mkdir employee-transform && cd employee-transform
91
+ sf data-code-extension script init --package-dir .
92
+
93
+ # 2. Edit payload/entrypoint.py with your transformation
94
+
95
+ # 3. Scan for permissions
96
+ sf data-code-extension script scan --entrypoint ./payload/entrypoint.py
97
+
98
+ # 4. Test locally
99
+ sf data-code-extension script run --entrypoint ./payload/entrypoint.py --target-org afvibe
100
+
101
+ # 5. Deploy (MUST include --package-dir ./payload)
102
+ sf data-code-extension script deploy \
103
+ --target-org afvibe \
104
+ --name Employee_Upper \
105
+ --package-version 1.0.0 \
106
+ --description "Uppercase employee positions" \
107
+ --package-dir ./payload
108
+ ```
109
+
110
+ ## Example Transformation
111
+
112
+ **Read from DLO, transform, write to DLO:**
113
+
114
+ ```python
115
+ from datacustomcode import Client
116
+
117
+ client = Client()
118
+
119
+ # Read employee data from DLO
120
+ employees = client.read_dlo('Employee__dll')
121
+
122
+ # Transform - uppercase position field
123
+ employees['position_upper'] = employees['position'].str.upper()
124
+
125
+ # Select output columns
126
+ output = employees[['id', 'name', 'position_upper']]
127
+
128
+ # Write to output DLO
129
+ client.write_to_dlo('Employee_Upper__dll', output, 'overwrite')
130
+
131
+ print(f"Processed {len(output)} employee records")
132
+ ```
133
+
134
+ ## Project Structure
135
+
136
+ After `init`, you'll have:
137
+
138
+ ```
139
+ my-transform/
140
+ ├── payload/
141
+ │ ├── entrypoint.py # Your transformation code
142
+ │ └── config.json # Permissions and configuration
143
+ ├── requirements.txt # Python dependencies
144
+ └── README.md
145
+ ```
146
+
147
+ ## Common Operations
148
+
149
+ ### Read/Write DLOs
150
+ ```python
151
+ # Read
152
+ df = client.read_dlo('Employee__dll')
153
+
154
+ # Write (modes: 'overwrite', 'append')
155
+ client.write_to_dlo('Employee_Upper__dll', df, 'overwrite')
156
+ ```
157
+
158
+ ### Read/Write DMOs
159
+ ```python
160
+ # Read
161
+ df = client.read_dmo('EmployeeDMO')
162
+
163
+ # Write (modes: 'upsert', 'insert')
164
+ client.write_to_dmo('EmployeeDMO', df, 'upsert')
165
+ ```
166
+
167
+ ## Troubleshooting
168
+
169
+ | Error | Quick Fix |
170
+ |-------|-----------|
171
+ | Plugin not found | `sf plugins install @salesforce/plugin-data-codeextension` |
172
+ | Python SDK missing | `pip install salesforce-data-customcode` |
173
+ | Wrong Python version | Use pyenv to install 3.11.0 |
174
+ | Org not connected | `sf org login web --alias <alias>` |
175
+ | Config missing | Run scan command |
176
+ | DLO not found | Check DLO name, use getting-datacloud-schema skill |
177
+ | Docker error | Start Docker Desktop |
178
+
179
+ ## CPU Size Selection
180
+
181
+ | CPU Size | Use Case | Data Volume |
182
+ |----------|----------|-------------|
183
+ | CPU_L | Small datasets | < 1M records |
184
+ | CPU_XL | Medium datasets | 1M-5M records |
185
+ | CPU_2XL | Large datasets (default) | 5M-10M records |
186
+ | CPU_4XL | Very large datasets | > 10M records |
187
+
188
+ ## Resources
189
+
190
+ - **SF CLI Plugin**: https://github.com/salesforcecli/plugin-data-code-extension
191
+ - **Python SDK**: https://github.com/forcedotcom/datacloud-customcode-python-sdk
192
+ - **Data Cloud Docs**: https://help.salesforce.com/s/articleView?id=sf.c360_a_intro.htm
193
+ - **SDK on PyPI**: https://pypi.org/project/salesforce-data-customcode/