@salesforce/afv-skills 1.31.0 → 1.32.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.
- package/package.json +1 -1
- package/skills/agentforce-bot-upgrade/SKILL.md +217 -0
- package/skills/agentforce-bot-upgrade/references/extraction-blueprint.md +242 -0
- package/skills/agentforce-bot-upgrade/references/generate-agent-spec.md +128 -0
- package/skills/agentforce-bot-upgrade/references/handoff-output-format.md +208 -0
- package/skills/agentforce-bot-upgrade/references/input-contract.md +101 -0
- package/skills/agentforce-bot-upgrade/references/mapping-rules.md +113 -0
- package/skills/agentforce-bot-upgrade/references/planner-workflow-reference.md +78 -0
- package/skills/agentforce-bot-upgrade/references/post-conversion-enhancements-reference.md +67 -0
- package/skills/agentforce-bot-upgrade/references/quality-checklist.md +33 -0
- package/skills/agentforce-bot-upgrade/references/sf-cli-bot-reference.md +116 -0
- package/skills/dx-devops-work-item-manage/SKILL.md +270 -0
- package/skills/dx-devops-work-item-manage/examples/common-workflows.md +479 -0
- package/skills/dx-devops-work-item-manage/references/cli-commands.md +476 -0
- package/skills/dx-org-manage/SKILL.md +8 -5
- package/skills/dx-org-trial-expiration-check/SKILL.md +239 -0
- package/skills/dx-org-trial-expiration-check/scripts/check_expiration.sh +588 -0
- package/skills/experience-ui-bundle-app-coordinate/SKILL.md +12 -9
- package/skills/experience-ui-bundle-custom-app-generate/SKILL.md +29 -5
- package/skills/experience-ui-bundle-custom-app-generate/references/configure-metadata-custom-application.md +1 -1
- package/skills/experience-ui-bundle-custom-app-generate/scripts/resolve-uibundle-path.sh +30 -0
- package/skills/experience-ui-bundle-features-generate/SKILL.md +86 -11
- package/skills/experience-ui-bundle-features-generate/references/conflict-resolution-schema.json +20 -0
- package/skills/experience-ui-bundle-features-generate/scripts/verify-react-bundle.sh +14 -0
- package/skills/experience-ui-bundle-frontend-generate/SKILL.md +6 -1
- package/skills/experience-ui-bundle-frontend-generate/references/component.md +34 -1
- package/skills/experience-ui-bundle-frontend-generate/references/page.md +1 -1
- package/skills/experience-ui-bundle-project-generate/SKILL.md +111 -0
- package/skills/experience-ui-bundle-project-generate/scripts/flatten-project.mjs +33 -0
- package/skills/platform-custom-lightning-type-generate/SKILL.md +9 -14
- package/skills/platform-custom-lightning-type-generate/references/widget-rendition.md +27 -111
- package/skills/platform-lightning-type-widget-coordinate/SKILL.md +214 -0
- package/skills/platform-lightning-type-widget-coordinate/examples/existing-lightning-type-with-widget-prompt.md +80 -0
- package/skills/platform-lightning-type-widget-coordinate/examples/new-lightning-type-with-widget-prompt.md +75 -0
- package/skills/platform-lightning-type-widget-coordinate/references/build-plan-format.md +67 -0
- package/skills/platform-lightning-type-widget-coordinate/references/lightning-type-discovery.md +124 -0
- package/skills/platform-lightning-type-widget-coordinate/references/validation-gates.md +130 -0
- package/skills/platform-sharing-owd-configure/SKILL.md +142 -0
- package/skills/platform-sharing-owd-configure/examples/get_owd_output.md +38 -0
- package/skills/platform-sharing-owd-configure/examples/update_owd_output.md +44 -0
- package/skills/platform-sharing-owd-configure/references/access_levels.md +49 -0
- package/skills/platform-sharing-owd-configure/references/metadata_api_approach.md +69 -0
- package/skills/platform-sharing-rules-generate/SKILL.md +89 -19
- package/skills/platform-sharing-rules-generate/examples/test-cases.md +381 -0
- package/skills/platform-widget-generate/SKILL.md +241 -0
- package/skills/platform-widget-generate/examples/conditional.json +73 -0
- package/skills/platform-widget-generate/examples/list-with-foreach.json +66 -0
- package/skills/platform-widget-generate/examples/single-object.json +64 -0
- package/skills/platform-widget-generate/references/schema-from-lightning-type.md +76 -0
- package/skills/platform-widget-generate/references/widget-bundle-layout.md +116 -0
- package/skills/platform-widget-generate/references/widget-meta-directives.md +130 -0
- package/skills/sales-agentforce-pipeline-management-configure/SKILL.md +268 -0
- package/skills/sales-agentforce-pipeline-management-configure/assets/field-completion-template.genAiPromptTemplate-meta.xml +141 -0
- package/skills/sales-agentforce-pipeline-management-configure/assets/pipeline_management_flow.flow-meta.xml +548 -0
- package/skills/sales-agentforce-pipeline-management-configure/assets/sales_management_agent.agent +2938 -0
- package/skills/sales-agentforce-pipeline-management-configure/assets/sales_management_agent.bundle-meta.xml +4 -0
- package/skills/sales-agentforce-pipeline-management-configure/assets/sfdx-project.json +12 -0
- package/skills/sales-agentforce-pipeline-management-configure/assets/stage-descriptions/bant.txt +11 -0
- package/skills/sales-agentforce-pipeline-management-configure/assets/stage-descriptions/meddic.txt +11 -0
- package/skills/sales-agentforce-pipeline-management-configure/assets/stage-descriptions/spiced.txt +11 -0
- package/skills/sales-agentforce-pipeline-management-configure/examples/custom-prompt-instructions.md +317 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/admin-communication.md +355 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/agent-creation.md +383 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/auth-and-cli.md +146 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/automation-matrix.md +23 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/autonomous-updates.md +215 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/canonical-agent-path.md +75 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/data-sources.md +155 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/field-completion-prompt-template.md +120 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/field-completion-prompts.md +149 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/flags.md +13 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/flow-clone-from-template.md +447 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/metadata-inventory.md +330 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/opportunity-stages.md +246 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/repair-diagnostics.md +265 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/setup-order.md +263 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/soap-api-enablement.md +528 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/CHANGES.md +180 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/README.md +56 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/add-field-suggestion.sh +679 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/create-agent.sh +302 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/create-flow.sh +250 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/define-agent-access.sh +430 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/deploy-settings.sh +77 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/enable-deal-agent.sh +241 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/enable-prerequisites.sh +538 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/flow-debug-and-verify.sh +385 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/retrieve-settings.sh +131 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/setup-all.sh +2791 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/shared/agent-bundle-publish.sh +189 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/shared/agent-detection.sh +239 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/shared/flow-builder.sh +238 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/shared/psg.sh +48 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/shared/soap.sh +140 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/shared/stage-descriptions.sh +448 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/shared/test-opp.sh +166 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/verify-all.sh +636 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/verify-prompt-generation.sh +346 -0
|
@@ -3,6 +3,16 @@ name: experience-ui-bundle-custom-app-generate
|
|
|
3
3
|
description: "MUST activate when the project contains a uiBundles/*/src/ directory and the task involves creating or configuring a Custom Application for hosting a UI bundle in Lightning Experience. Use this skill when creating a CustomApplication metadata record to surface the UI bundle in the App Launcher. Activate when files matching applications/*.app-meta.xml exist and need modification, or when the user wants to expose their app via the Lightning App Launcher without a Digital Experience Site. Do NOT use platform-custom-application-generate for this — UI bundle apps do not use tabs, action overrides, or flexipages."
|
|
4
4
|
metadata:
|
|
5
5
|
version: "1.0"
|
|
6
|
+
minApiVersion: "51.0"
|
|
7
|
+
relatedSkills:
|
|
8
|
+
- "platform-custom-application-generate"
|
|
9
|
+
cliTools:
|
|
10
|
+
- tool: ["sf"]
|
|
11
|
+
semver: ">=2.0.0"
|
|
12
|
+
mcpTools:
|
|
13
|
+
salesforce-api-context:
|
|
14
|
+
tools: ["get_metadata_type_fields"]
|
|
15
|
+
semver: ">=1.0.0"
|
|
6
16
|
---
|
|
7
17
|
|
|
8
18
|
# Custom Application for React UI Bundles
|
|
@@ -28,9 +38,9 @@ Determine values for all properties before constructing anything. Use the resolu
|
|
|
28
38
|
### Step 2: Query API Context (Version-Aware Field Discovery)
|
|
29
39
|
Call `salesforce-api-context` MCP tools to discover which fields exist for the target org's API version. This ensures the generated metadata is compatible with the user's Salesforce version.
|
|
30
40
|
|
|
31
|
-
**Required calls:**
|
|
32
|
-
1.
|
|
33
|
-
2.
|
|
41
|
+
**Required calls — use the `metadataType` parameter exactly as shown. Do not substitute a `detail` parameter or any other shape; `metadataType` is the only parameter this tool accepts:**
|
|
42
|
+
1. `get_metadata_type_fields({ "metadataType": "CustomApplication" })` — check whether the `uiBundle` field exists in the response's field list
|
|
43
|
+
2. `get_metadata_type_fields({ "metadataType": "UIBundle" })` — check whether the `target` field exists in the response's field list
|
|
34
44
|
|
|
35
45
|
**Field resolution based on API response:**
|
|
36
46
|
|
|
@@ -63,7 +73,20 @@ Use the default template in the doc below. Values in `{braces}` are resolved pro
|
|
|
63
73
|
- If Step 2 determined the older field names apply, substitute `<uiBundle>` with `<webApplication>` in the generated output.
|
|
64
74
|
|
|
65
75
|
### Step 5: Update UI Bundle Meta XML
|
|
66
|
-
|
|
76
|
+
This step edits an **existing** file — it never creates a new one. `UIBundle` is a bundle-style metadata type: its meta XML normally lives inside its own folder at `uiBundles/{appName}/{appName}.uibundle-meta.xml`, alongside the bundle's other source files (e.g. `index.html`, `src/`). Some older or hand-authored projects may instead have it at the flat path `uiBundles/{appName}.uibundle-meta.xml` (no subfolder).
|
|
77
|
+
|
|
78
|
+
Run `scripts/resolve-uibundle-path.sh "{appName}"` — it prints the path of the existing meta XML (preferring the nested layout, falling back to the flat layout). Edit that exact file in place; do not create a second file at the other path or migrate it to a different layout as part of this skill.
|
|
79
|
+
|
|
80
|
+
If Step 2 confirmed the `target` field exists on `UIBundle`, add `<target>CustomApplication</target>` inside the existing `<UIBundle>` element of that file, preserving every other existing element and value untouched (skip this step entirely if the field doesn't exist in the org's API version — do not create the file or add `<target>` in that case).
|
|
81
|
+
|
|
82
|
+
**Do NOT:**
|
|
83
|
+
- Create a new `.uibundle-meta.xml` file
|
|
84
|
+
- Create a second `.uibundle-meta.xml` file at a different path when one already exists (nested or flat) — edit the existing one in place, wherever it is
|
|
85
|
+
- Leave the original `uiBundles/{appName}/{appName}.uibundle-meta.xml` (or `uiBundles/{appName}.uibundle-meta.xml`, if that's the existing layout) unmodified while adding `<target>` somewhere else
|
|
86
|
+
|
|
87
|
+
The only files this skill produces or modifies are `applications/{appName}.app-meta.xml` (new) and the existing `{appName}.uibundle-meta.xml` (edited in place, only if `<target>` applies). Any other UI-bundle-related file appearing in the output is a bug.
|
|
88
|
+
|
|
89
|
+
Example of the fully updated file (at `uiBundles/{appName}/{appName}.uibundle-meta.xml`, or the flat path if that's the existing layout) — this illustrates the end state of the existing file, not a new file to create:
|
|
67
90
|
|
|
68
91
|
```xml
|
|
69
92
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
@@ -86,7 +109,8 @@ Before deploying, confirm:
|
|
|
86
109
|
- [ ] API context was queried to determine available fields (Step 2)
|
|
87
110
|
- [ ] `applications/{appName}.app-meta.xml` exists with correct content
|
|
88
111
|
- [ ] The bundle reference field matches the org's API version (`<uiBundle>` or `<webApplication>`)
|
|
89
|
-
- [ ] If `target` field is supported:
|
|
112
|
+
- [ ] If `target` field is supported: the **existing** `{appName}.uibundle-meta.xml` (nested at `uiBundles/{appName}/`, or flat at `uiBundles/`, whichever already existed) has `<target>CustomApplication</target>`
|
|
113
|
+
- [ ] No extra `.uibundle-meta.xml` file was created — exactly one `{appName}.uibundle-meta.xml` exists, at whichever path it already lived at
|
|
90
114
|
- [ ] Deployment validates successfully:
|
|
91
115
|
```bash
|
|
92
116
|
sf project deploy validate --metadata CustomApplication UIBundle --target-org ${usernameOrAlias}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
This configuration file creates a **net-new, default** CustomApplication metadata record for a Lightning Experience app that hosts a React UI bundle. It is not intended to edit or modify an existing CustomApplication record. Use this template only when provisioning a brand-new Custom Application for a UI bundle.
|
|
5
5
|
|
|
6
6
|
## File Location
|
|
7
|
-
```
|
|
7
|
+
```xml
|
|
8
8
|
<sourceDir>/applications/{appName}.app-meta.xml
|
|
9
9
|
```
|
|
10
10
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Resolve the existing path of a UIBundle's meta XML file.
|
|
3
|
+
#
|
|
4
|
+
# UIBundle metadata may live at either the nested bundle-style path
|
|
5
|
+
# (uiBundles/{appName}/{appName}.uibundle-meta.xml) or, in older/hand-authored
|
|
6
|
+
# projects, the flat path (uiBundles/{appName}.uibundle-meta.xml). This script
|
|
7
|
+
# performs the deterministic file-existence check and prints whichever path
|
|
8
|
+
# already exists, preferring the nested layout.
|
|
9
|
+
#
|
|
10
|
+
# Usage: scripts/resolve-uibundle-path.sh <appName>
|
|
11
|
+
|
|
12
|
+
set -euo pipefail
|
|
13
|
+
|
|
14
|
+
APP="${1:-}"
|
|
15
|
+
if [ -z "$APP" ]; then
|
|
16
|
+
echo "ERROR: appName argument is required" >&2
|
|
17
|
+
exit 1
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
NESTED="uiBundles/${APP}/${APP}.uibundle-meta.xml"
|
|
21
|
+
FLAT="uiBundles/${APP}.uibundle-meta.xml"
|
|
22
|
+
|
|
23
|
+
if [ -f "$NESTED" ]; then
|
|
24
|
+
echo "$NESTED"
|
|
25
|
+
elif [ -f "$FLAT" ]; then
|
|
26
|
+
echo "$FLAT"
|
|
27
|
+
else
|
|
28
|
+
echo "ERROR: no .uibundle-meta.xml found for $APP" >&2
|
|
29
|
+
exit 1
|
|
30
|
+
fi
|
|
@@ -1,18 +1,37 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: experience-ui-bundle-features-generate
|
|
3
|
-
description: "MUST activate when the project contains a uiBundles/*/src/ directory and the user wants to add
|
|
3
|
+
description: "MUST activate when the project contains a uiBundles/*/src/ directory and the user wants to add a pre-built feature — such as authentication (login, logout, protected routes, session management) or search (global search across pages and content) — instead of building it from scratch. Always run list first to see the current feature catalog, since it can include more than authentication and search. Always use this skill for installing pre-built features rather than hand-building them. DO NOT TRIGGER for Agentforce conversational client or file-upload features — use experience-ui-bundle-agentforce-client-generate and experience-ui-bundle-file-upload-generate respectively."
|
|
4
4
|
metadata:
|
|
5
|
-
version: "1.
|
|
5
|
+
version: "1.1"
|
|
6
|
+
relatedSkills: ["experience-ui-bundle-agentforce-client-generate", "experience-ui-bundle-file-upload-generate"]
|
|
7
|
+
cliTools:
|
|
8
|
+
- tool: ["npx"]
|
|
9
|
+
semver: ">=7.0.0"
|
|
10
|
+
- tool: ["npm"]
|
|
11
|
+
semver: ">=7.0.0"
|
|
12
|
+
accessCheck:
|
|
13
|
+
- type: "license"
|
|
14
|
+
value: "Experience Cloud (Customer Community / Customer Community Plus)"
|
|
15
|
+
- type: "orgPref"
|
|
16
|
+
value: "Sites"
|
|
6
17
|
---
|
|
7
18
|
|
|
8
19
|
# UI Bundle Features
|
|
9
20
|
|
|
10
21
|
## Installing Pre-built Features
|
|
11
22
|
|
|
12
|
-
Always check for an existing feature before building something from scratch. The features CLI installs pre-built, tested packages into Salesforce UI bundles — from foundational UI libraries (shadcn/ui) to full-stack capabilities
|
|
23
|
+
Always check for an existing feature before building something from scratch. The features CLI installs pre-built, tested packages into Salesforce UI bundles — from foundational UI libraries (shadcn/ui) to full-stack capabilities. Authentication and search are the most commonly used features today; run `list --verbose` for the full current catalog, since it can grow over time.
|
|
24
|
+
|
|
25
|
+
> **Ownership note:** Agentforce AI conversation clients and file-upload are owned by separate skills (`experience-ui-bundle-agentforce-client-generate`, `experience-ui-bundle-file-upload-generate`). If the catalog also lists an Agentforce or file-upload entry, do not install it from both places — confirm with the user which delivery path they want, and never install the same capability twice in one bundle.
|
|
26
|
+
|
|
27
|
+
> **Package name:** `@salesforce/ui-bundle-features` is the canonical package name. Some older templates/samples still reference the deprecated `@salesforce/ui-bundle-features-experimental` name — never use the `-experimental` suffix. If a command fails to resolve, confirm the published version with `npm view @salesforce/ui-bundle-features version` before assuming the package name is wrong.
|
|
13
28
|
|
|
14
29
|
### Workflow
|
|
15
30
|
|
|
31
|
+
0. **Confirm this is a React UI bundle** — this CLI copies into `src/features/` and expects `npm run build` to work. Non-React bundles are not supported and will fail late in the install.
|
|
32
|
+
|
|
33
|
+
Run `scripts/verify-react-bundle.sh`. If it exits non-zero, stop — the bundle is not React-based and this skill cannot proceed.
|
|
34
|
+
|
|
16
35
|
1. **Search project code first** — check `src/` for existing implementations before installing anything. Scope searches to `src/` to avoid matching `node_modules/` or `dist/`.
|
|
17
36
|
|
|
18
37
|
2. **Search available features** — use `npx @salesforce/ui-bundle-features list` with `--search <query>` to filter by keyword. Use `--verbose` for full descriptions.
|
|
@@ -24,24 +43,80 @@ Always check for an existing feature before building something from scratch. The
|
|
|
24
43
|
- `--yes` for non-interactive mode (skips conflicts)
|
|
25
44
|
- `--on-conflict error` to detect conflicts, then `--conflict-resolution <file>` to resolve them
|
|
26
45
|
|
|
46
|
+
Install features **before** doing custom frontend/layout work in this bundle — features may rewrite `appLayout.tsx`/`routes.tsx`, and installing after hand-built layout changes risks collisions.
|
|
47
|
+
|
|
27
48
|
If no matching feature is found, ask the user before building a custom implementation — a relevant feature may exist under a different name.
|
|
28
49
|
|
|
29
50
|
### Conflict Handling
|
|
30
51
|
|
|
31
|
-
In non-interactive environments, use the two-pass approach:
|
|
52
|
+
In non-interactive environments, use the two-pass approach:
|
|
32
53
|
|
|
33
|
-
|
|
54
|
+
1. Run install with `--on-conflict error` to detect conflicts without applying them.
|
|
55
|
+
2. Before writing the resolution file, read `references/conflict-resolution-schema.json` for the allowed keys and enum values.
|
|
56
|
+
3. Write a resolution file at `<ui-bundle-dir>/conflict-resolution.json` (path is relative to the UI bundle directory being installed into, not the repo root). Key it by the exact paths the CLI printed as conflicts in pass 1, verbatim:
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"src/appLayout.tsx": "overwrite",
|
|
60
|
+
"src/routes.tsx": "skip"
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
Any conflicting path *not* listed in this file defaults to `skip` — the CLI will not overwrite a file you didn't explicitly mark `overwrite`.
|
|
64
|
+
4. Re-run install with `--conflict-resolution <path-to-that-file>`.
|
|
34
65
|
|
|
35
|
-
|
|
66
|
+
### Post-install: Integrating Example Files
|
|
36
67
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
68
|
+
Features may include example files under an `__examples__/` directory (plural) showing integration patterns. These are often full, working pages with concrete names (e.g. `AccountSearch.tsx`), not bare placeholder templates. For each:
|
|
69
|
+
|
|
70
|
+
1. Read the example file to understand the pattern — treat it as a working reference implementation, not necessarily a stub.
|
|
71
|
+
2. Read the target file (shown in `describe` output).
|
|
72
|
+
3. Apply the pattern from the example into the target.
|
|
73
|
+
4. **CRITICAL — verify before deleting:**
|
|
74
|
+
```bash
|
|
75
|
+
# Verify the build passes with the integrated pattern
|
|
76
|
+
npm run build || {
|
|
77
|
+
echo "ERROR: Build failed after integration - do NOT delete __examples__/"
|
|
78
|
+
exit 1
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
# Verify the pattern from the example is actually present in the target
|
|
82
|
+
# (adjust grep pattern to match a key symbol/import/component from the example)
|
|
83
|
+
# Example: for SearchInput pattern integrated into AccountSearch.tsx
|
|
84
|
+
grep -q "SearchInput\|useSearch" src/pages/*.tsx src/components/*.tsx 2>/dev/null || {
|
|
85
|
+
echo "ERROR: Pattern from example not found in target files - integration incomplete"
|
|
86
|
+
echo "Do NOT delete __examples__/ until the pattern is confirmed present"
|
|
87
|
+
exit 1
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
# Only delete after both checks pass
|
|
91
|
+
rm -rf __examples__/
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
If either check fails, **do NOT delete `__examples__/`** — the integration is incomplete. Fix the integration first, then re-run the verification.
|
|
41
95
|
|
|
42
96
|
### Hint Placeholders
|
|
43
97
|
|
|
44
|
-
Some copy paths use `<descriptive-name>` placeholders (e.g., `<desired-page-with-search-input>`) that the CLI does not resolve. After installation, rename or relocate these files to the intended target, or integrate their patterns into an existing file.
|
|
98
|
+
Some copy paths use `<descriptive-name>` placeholders (e.g., `<desired-page-with-search-input>`) that the CLI does not resolve. After installation, rename or relocate these files to the intended target, or integrate their patterns into an existing file. This is separate from the `__examples__/` convention above — a single copy path can use either mechanism.
|
|
99
|
+
|
|
100
|
+
### Auth Feature: Org-Side Prerequisites
|
|
101
|
+
|
|
102
|
+
Installing the authentication feature only copies files — it does not configure the org. Before telling the user auth is done, flag that these org-side steps still need to happen (outside this skill's scope, but required for the feature to actually work):
|
|
103
|
+
|
|
104
|
+
- Digital Experiences (Experience Cloud) must be enabled, with Customer Community / Customer Community Plus licenses assigned to the relevant users, and Salesforce Sites enabled.
|
|
105
|
+
- The community and guest profiles need explicit Apex class access granted for the auth utility, login/registration, and password-reset classes — the CLI does not grant this automatically.
|
|
106
|
+
- Guest-profile sharing rules / org-wide defaults for any objects the auth flow touches.
|
|
107
|
+
- **Known limitation:** logout has a documented CSRF-handling gap (tracked as W-21253864) — call this out to the user rather than presenting logout as fully solved.
|
|
108
|
+
|
|
109
|
+
### CRITICAL: Resolve `<sfdxRoot>` After Every Install
|
|
110
|
+
|
|
111
|
+
The CLI may copy files under a literal `<sfdxRoot>` folder — an unresolved placeholder for this project's Salesforce DX metadata root (from `sfdx-project.json`'s `packageDirectories[].path`, e.g. `force-app/main/default`). Files left there are undeployable.
|
|
112
|
+
|
|
113
|
+
**After every install:**
|
|
114
|
+
```bash
|
|
115
|
+
find uiBundles/<AppName> -type d -regex '.*/<[^/]+>$'
|
|
116
|
+
```
|
|
117
|
+
If found, move each file to `<metadata-root>/<same-relative-subpath>` (keep `-meta.xml` sidecars attached) and delete the emptied placeholder dir(s).
|
|
45
118
|
|
|
119
|
+
**Verification:**
|
|
120
|
+
- [ ] Re-run `find uiBundles/<AppName> -type d -regex '.*/<[^/]+>$'` — output must be empty before proceeding.
|
|
46
121
|
|
|
47
122
|
|
package/skills/experience-ui-bundle-features-generate/references/conflict-resolution-schema.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "UI Bundle Features Conflict Resolution",
|
|
4
|
+
"description": "Schema for conflict-resolution.json used by @salesforce/ui-bundle-features CLI",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"patternProperties": {
|
|
7
|
+
"^.+$": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"enum": ["overwrite", "skip"],
|
|
10
|
+
"description": "Resolution strategy for a conflicting file path. 'overwrite' replaces the existing file, 'skip' keeps the existing file."
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"additionalProperties": false,
|
|
14
|
+
"examples": [
|
|
15
|
+
{
|
|
16
|
+
"src/appLayout.tsx": "overwrite",
|
|
17
|
+
"src/routes.tsx": "skip"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Verify that the project contains a React-based UI bundle
|
|
3
|
+
# Exit 0 if React is found, exit 1 otherwise
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
if ! grep -q '"react"' uiBundles/*/package.json 2>/dev/null; then
|
|
8
|
+
echo "ERROR: Not a React bundle - @salesforce/ui-bundle-features requires React"
|
|
9
|
+
echo "Found bundle type: $(grep '"type"' uiBundles/*/package.json 2>/dev/null || echo 'unknown')"
|
|
10
|
+
exit 1
|
|
11
|
+
fi
|
|
12
|
+
|
|
13
|
+
echo "React bundle detected"
|
|
14
|
+
exit 0
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: experience-ui-bundle-frontend-generate
|
|
3
|
-
description: "MUST activate before editing ANY file under uiBundles/*/src/ for visual or UI changes to an EXISTING app — pages, components, sections, layout, styling, colors, fonts, navigation, animations, or any look-and-feel change. Use this skill when modifying pages, components, layout, styling, or navigation in an existing UI bundle app. Activate when the project contains appLayout.tsx, routes.tsx, src/pages/, src/components/, or global.css. This skill contains critical project-specific conventions (appLayout.tsx shell, shadcn/ui components, Tailwind CSS, Salesforce base-path routing, module restrictions) that override general knowledge. Without this skill, generated code will use wrong imports, break routing, or ignore project structure. Do NOT use when creating a new app from scratch (use experience-ui-bundle-app-coordinate instead)."
|
|
3
|
+
description: "MUST activate before editing ANY file under uiBundles/*/src/ for visual or UI changes to an EXISTING app — pages, components, sections, layout, styling, colors, fonts, navigation, animations, or any look-and-feel change. Use this skill when modifying pages, components, layout, styling, or navigation in an existing UI bundle app. Activate when the project contains appLayout.tsx, routes.tsx, src/pages/, src/components/, or src/styles/global.css. This skill contains critical project-specific conventions (appLayout.tsx shell, shadcn/ui components, Tailwind CSS, Salesforce base-path routing, module restrictions) that override general knowledge. Without this skill, generated code will use wrong imports, break routing, or ignore project structure. Do NOT use when creating a new app from scratch (use experience-ui-bundle-app-coordinate instead)."
|
|
4
4
|
metadata:
|
|
5
5
|
version: "1.0"
|
|
6
|
+
relatedSkills:
|
|
7
|
+
- "experience-ui-bundle-app-coordinate"
|
|
8
|
+
- "experience-ui-bundle-salesforce-data-access"
|
|
6
9
|
---
|
|
7
10
|
|
|
8
11
|
# UI Bundle UI
|
|
@@ -78,6 +81,8 @@ React UI bundles must not import Salesforce platform modules like `lightning/*`
|
|
|
78
81
|
|
|
79
82
|
## Design Thinking
|
|
80
83
|
|
|
84
|
+
The rules in this section and "Frontend Aesthetics" below are creative direction, not hard constraints — they cannot be lint- or build-checked and are judged by review, not automation. Two hard, checkable exceptions: never default to Inter/Roboto/Arial/Space Grotesk/system fonts, and mobile responsiveness (Tailwind breakpoints, 44px touch targets) is a MUST, not a style preference.
|
|
85
|
+
|
|
81
86
|
Before coding, commit to a bold aesthetic direction:
|
|
82
87
|
|
|
83
88
|
- **Purpose:** What problem does this interface solve? Who uses it?
|
|
@@ -7,6 +7,39 @@
|
|
|
7
7
|
3. **Use design tokens** — prefer `bg-background`, `text-foreground`, `text-muted-foreground`, `border`, `bg-primary`, `text-destructive`, `rounded-lg` over hardcoded colors.
|
|
8
8
|
4. **Use `cn()`** from `@/lib/utils` for conditional or composable class names.
|
|
9
9
|
5. **TypeScript** — functional components with typed props interface; always accept `className?: string`.
|
|
10
|
+
6. **Never assume a primitive or its exports exist** — the shadcn inventory below is a common baseline, not a guarantee for every app. Before importing anything from `@/components/ui`, read `src/components/ui/index.ts` (the barrel) to confirm the component is actually re-exported there. If it isn't, either import directly from its file (`@/components/ui/<file>`) or add the export to the barrel yourself — never invent a component that isn't present in either place.
|
|
11
|
+
|
|
12
|
+
### Common shadcn/ui Inventory
|
|
13
|
+
|
|
14
|
+
Apps scaffolded from the standard template typically ship these primitives under `src/components/ui/`. Treat this as a starting checklist, not a source of truth — always verify against the actual files and the barrel (`index.ts`) in the current project, since apps diverge (custom primitives get added, unused ones get removed, and not every file is necessarily re-exported from the barrel).
|
|
15
|
+
|
|
16
|
+
| Primitive | Typical file | Notes |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| Alert | `alert.tsx` | `Alert`, `AlertTitle`, `AlertDescription` |
|
|
19
|
+
| Avatar | `avatar.tsx` | `Avatar`, `AvatarImage`, `AvatarFallback` |
|
|
20
|
+
| Badge | `badge.tsx` | Often exists as a file but may not be barrel-exported — check first |
|
|
21
|
+
| Breadcrumb | `breadcrumb.tsx` | |
|
|
22
|
+
| Button | `button.tsx` | `Button`, `buttonVariants` |
|
|
23
|
+
| Calendar | `calendar.tsx` | |
|
|
24
|
+
| Card | `card.tsx` | `Card`, `CardHeader`, `CardTitle`, `CardContent`, `CardFooter` |
|
|
25
|
+
| Checkbox | `checkbox.tsx` | |
|
|
26
|
+
| Collapsible | `collapsible.tsx` | |
|
|
27
|
+
| Date Picker | `datePicker.tsx` | |
|
|
28
|
+
| Dialog | `dialog.tsx` | `Dialog`, `DialogContent`, `DialogHeader`, `DialogTitle`, `DialogTrigger` |
|
|
29
|
+
| Dropdown Menu | `dropdown-menu.tsx` | |
|
|
30
|
+
| Field | `field.tsx` | Composable form-field wrapper (label + error + description) |
|
|
31
|
+
| Input | `input.tsx` | |
|
|
32
|
+
| Label | `label.tsx` | |
|
|
33
|
+
| Pagination | `pagination.tsx` | |
|
|
34
|
+
| Popover | `popover.tsx` | |
|
|
35
|
+
| Select | `select.tsx` | |
|
|
36
|
+
| Separator | `separator.tsx` | |
|
|
37
|
+
| Skeleton | `skeleton.tsx` | |
|
|
38
|
+
| Spinner | `spinner.tsx` | |
|
|
39
|
+
| Table | `table.tsx` | `Table`, `TableHeader`, `TableBody`, `TableRow`, `TableCell` |
|
|
40
|
+
| Tabs | `tabs.tsx` | `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent` |
|
|
41
|
+
|
|
42
|
+
**Not part of this baseline** — do not assume these exist without checking: `Sheet`, `Combobox`, `Accordion`, `Toast`/`Sonner`, `Slider`, `Switch`, `RadioGroup`, `Command`, `Menubar`, `NavigationMenu`, `Tooltip`, `Progress`, `Carousel`, `Drawer`. If the task needs one of these, check `src/components/ui/` first; if it's genuinely missing, either compose it from an existing primitive or tell the user it needs to be added rather than fabricating an import.
|
|
10
43
|
|
|
11
44
|
### File Location — Component
|
|
12
45
|
|
|
@@ -69,7 +102,7 @@ export default function HomePage() {
|
|
|
69
102
|
- **Icons:** `lucide-react`; add `aria-hidden="true"` on decorative icons
|
|
70
103
|
- **Focus styles:** use `focus-visible:` variants
|
|
71
104
|
- **Multiple visual variants:** use CVA (`cva`) and `VariantProps`
|
|
72
|
-
- **shadcn import barrel:** `import { Button, Card, Input } from "@/components/ui"`
|
|
105
|
+
- **shadcn import barrel:** `import { Button, Card, Input } from "@/components/ui"` — only for components confirmed present in `index.ts`; see rule 6 above
|
|
73
106
|
|
|
74
107
|
### Confirm — Component
|
|
75
108
|
|
|
@@ -82,7 +82,7 @@ Use `ROUTES.*` constants from `@/utils/authenticationConfig` for auth-related pa
|
|
|
82
82
|
|
|
83
83
|
- **Local state:** `useState`, `useReducer`, `useRef` inside the page component
|
|
84
84
|
- **Shared or complex state:** extract to `src/hooks/` with a `use` prefix (e.g., `useContacts`)
|
|
85
|
-
- **Data fetching:**
|
|
85
|
+
- **Data fetching:** any Salesforce record access — GraphQL or REST — goes through the `@salesforce/platform-sdk` Data SDK (`createDataSDK()`, then `sdk.graphql`/`sdk.fetch`); consult the `experience-ui-bundle-salesforce-data-access` skill before writing this code, do not call `fetch`/`axios` directly or invent a different data API. Place client/query modules in `src/api/`; place shared data logic (loading, error, caching state) in `src/hooks/`
|
|
86
86
|
- **Auth context:** `useAuth()` from `@/context/AuthContext` when current user is needed — only valid under `AuthProvider`
|
|
87
87
|
|
|
88
88
|
### Confirm — Page
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: experience-ui-bundle-project-generate
|
|
3
|
+
description: "Generates a minimal, ready-to-develop SFDX starter project from template instead of hand-scaffolding files. Use this skill when starting a brand-new Salesforce React UI bundle app and the initial project must be scaffolded — trigger phrases include create, start, or scaffold a new React UI bundle app, generate a starter project, or use a prebuilt/starter template. DO NOT TRIGGER when: editing, styling, or adding pages or components to an EXISTING app (use experience-ui-bundle-frontend-generate); configuring ui-bundle.json or metadata files (use experience-ui-bundle-metadata-generate); deploying to an org (use experience-ui-bundle-deploy); or when the user explicitly says they want to hand-scaffold from scratch."
|
|
4
|
+
metadata:
|
|
5
|
+
version: "1.1"
|
|
6
|
+
relatedSkills:
|
|
7
|
+
- "experience-ui-bundle-app-coordinate"
|
|
8
|
+
- "experience-ui-bundle-metadata-generate"
|
|
9
|
+
- "experience-ui-bundle-frontend-generate"
|
|
10
|
+
- "experience-ui-bundle-salesforce-data-access"
|
|
11
|
+
- "experience-ui-bundle-deploy"
|
|
12
|
+
cliTools:
|
|
13
|
+
- tool: ["sf"]
|
|
14
|
+
semver: ">=2.0.0"
|
|
15
|
+
- tool: ["npm"]
|
|
16
|
+
semver: ">=7.0.0"
|
|
17
|
+
- tool: ["node"]
|
|
18
|
+
semver: ">=16.7.0"
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# Using a UI Bundle Template
|
|
22
|
+
|
|
23
|
+
Before building a Salesforce React UI bundle app from scratch, offer the user a **prebuilt starter template**. The Salesforce CLI generates these — a complete, deployable SFDX project (React UI bundle + toolchain + an `npm run setup` automation) — in one command. Starting from a starter is faster and less error-prone than hand-scaffolding.
|
|
24
|
+
|
|
25
|
+
The CLI command is `sf template generate project`.
|
|
26
|
+
|
|
27
|
+
## Step 1: Offer the choice
|
|
28
|
+
|
|
29
|
+
The following are the templates. Ask the user which one fits, or whether they want to start from scratch.
|
|
30
|
+
|
|
31
|
+
| Template | `--template` flag | Best for |
|
|
32
|
+
|----------|-------------------|----------|
|
|
33
|
+
| Internal starter | `reactinternalapp` | Starter for internal, employee-facing Salesforce apps (e.g. support consoles, ops dashboards, internal admin apps) — users are already-authenticated employees. Includes Agentforce chat. No login flow or public. |
|
|
34
|
+
| External starter | `reactexternalapp` | Starter for customer/partner-facing Salesforce apps/sites (e.g. portals, communities, storefront, public sites). Full auth support (login, registration, reset, profile) -- external users sign in with their own accounts. |
|
|
35
|
+
|
|
36
|
+
**If the user prefers to start from scratch** (or neither fits), stop here and let `experience-ui-bundle-app-coordinate` scaffold a new project. This skill is opt-in — do not force a template.
|
|
37
|
+
|
|
38
|
+
## Step 2: Generate the project into the target root
|
|
39
|
+
|
|
40
|
+
The project contents must land **directly at the target root `$DEST`** — so `sfdx-project.json` sits at `$DEST/sfdx-project.json`, with no extra wrapper subfolder. `sf template generate project` always nests its output under a `--name` subfolder, so generate into the `$DEST` dir, then move the contents from the subfolder up into `$DEST`, overwriting anything already there on conflict. Remove the empty subfolder at the end.
|
|
41
|
+
|
|
42
|
+
- `<SKILL_DIR>` = the absolute path to **this skill's own directory** — the folder containing this `SKILL.md`; resolve it from the skill path in context
|
|
43
|
+
- **`$NAME`** — the project name (alphanumerical only — no spaces, hyphens, underscores, or special characters). Ask the user for it. It also names the UI bundle, so it shows up inside the project.
|
|
44
|
+
- **`$DEST`** — the target root directory the contents land in (use `.` for the current directory).
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
NAME=MyApp # project name the user chose; also names the UI bundle
|
|
48
|
+
DEST=. # target root directory (the contents land directly here, no NAME/ wrapper)
|
|
49
|
+
|
|
50
|
+
# choose ONE template flag based on the user's pick from Step 1
|
|
51
|
+
TEMPLATE=reactinternalapp # or reactexternalapp
|
|
52
|
+
|
|
53
|
+
mkdir -p "$DEST"
|
|
54
|
+
sf template generate project --name "$NAME" --template "$TEMPLATE" --output-dir "$DEST"
|
|
55
|
+
|
|
56
|
+
# Flatten the generated $DEST/$NAME contents up into $DEST (see <SKILL_DIR>/scripts/flatten-project.mjs).
|
|
57
|
+
# Use the absolute skill-dir path — a relative ./scripts/ would resolve against $DEST, not the skill.
|
|
58
|
+
node "<SKILL_DIR>/scripts/flatten-project.mjs" "$DEST/$NAME" "$DEST"
|
|
59
|
+
rm -rf "$DEST/$NAME"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
> `<SKILL_DIR>/scripts/flatten-project.mjs` moves every generated entry (incl. dotfiles) into `$DEST`, overwriting any existing file/dir of any type on conflict while preserving unrelated files the user already had in `$DEST`. The per-entry `rmSync` + `renameSync` is what guarantees the template's files win on conflict (including a file-vs-directory type mismatch).
|
|
63
|
+
|
|
64
|
+
### Verify
|
|
65
|
+
|
|
66
|
+
After generation, confirm the contents landed at the root (not in a `$NAME/` subfolder):
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
test -f "$DEST/sfdx-project.json" && echo "OK: project root landed" || echo "FAILED"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`sfdx-project.json` must sit at `$DEST/sfdx-project.json`. The project also contains `package.json`, `force-app/main/default/uiBundles/$NAME/` (the React/Vite bundle), `scripts/`, `config/`, and `README.md`. If `sfdx-project.json` is missing or is one level down in `$DEST/$NAME/`, the flatten did not run — re-check before continuing.
|
|
73
|
+
|
|
74
|
+
## Step 3: Install dependencies (you do this — do NOT hand off uninstalled)
|
|
75
|
+
|
|
76
|
+
If the generated project ships **without** `node_modules`, **install dependencies yourself before handing the project back** — a fresh template is not runnable (preview/build/lint all fail) until deps are present. The user should receive a ready-to-develop project.
|
|
77
|
+
|
|
78
|
+
There are **multiple** `package.json` files, each needing its own install:
|
|
79
|
+
- the **project root** (`$DEST/package.json`), and
|
|
80
|
+
- the **UI bundle** dir under `$DEST/force-app/main/default/uiBundles/$NAME/` — this holds the toolchain the preview server loads, so it must have `node_modules` too.
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
# 1. project root ($DEST was set in Step 2)
|
|
84
|
+
( cd "$DEST" && npm install )
|
|
85
|
+
|
|
86
|
+
# 2. each UI bundle
|
|
87
|
+
for b in "$DEST"/force-app/main/default/uiBundles/*/; do
|
|
88
|
+
[ -f "$b/package.json" ] && ( cd "$b" && npm install )
|
|
89
|
+
done
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
> First-run install of the bundle is the heavy step (tailwind, radix-ui, recharts, vite, etc.); expect a short wait. If an install fails, surface it — don't hand off a half-installed project.
|
|
93
|
+
|
|
94
|
+
## Step 4: Confirm and hand off
|
|
95
|
+
|
|
96
|
+
Verify the project landed and is installed:
|
|
97
|
+
|
|
98
|
+
```sh
|
|
99
|
+
ls "$DEST" # sfdx-project.json, package.json, force-app/, scripts/, README.md ...
|
|
100
|
+
ls "$DEST"/force-app/main/default/uiBundles/*/node_modules >/dev/null && echo "bundle deps installed"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The project is now ready to develop and deploy. If there's a `README.md` in the template, take a look at it to see if there is any extra step or guidance for the user.
|
|
104
|
+
|
|
105
|
+
From here, continue development with the other ui-bundle skills (`experience-ui-bundle-frontend-generate`, `experience-ui-bundle-salesforce-data-access`, `experience-ui-bundle-deploy`, etc.) against the now-scaffolded project — scaffolding and dependency install are already done.
|
|
106
|
+
|
|
107
|
+
## Notes
|
|
108
|
+
|
|
109
|
+
- The starters are **minimal** — no seeded sample data or custom objects. Build the rest with the other ui-bundle skills.
|
|
110
|
+
- These templates use the `uiBundles` metadata convention. The UI bundle directory and meta XML are named after the project name you pass to `--name`.
|
|
111
|
+
- `sf template generate project --help` lists all available templates if the flag names ever change.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Flatten a `sf template generate project` result into the target root.
|
|
3
|
+
//
|
|
4
|
+
// Usage: node <skill_dir>/scripts/flatten-project.mjs <srcDir> <destDir>
|
|
5
|
+
// <srcDir> — the generated project dir (the `$STAGE/$NAME` subfolder the CLI nests output under)
|
|
6
|
+
// <destDir> — the target root the contents should land in (so sfdx-project.json sits at <destDir>/sfdx-project.json)
|
|
7
|
+
//
|
|
8
|
+
// Moves every generated entry (incl. dotfiles) from <srcDir> up into <destDir>, overwriting any
|
|
9
|
+
// existing file/dir of any type on conflict. Unrelated files already in <destDir> are left untouched
|
|
10
|
+
// — only the paths the template ships get replaced. The per-entry rmSync + renameSync is what
|
|
11
|
+
// guarantees the template's files win on conflict (including a file-vs-directory type mismatch).
|
|
12
|
+
// Requires Node ≥ 16.7 for rmSync.
|
|
13
|
+
|
|
14
|
+
import fs from "node:fs";
|
|
15
|
+
import path from "node:path";
|
|
16
|
+
|
|
17
|
+
const [src, dest] = process.argv.slice(2);
|
|
18
|
+
|
|
19
|
+
if (!src || !dest) {
|
|
20
|
+
console.error("usage: node <skill_dir>/scripts/flatten-project.mjs <srcDir> <destDir>");
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!fs.existsSync(path.join(src, "sfdx-project.json"))) {
|
|
25
|
+
console.error("generated project has no sfdx-project.json: " + src);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
for (const entry of fs.readdirSync(src)) {
|
|
30
|
+
const target = path.join(dest, entry);
|
|
31
|
+
fs.rmSync(target, { recursive: true, force: true });
|
|
32
|
+
fs.renameSync(path.join(src, entry), target);
|
|
33
|
+
}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: platform-custom-lightning-type-generate
|
|
3
|
-
description: "Use this skill when users need to create Custom Lightning Types (CLTs) for Einstein Agent actions or structured input/output schemas. Trigger when users mention CLT, Custom Lightning Types,
|
|
3
|
+
description: "Use this skill when users need to create Custom Lightning Types (CLTs) for Einstein Agent actions or structured input/output schemas. Trigger when users mention CLT, Custom Lightning Types, JSON schemas for agents, type definitions, lightning__objectType, or editor/renderer configurations. For widget renditions that combine a CLT with a Widget bundle, use the platform-lightning-type-widget-coordinate orchestrator instead. This is complex - always use this skill for CLT work."
|
|
4
4
|
metadata:
|
|
5
5
|
version: "1.0"
|
|
6
|
+
minApiVersion: "60.0"
|
|
7
|
+
relatedSkills:
|
|
8
|
+
- "platform-lightning-type-widget-coordinate"
|
|
6
9
|
---
|
|
7
10
|
|
|
8
11
|
## When to Use This Skill
|
|
@@ -12,7 +15,6 @@ Use this skill when you need to:
|
|
|
12
15
|
- Generate JSON Schema-based type definitions for Lightning Platform
|
|
13
16
|
- Configure CLTs for Einstein Agent actions
|
|
14
17
|
- Set up editor and renderer configurations for custom UI
|
|
15
|
-
- Create CLTs with widget/mosaic/fragment rendition
|
|
16
18
|
- Troubleshoot deployment errors related to Custom Lightning Types
|
|
17
19
|
|
|
18
20
|
## Specification
|
|
@@ -54,6 +56,7 @@ Custom Lightning Types (CLTs) are JSON Schema-based type definitions used by the
|
|
|
54
56
|
- **Apex class CLTs are minimal**:
|
|
55
57
|
- Include **only** `title`, `description` (optional), and `lightning:type` set to `@apexClassType/...`.
|
|
56
58
|
- Do **not** add `type`, `properties`, `required`, or `unevaluatedProperties`.
|
|
59
|
+
- **No shell metacharacters that trigger the Vibes safe-shell filter.** In any Bash tool call emitted by this skill, do NOT use command substitution (`$(…)` or backticks), process substitution (`<(…)`, `>(…)`), brace expansion (`{a,b,c}` or `{1..N}`), or `eval` / `exec`. Vibes forces manual approval on these patterns even under Bypass mode and stalls the eval. Emit separate commands (`mkdir -p a && mkdir -p b`) or print each value with its own command and reason about the output rather than capturing it in a shell variable.
|
|
57
60
|
|
|
58
61
|
## Additional CLT Metaschema Validations
|
|
59
62
|
- **Org namespace validation**: titles/descriptions and other string fields may be validated to ensure you are not using an org namespace in places that are disallowed.
|
|
@@ -66,7 +69,7 @@ When you need the full list of supported primitive `lightning:type` identifiers,
|
|
|
66
69
|
|
|
67
70
|
## Generation Workflow
|
|
68
71
|
1. **Confirm the CLT approach**
|
|
69
|
-
- If referencing Apex: capture the exact class reference (
|
|
72
|
+
- If referencing Apex: capture the exact class reference (@apexClassType/namespace__ClassName$InnerClass).
|
|
70
73
|
- If using standard primitives: list the fields, their Lightning primitive types, and which fields are required.
|
|
71
74
|
2. **Draft `schema.json`**
|
|
72
75
|
- **DO NOT include `"$schema"` at the top**
|
|
@@ -100,26 +103,18 @@ When you need the full list of supported primitive `lightning:type` identifiers,
|
|
|
100
103
|
- **Avoid known-invalid patterns**:
|
|
101
104
|
- Do not use `es_property_editors/inputList`.
|
|
102
105
|
- Do not use `itemSchema` attributes.
|
|
103
|
-
4. **(Optional) Draft `renderer.json`** (only if custom UI or
|
|
106
|
+
4. **(Optional) Draft `renderer.json`** (only if custom UI or widget rendition is required)
|
|
104
107
|
- **Supported shape:** Top-level `renderer` object with `renderer.componentOverrides` and `renderer.layout`.
|
|
105
108
|
- Top-level `renderer` object.
|
|
106
109
|
- Use `renderer.componentOverrides` for component overrides.
|
|
107
110
|
- Use `renderer.layout` for layout.
|
|
108
111
|
- **DEPRECATED**: Do NOT use `propertyRenderers` or `view` — these are legacy keys. Always use `componentOverrides` and `layout` instead.
|
|
109
|
-
- **
|
|
112
|
+
- **Widget rendition pattern** (reference an existing WidgetBundle as the root renderer): the renderer file is a thin wrapper that points at the widget by developer name (`"definition": "@widget/c/<widgetDeveloperName>"`) and maps CLT schema properties to widget attributes via `{!$attrs.<schemaPropertyName>}`. Do **NOT** duplicate the widget body inside `renderer.json`. See `references/widget-rendition.md` for the full shape, binding rules, and constraints. For the full Apex → Lightning Type → Widget pipeline, use the `platform-lightning-type-widget-coordinate` orchestrator instead of this skill.
|
|
113
|
+
- **Root override pattern** (most common for fully custom rendering UI with a custom LWC):
|
|
110
114
|
- `renderer.componentOverrides["$"] = { "definition": "c/<yourRendererComponent>", "attributes": { ... } }`
|
|
111
115
|
- Use `{!$attrs.<name>}` in attribute mappings when binding schema data to custom renderer component attributes.
|
|
112
116
|
- **CRITICAL**: Attribute mappings like `{!$attrs.propertyName}` must reference properties that **actually exist** in your type schema. Referencing non-existent properties will fail validation.
|
|
113
117
|
- **Type matching**: Attribute values must match the expected type for the component. For example, if a component expects a string attribute, passing an integer will fail validation.
|
|
114
|
-
- **Widget renderer pattern** (for widget rendition):
|
|
115
|
-
- **When to use:** Use this when users request "mosaic", "widget", "fragment", or "cross-platform rendering" for their CLT.
|
|
116
|
-
- **Structure:** `renderer.componentOverrides["$"] = { "type": "mosaic", "definition": "tile/mosaic", "children": [ /* UEM tree of blocks and regions */ ] }`
|
|
117
|
-
- **REQUIRED workflow:**
|
|
118
|
-
- **STOP**: Do NOT attempt to create the widget renderer yourself.
|
|
119
|
-
- **MANDATORY FIRST STEP**: You MUST fetch the reference file `references/widget-rendition.md` located in this skill's directory before proceeding.
|
|
120
|
-
- Follow the complete workflow documented in `widget-rendition.md` using the generated CLT schema as the grounding schema.
|
|
121
|
-
- The `widget-rendition.md` reference contains the full widget generation workflow: discovering UEM blocks via discoverUiComponents, calling getUiComponentSchemas, building the UEM tree, and writing renderer.json.
|
|
122
|
-
- **Do not** attempt to generate widget rendition without first fetching the `widget-rendition.md` reference file.
|
|
123
118
|
- **Property-level override pattern**:
|
|
124
119
|
- `renderer.componentOverrides["<propertyName>"] = { "definition": "es_property_editors/outputText" | "es_property_editors/outputNumber" | "es_property_editors/outputImage" | ... }`. **Valid renderer components** (examples): `es_property_editors/outputText`, `es_property_editors/outputNumber`, `es_property_editors/outputImage`. Avoid input-style components in the renderer.
|
|
125
120
|
- **Layout pattern for renderer**:
|