Rename webapp/webapplication to UI bundle in skills (#129)

* Split generating-webapp-metadata into single-purpose skills

Extract the deployment sequence into a new deploying-webapp skill so each
webapp skill describes exactly one actionable goal. This improves agent
skill selection accuracy by eliminating multi-concern descriptions.

- generating-webapp-metadata: now focused on scaffolding, bundle config, CSP
- deploying-webapp: new skill for the 7-step deployment sequence

* Rename -webapp- skill directories and references to -webapplication-

Rename all 7 webapp skill directories to use the full "webapplication"
entity name. Update frontmatter name fields, cross-skill references,
and descriptive prose. Package names and CLI commands are preserved
as-is since those are actual identifiers.
This commit is contained in:
k-j-kim 2026-03-30 09:49:19 -07:00 committed by GitHub
parent 5a52a8a6ec
commit a779945206
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 203 additions and 200 deletions

View File

@ -0,0 +1,77 @@
---
name: deploying-webapplication
description: "Deploy a Salesforce web application to an org — the full deployment sequence including org authentication, pre-deploy build, metadata deployment, permission set assignment, data import, GraphQL schema fetch, and codegen. Use whenever the user wants to deploy, push to org, assign permission sets, import data, fetch GraphQL schema, run codegen, or set up an org after development. Triggers on: deploy, push to org, deploy metadata, assign permission set, import data, schema fetch, codegen, org auth, authenticate org, build and deploy, post-deploy, org setup."
---
# Deploying a Web Application
The order of operations is critical when deploying to a Salesforce org. This sequence reflects the canonical flow.
## Step 1: Org Authentication
Check if the org is connected. If not, authenticate. All subsequent steps require an authenticated org.
## Step 2: Pre-deploy Web Application Build
Install dependencies and build the web application to produce `dist/`. Required before deploying web application entities.
Run when: deploying web applications and `dist/` is missing or source has changed.
## Step 3: Deploy Metadata
Check for a manifest (`manifest/package.xml` or `package.xml`) first. If present, deploy using the manifest. If not, deploy all metadata from the project.
Deploys objects, layouts, permission sets, Apex classes, web applications, and all other metadata. Must complete before schema fetch — the schema reflects org state.
## Step 4: Post-deploy Configuration
Deploying does not mean assigning. After deployment:
- **Permission sets / groups** — assign to users so they have access to custom objects and fields. Required for GraphQL introspection to return the correct schema.
- **Profiles** — ensure users have the correct profile.
- **Other config** — named credentials, connected apps, custom settings, flow activation.
Proactive behavior: after a successful deploy, discover permission sets in `force-app/main/default/permissionsets/` and assign each one (or ask the user).
## Step 5: Data Import (optional)
Only if `data/data-plan.json` exists. Delete runs in reverse plan order (children before parents). Import uses Anonymous Apex with duplicate rule save enabled.
Always ask the user before importing or cleaning data.
## Step 6: GraphQL Schema and Codegen
1. Set default org
2. Fetch schema (GraphQL introspection) — writes `schema.graphql` at project root
3. Generate types (codegen reads schema locally)
Run when: schema missing, or metadata/permissions changed since last fetch.
## Step 7: Final Web Application Build
Build the web application if not already done in Step 2.
## Summary: Interaction Order
1. Check/authenticate org
2. Build web application (if deploying web applications)
3. Deploy metadata
4. Assign permissions and configure
5. Import data (if data plan exists, with user confirmation)
6. Fetch GraphQL schema and run codegen
7. Build web application (if needed)
## Critical Rules
- Deploy metadata **before** fetching schema — custom objects/fields appear only after deployment
- Assign permissions **before** schema fetch — the user may lack FLS for custom fields
- Re-run schema fetch and codegen **after every metadata deployment** that changes objects, fields, or permissions
- Never skip permission set assignment or data import silently — either run them or ask the user
## Post-deploy Checklist
After every successful metadata deploy:
1. Discover and assign permission sets (or ask the user)
2. If `data/data-plan.json` exists, ask the user about data import
3. Re-run schema fetch and codegen from the web application directory

View File

@ -1,180 +0,0 @@
---
name: generating-webapp-metadata
description: "Scaffold new Salesforce web applications and configure/deploy their metadata — sf webapp generate, WebApplication bundles (meta XML, webapplication.json with routing/headers/outputDir), CSP Trusted Sites for external domains, and the full deployment sequence (org auth, build, deploy, permset assign, data import, GraphQL schema fetch, codegen). Use whenever creating a new webapp, setting up webapp metadata structure, adding external domains that need CSP registration, deploying to a Salesforce org, assigning permission sets, fetching GraphQL schema, or running codegen. Triggers on: create webapp, new app, sf webapp generate, deploy, metadata, webapplication.json, CSP, trusted site, permission set, schema fetch, codegen, org setup, bundle configuration, meta XML, routing config, external domain."
---
# Web Application Metadata
## Scaffolding a New Webapp
Use `sf webapp generate` to create new apps — not create-react-app, Vite, or other generic scaffolds.
**Webapp name (`-n`):** Alphanumerical only — no spaces, hyphens, underscores, or special characters. Example: `CoffeeBoutique` (not `Coffee Boutique`).
After generation:
1. Replace all default boilerplate — "React App", "Vite + React", default `<title>`, placeholder text
2. Populate the home page with real content (landing section, banners, hero, navigation)
3. Update navigation and placeholders (see the `generating-webapp-ui` skill)
Always install dependencies before running any scripts in the webapp directory.
---
## WebApplication Bundle
A WebApplication bundle lives under `webapplications/<AppName>/` and must contain:
- `<AppName>.webapplication-meta.xml` — filename must exactly match the folder name
- A build output directory (default: `dist/`) with at least one file
### Meta XML
Required fields: `masterLabel`, `version` (max 20 chars), `isActive` (boolean).
Optional: `description` (max 255 chars).
### webapplication.json
Optional file. Allowed top-level keys: `outputDir`, `routing`, `headers`.
**Constraints:**
- Valid UTF-8 JSON, max 100 KB
- Root must be a non-empty object (never `{}`, arrays, or primitives)
**Path safety** (applies to `outputDir` and `routing.fallback`): Reject backslashes, leading `/` or `\`, `..` segments, null/control characters, globs (`*`, `?`, `**`), and `%`. All resolved paths must stay within the bundle.
#### outputDir
Non-empty string referencing a subdirectory (not `.` or `./`). Directory must exist and contain at least one file.
#### routing
If present, must be a non-empty object. Allowed keys: `rewrites`, `redirects`, `fallback`, `trailingSlash`, `fileBasedRouting`.
- **trailingSlash**: `"always"`, `"never"`, or `"auto"`
- **fileBasedRouting**: boolean
- **fallback**: non-empty string satisfying path safety; target file must exist
- **rewrites**: non-empty array of `{ route?, rewrite }` objects — e.g., `{ "route": "/app/:path*", "rewrite": "/index.html" }`
- **redirects**: non-empty array of `{ route?, redirect, statusCode? }` objects — statusCode must be 301, 302, 307, or 308
#### headers
Non-empty array of `{ source, headers: [{ key, value }] }` objects.
**Example:**
```json
{
"routing": {
"rewrites": [{ "route": "/app/:path*", "rewrite": "/index.html" }],
"trailingSlash": "never"
},
"headers": [
{
"source": "/assets/**",
"headers": [{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }]
}
]
}
```
**Never suggest:** `{}` as root, empty `"routing": {}`, empty arrays, `[{}]`, `"outputDir": "."`, `"outputDir": "./"`.
---
## CSP Trusted Sites
Salesforce enforces Content Security Policy headers. Any external domain not registered as a CSP Trusted Site will be blocked (images won't load, API calls fail, fonts missing).
### When to Create
Whenever the app references a new external domain: CDN images, external fonts, third-party APIs, map tiles, iframes, external stylesheets.
### Steps
1. **Identify external domains** — extract the origin (scheme + host) from each external URL in the code
2. **Check existing registrations** — look in `force-app/main/default/cspTrustedSites/`
3. **Map resource type to CSP directive:**
| Resource Type | Directive Field |
|--------------|----------------|
| Images | `isApplicableToImgSrc` |
| API calls (fetch, XHR) | `isApplicableToConnectSrc` |
| Fonts | `isApplicableToFontSrc` |
| Stylesheets | `isApplicableToStyleSrc` |
| Video / audio | `isApplicableToMediaSrc` |
| Iframes | `isApplicableToFrameSrc` |
Always also set `isApplicableToConnectSrc` to `true` for preflight/redirect handling.
4. **Create the metadata file** — follow `implementation/csp-metadata-format.md` for the `.cspTrustedSite-meta.xml` format. Place in `force-app/main/default/cspTrustedSites/`.
---
## Deployment Sequence
The order of operations is critical when deploying to a Salesforce org. This sequence reflects the canonical flow.
### Step 1: Org Authentication
Check if the org is connected. If not, authenticate. All subsequent steps require an authenticated org.
### Step 2: Pre-deploy Webapp Build
Install dependencies and build the webapp to produce `dist/`. Required before deploying web application entities.
Run when: deploying web apps and `dist/` is missing or source has changed.
### Step 3: Deploy Metadata
Check for a manifest (`manifest/package.xml` or `package.xml`) first. If present, deploy using the manifest. If not, deploy all metadata from the project.
Deploys objects, layouts, permission sets, Apex classes, web applications, and all other metadata. Must complete before schema fetch — the schema reflects org state.
### Step 4: Post-deploy Configuration
Deploying does not mean assigning. After deployment:
- **Permission sets / groups** — assign to users so they have access to custom objects and fields. Required for GraphQL introspection to return the correct schema.
- **Profiles** — ensure users have the correct profile.
- **Other config** — named credentials, connected apps, custom settings, flow activation.
Proactive behavior: after a successful deploy, discover permission sets in `force-app/main/default/permissionsets/` and assign each one (or ask the user).
### Step 5: Data Import (optional)
Only if `data/data-plan.json` exists. Delete runs in reverse plan order (children before parents). Import uses Anonymous Apex with duplicate rule save enabled.
Always ask the user before importing or cleaning data.
### Step 6: GraphQL Schema and Codegen
1. Set default org
2. Fetch schema (GraphQL introspection) — writes `schema.graphql` at project root
3. Generate types (codegen reads schema locally)
Run when: schema missing, or metadata/permissions changed since last fetch.
### Step 7: Final Webapp Build
Build the webapp if not already done in Step 2.
### Summary: Interaction Order
1. Check/authenticate org
2. Build webapp (if deploying web apps)
3. Deploy metadata
4. Assign permissions and configure
5. Import data (if data plan exists, with user confirmation)
6. Fetch GraphQL schema and run codegen
7. Build webapp (if needed)
### Critical Rules
- Deploy metadata **before** fetching schema — custom objects/fields appear only after deployment
- Assign permissions **before** schema fetch — the user may lack FLS for custom fields
- Re-run schema fetch and codegen **after every metadata deployment** that changes objects, fields, or permissions
- Never skip permission set assignment or data import silently — either run them or ask the user
### Post-deploy Checklist
After every successful metadata deploy:
1. Discover and assign permission sets (or ask the user)
2. If `data/data-plan.json` exists, ask the user about data import
3. Re-run schema fetch and codegen from the webapp directory

View File

@ -1,5 +1,5 @@
---
name: generating-webapp-features
name: generating-webapplication-features
description: "Search and install pre-built features into Salesforce React web applications — authentication, shadcn, search, navigation, GraphQL, Agentforce AI, and more. Use whenever searching for or installing features. Always check for an existing feature before building from scratch. Triggers on: install feature, add authentication, add shadcn, add feature, search features, list features."
---
@ -7,7 +7,7 @@ description: "Search and install pre-built features into Salesforce React web ap
## Installing Pre-built Features
Always check for an existing feature before building something from scratch. The features CLI installs pre-built, tested packages into Salesforce webapps — from foundational UI libraries (shadcn/ui) to full-stack capabilities (authentication, search, navigation, GraphQL, Agentforce AI).
Always check for an existing feature before building something from scratch. The features CLI installs pre-built, tested packages into Salesforce web applications — from foundational UI libraries (shadcn/ui) to full-stack capabilities (authentication, search, navigation, GraphQL, Agentforce AI).
### Workflow

View File

@ -0,0 +1,106 @@
---
name: generating-webapplication-metadata
description: "Scaffold new Salesforce web applications and configure their metadata — sf webapp generate, WebApplication bundles (meta XML, webapplication.json with routing/headers/outputDir), and CSP Trusted Sites for external domains. Use whenever creating a new web application, setting up web application metadata structure, configuring routing or headers, setting outputDir, adding external domains that need CSP registration, or editing bundle configuration. Triggers on: create web application, create webapp, new app, sf webapp generate, metadata, webapplication.json, CSP, trusted site, bundle configuration, meta XML, routing config, external domain, headers config, outputDir."
---
# Web Application Metadata
## Scaffolding a New Web Application
Use `sf webapp generate` to create new apps — not create-react-app, Vite, or other generic scaffolds.
**Web application name (`-n`):** Alphanumerical only — no spaces, hyphens, underscores, or special characters. Example: `CoffeeBoutique` (not `Coffee Boutique`).
After generation:
1. Replace all default boilerplate — "React App", "Vite + React", default `<title>`, placeholder text
2. Populate the home page with real content (landing section, banners, hero, navigation)
3. Update navigation and placeholders (see the `generating-webapplication-ui` skill)
Always install dependencies before running any scripts in the web application directory.
---
## WebApplication Bundle
A WebApplication bundle lives under `webapplications/<AppName>/` and must contain:
- `<AppName>.webapplication-meta.xml` — filename must exactly match the folder name
- A build output directory (default: `dist/`) with at least one file
### Meta XML
Required fields: `masterLabel`, `version` (max 20 chars), `isActive` (boolean).
Optional: `description` (max 255 chars).
### webapplication.json
Optional file. Allowed top-level keys: `outputDir`, `routing`, `headers`.
**Constraints:**
- Valid UTF-8 JSON, max 100 KB
- Root must be a non-empty object (never `{}`, arrays, or primitives)
**Path safety** (applies to `outputDir` and `routing.fallback`): Reject backslashes, leading `/` or `\`, `..` segments, null/control characters, globs (`*`, `?`, `**`), and `%`. All resolved paths must stay within the bundle.
#### outputDir
Non-empty string referencing a subdirectory (not `.` or `./`). Directory must exist and contain at least one file.
#### routing
If present, must be a non-empty object. Allowed keys: `rewrites`, `redirects`, `fallback`, `trailingSlash`, `fileBasedRouting`.
- **trailingSlash**: `"always"`, `"never"`, or `"auto"`
- **fileBasedRouting**: boolean
- **fallback**: non-empty string satisfying path safety; target file must exist
- **rewrites**: non-empty array of `{ route?, rewrite }` objects — e.g., `{ "route": "/app/:path*", "rewrite": "/index.html" }`
- **redirects**: non-empty array of `{ route?, redirect, statusCode? }` objects — statusCode must be 301, 302, 307, or 308
#### headers
Non-empty array of `{ source, headers: [{ key, value }] }` objects.
**Example:**
```json
{
"routing": {
"rewrites": [{ "route": "/app/:path*", "rewrite": "/index.html" }],
"trailingSlash": "never"
},
"headers": [
{
"source": "/assets/**",
"headers": [{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }]
}
]
}
```
**Never suggest:** `{}` as root, empty `"routing": {}`, empty arrays, `[{}]`, `"outputDir": "."`, `"outputDir": "./"`.
---
## CSP Trusted Sites
Salesforce enforces Content Security Policy headers. Any external domain not registered as a CSP Trusted Site will be blocked (images won't load, API calls fail, fonts missing).
### When to Create
Whenever the app references a new external domain: CDN images, external fonts, third-party APIs, map tiles, iframes, external stylesheets.
### Steps
1. **Identify external domains** — extract the origin (scheme + host) from each external URL in the code
2. **Check existing registrations** — look in `force-app/main/default/cspTrustedSites/`
3. **Map resource type to CSP directive:**
| Resource Type | Directive Field |
|--------------|----------------|
| Images | `isApplicableToImgSrc` |
| API calls (fetch, XHR) | `isApplicableToConnectSrc` |
| Fonts | `isApplicableToFontSrc` |
| Stylesheets | `isApplicableToStyleSrc` |
| Video / audio | `isApplicableToMediaSrc` |
| Iframes | `isApplicableToFrameSrc` |
Always also set `isApplicableToConnectSrc` to `true` for preflight/redirect handling.
4. **Create the metadata file** — follow `implementation/csp-metadata-format.md` for the `.cspTrustedSite-meta.xml` format. Place in `force-app/main/default/cspTrustedSites/`.

View File

@ -1,5 +1,5 @@
---
name: generating-webapp-ui
name: generating-webapplication-ui
description: "Build and modify React UI for Salesforce web applications — pages, components, layout, navigation, and headers/footers. Use whenever creating or editing TSX/JSX files or making visual/layout changes. Triggers on: add page, add component, header, footer, navigation, layout, styling, Tailwind, shadcn, React component, appLayout."
---
@ -61,7 +61,7 @@ Apps run behind dynamic base paths. Router navigation (`<Link to>`, `navigate()`
### Module Restrictions
React apps must not import Salesforce platform modules like `lightning/*` or `@wire` (LWC-only). For data access, use the `using-webapp-salesforce-data` skill.
React apps must not import Salesforce platform modules like `lightning/*` or `@wire` (LWC-only). For data access, use the `using-webapplication-salesforce-data` skill.
---
@ -119,4 +119,4 @@ Ask one question at a time and stop when you have enough context.
## Verification
Before completing, run lint and build from the webapp directory. Lint must result in 0 errors and build must succeed.
Before completing, run lint and build from the web application directory. Lint must result in 0 errors and build must succeed.

View File

@ -1,5 +1,5 @@
---
name: implementing-webapp-agentforce-conversation-client
name: implementing-webapplication-agentforce-conversation-client
description: "Adds or modifies AgentforceConversationClient in React apps (.tsx or .jsx files). Use when user says \"add chat widget\", \"embed agentforce\", \"add agent\", \"add chatbot\", \"integrate conversational AI\", or asks to change colors, dimensions, styling, or configure agentId, width, height, inline mode, or styleTokens for travel agent, HR agent, employee agent, or any Salesforce agent chat."
metadata:
author: ACC Components

View File

@ -1,11 +1,11 @@
---
name: implementing-webapp-file-upload
description: "Add file upload functionality to React webapps with progress tracking and Salesforce ContentVersion integration. Use when the user wants to upload files, attach documents, handle file input, create file dropzones, track upload progress, or link files to Salesforce records. This feature provides programmatic APIs ONLY — no components or hooks are exported. Build your own custom UI using the upload() API. ALWAYS use this feature instead of building file upload from scratch with FormData or XHR."
name: implementing-webapplication-file-upload
description: "Add file upload functionality to React web applications with progress tracking and Salesforce ContentVersion integration. Use when the user wants to upload files, attach documents, handle file input, create file dropzones, track upload progress, or link files to Salesforce records. This feature provides programmatic APIs ONLY — no components or hooks are exported. Build your own custom UI using the upload() API. ALWAYS use this feature instead of building file upload from scratch with FormData or XHR."
---
# File Upload API (workflow)
When the user wants file upload functionality in a React webapp, follow this workflow. This feature provides **APIs only** — you must build the UI components yourself using the provided APIs.
When the user wants file upload functionality in a React web application, follow this workflow. This feature provides **APIs only** — you must build the UI components yourself using the provided APIs.
## CRITICAL: This is an API-only package
@ -366,7 +366,7 @@ The package includes a reference implementation in `src/features/fileupload/` wi
**Upload fails with CORS error:**
- Ensure the webapp is properly deployed to Salesforce or running on `localhost`
- Ensure the web application is properly deployed to Salesforce or running on `localhost`
- Check that the org allows the origin in CORS settings
**No progress updates:**

View File

@ -1,5 +1,5 @@
---
name: using-webapp-salesforce-data
name: using-webapplication-salesforce-data
description: "Salesforce data access for reading, writing, and querying records via REST, GraphQL, Apex, or Platform SDK. Use when the user wants to fetch, search, filter, sort, display, create, update, delete, or attach files to Salesforce records (standard objects like Accounts, Contacts, Opportunities, Cases, Quotes, or any custom object) in a web app or UI component (React, Angular, Vue, etc.); call Chatter, Connect, or Apex REST APIs; or invoke AuraEnabled Apex methods from an external app. Does not apply to authentication/OAuth setup, schema changes (adding fields, relationships), Bulk/Tooling/Metadata API usage, declarative automation (Flows, Process Builder), general LWC/Apex coding guidance without a specific data operation, or Salesforce admin/configuration tasks."
---
@ -48,7 +48,7 @@ const res = await sdk.fetch?.("/services/apexrest/my-resource");
**Not supported:**
- **Enterprise REST query endpoint** (`/services/data/v*/query` with SOQL) — blocked at the proxy level. Use GraphQL for record reads; use Apex REST if server-side SOQL aggregates are required.
- **Aura-enabled Apex** (`@AuraEnabled`) — an LWC/Aura pattern with no invocation path from React webapps.
- **Aura-enabled Apex** (`@AuraEnabled`) — an LWC/Aura pattern with no invocation path from React web applications.
- **Chatter API** (`/chatter/users/me`) — use `uiapi { currentUser { ... } }` in a GraphQL query instead.
- **Any other Salesforce REST endpoint** not listed in the supported table above.
@ -92,8 +92,8 @@ These rules exist because Salesforce GraphQL has platform-specific behaviors tha
The `schema.graphql` file (265K+ lines) is the source of truth. **Never open or parse it directly.**
1. Check if `schema.graphql` exists at the SFDX project root
2. If missing, run from the **webapp dir**: `npm run graphql:schema`
3. Custom objects appear only after metadata is deployed — invoke the `deploying-webapp-to-salesforce` skill if deployment is needed
2. If missing, run from the **web application dir**: `npm run graphql:schema`
3. Custom objects appear only after metadata is deployed
### Step 2: Look Up Entity Schema
@ -233,7 +233,7 @@ const fields = response?.data?.uiapi?.objectInfos?.[0]?.fields ?? [];
### Step 4: Validate & Test
1. **Lint**: `npx eslint <file>` from webapp dir
1. **Lint**: `npx eslint <file>` from web application dir
2. **Test**: Ask user before testing. For mutations, request input values — never fabricate data.
**If ESLint reports a GraphQL error** (e.g. `Cannot query field`, `Unknown type`, `Unknown argument`), the field or type name is wrong. Re-run the schema search script to find the correct name — do not guess:
@ -247,7 +247,7 @@ Then fix the query using the exact names from the script output. For detailed er
---
## Webapp Integration (React)
## Web Application Integration (React)
Two integration patterns are available:
@ -335,16 +335,16 @@ const response = await sdk.graphql?.(GET_CURRENT_USER);
<project-root>/ ← SFDX project root
├── schema.graphql ← grep target (lives here)
├── sfdx-project.json
└── force-app/main/default/webapplications/<app-name>/ ← webapp dir
└── force-app/main/default/webapplications/<app-name>/ ← web application dir
├── package.json ← npm scripts
└── src/
```
| Command | Run From | Why |
|---------|----------|-----|
| `npm run graphql:schema` | webapp dir | Script in webapp's package.json |
| `npx eslint <file>` | webapp dir | Reads eslint.config.js |
| `bash scripts/graphql-search.sh <Entity>` | skill root | Schema lookup |
| `npm run graphql:schema` | web application dir | Script in web application's package.json |
| `npx eslint <file>` | web application dir | Reads eslint.config.js |
| `bash scripts/graphql-search.sh <Entity>` | project root | Schema lookup |
| `sf api request rest` | project root | Needs sfdx-project.json |
---