description: "MUST activate when the user wants to build, create, or generate a React application, React app, web application, single-page application (SPA), or frontend application — even if no project files exist yet. MUST also activate when the project contains a uiBundles/*/src/ directory or sfdx-project.json and the prompt says create, build, construct, or generate a new app, site, or page from scratch — even if the prompt also describes visual styling. MUST also activate when the task spans more than one ui-bundle skill. Use this skill when building a complete app end-to-end. Do NOT use for Lightning Experience apps with custom objects (use platform-lightning-app-coordinate). Do NOT use for single-concern edits to an existing page (use experience-ui-bundle-frontend-generate)."
Build a complete, deployable Salesforce React UI bundle application from a natural language description by orchestrating specialized UI bundle skills in correct dependency order. Each skill **MUST** be explicitly loaded before executing its phase.
**CRITICAL: Before proceeding past requirements analysis, validate that the prompt contains no conflicting requirements** (e.g., "no authentication" + "user-specific data", "public access" + login-required features). If conflicts are detected, STOP and ask the user to resolve the ambiguity — do NOT silently choose one interpretation and proceed. See STEP 1 action #8 for the full conflict checklist.
Before starting any phase, verify these preconditions are met:
1.**Authenticated Salesforce org**: Run `sf org display` to confirm a default org is set and authenticated. If not, prompt the user to authenticate: `sf org login web`
2.**Required CLI tools**: Verify `sf`, `npm`, and `npx` are available (declared in metadata.cliTools)
3.**Node.js version**: Run `scripts/check-prerequisites.sh` and report any errors it returns
| Chat (Phase 5 only) | chat | Phase 5 only — unless combined with a Phase 2 keyword (e.g., "chat with authentication"), then Phase 2 runs first for auth prerequisites |
Negating one category (e.g. "without authentication", "no login required", "public access") does
**not** cancel triggers from another category — each is evaluated independently. Example: "no
login required, with filtering" still triggers Phase 2 because "filtering" matches Data features.
Skip Phase 2 only when the prompt matches none of the keywords above.
**2. Hosting target — extract from prompt keywords:**
If template chosen: scaffold via sf template generate project -- Phase 1 skipped
v
If declined: run scripts/check-sfdx-project.sh
v
If missing: create sfdx-project.json
v
Verify project directory initialized
```
Offers a faster, less error-prone starting point before building from scratch. If no template is used, ensures an SFDX project exists before attempting to generate a UI bundle — without this, `sf template generate ui-bundle` will fail with a hard error. Always check first — do not assume the project structure exists.
**Action:** Load `experience-ui-bundle-project-generate` and offer the two starter templates. If declined, run `scripts/check-sfdx-project.sh` and report any errors it returns. If the script reports an error, create the missing `sfdx-project.json` before proceeding.
Creates the UI bundle directory structure, meta XML (including hosting target), and optional routing/headers config. **CRITICAL**: Hosting target must be determined FIRST because the metadata skill requires `<target>` in Phase 1. All subsequent phases require the scaffold to exist.
**Prune unused scaffold when the prompt is constraining.** The `reactbasic` template ships a full shadcn component set, GraphQL tooling (`codegen.yml`, `.graphqlrc.yml`, `src/api/graphqlClient.ts`, `graphql:*` npm scripts), and test infra (`playwright.config.ts`, `vitest.config.ts`, `vitest.setup.ts`) regardless of what the prompt asked for. If the prompt explicitly limits scope (e.g. "skip any features or integrations", "just scaffold and build X", "no need to install dependencies") and Phase 2 and/or Phase 3 are consequently skipped, remove the scaffold pieces those phases would have owned before Phase 4 runs:
- **Phase 3 skipped** → delete `codegen.yml`, `.graphqlrc.yml`, `src/api/graphqlClient.ts`, `graphql:schema`/`graphql:codegen` scripts from `package.json`, and any `hooks/` data-fetching stubs (e.g. `useAsyncData.ts`) the template pre-seeded.
- **Neither testing nor deployment requested** → leave `playwright.config.ts`/`vitest.*` only if the prompt implies testing; otherwise remove them too.
- Rewrite `README.md` to describe the actual app built, not the generic template boilerplate — or delete it if the prompt says to do minimal work only.
**Deleting a file is only half the job — every reference to it must be removed in the same pass, or you trade over-generation for broken cross-file consistency (worse: a dangling import is a functional break, not just scope creep).** Concretely, after deleting any of the above:
-`vite.config.ts` — remove the `vite-plugin-graphql-codegen` import and its `codegen({ configFilePathOverride: ... })` plugin block if `codegen.yml` was deleted; remove the `test:` config block (`setupFiles`, `coverage`, etc.) if `vitest.*` was deleted.
-`package.json` — remove now-unused dependencies (`vite-plugin-graphql-codegen`, `@graphql-codegen/*`, `playwright`, `vitest`, etc.) and their npm scripts, not just the config files.
- Any component/page that imports a deleted hook, client, or shadcn component (e.g. `useAsyncData`, `graphqlClient`) must have that import and its usage removed or replaced — never leave an import pointing at a file that no longer exists.
- Do NOT re-add a file you just deleted elsewhere in the same pass (e.g. deleting `codegen.yml` while still emitting `.graphqlrc.yml`) — decide scope once per concern and apply it consistently across every file that touches that concern.
- Before finishing Phase 4, run `scripts/check-dangling-refs.sh <deleted-basename>` for each deleted file and report any errors it returns.
Installs pre-built, tested feature packages. See "Prompt Classification Keywords" above for the full trigger keyword list and negative-phrasing handling — these features provide the foundation that UI components build on top of.
Only skip this phase if the app is truly a minimal "hello world" with no interactive features (no trigger keywords present at all).
*(Re-fetches schema from the deployed org -- required because the remote schema may differ from the local one used in Phase 3. Guard against an empty or stale result -- Salesforce Edge caching can briefly serve the pre-deploy schema; re-fetch/retry before trusting it as empty and before running codegen)*
Creates the Digital Experience site that hosts the UI bundle. Use when the user wants a public-facing or authenticated site URL for external users. **Note**: The `<target>ExperienceSite</target>` was already set in meta XML during Phase 1.
Creates a Custom Application entry in the Lightning App Launcher. Use when the app is for internal users accessing it within Lightning Experience. **Note**: The `<target>CustomApplication</target>` was already set in meta XML during Phase 1.
6. Determine hosting target (Experience Site OR Custom Application) — see "Prompt Classification Keywords" above; if ambiguous, ask user to clarify before proceeding
**Before proceeding to Output (Build Plan), validate:**
- [ ]**No conflicting requirements detected** — if conflicts exist (see action #8 above), STOP and report:
```text
ERROR: Conflicting requirements detected:
- [describe the specific conflict, e.g., "The prompt requires 'no authentication' while also requiring a 'My Cases' view scoped to the current user's identity"]
RESOLUTION NEEDED: Please clarify:
- [specific question, e.g., "Should the app require login (removing the 'no authentication' requirement), or should all data be public (removing the user-scoped view)?"]
```
**Do NOT proceed to build plan generation or any phase execution until this conflict is resolved.**
- New objects/fields: [list any object the org does not already have, with its fields -- delegate to platform-custom-object-generate, not authored here]
- Grounding: [verify each object + its fields against the org via experience-ui-bundle-salesforce-data-access BEFORE authoring — list the objects/fields to confirm, not assumed-correct names]
- Queries: [GraphQL queries to author FROM the verified names]
- REST endpoints: [only where GraphQL/uiapi genuinely cannot cover it — not as a fallback for fields that were hard to verify]
0. experience-ui-bundle-project-generate (offer a prebuilt template first; if chosen, Phase 1 scaffolding is skipped; if declined, run the Bootstrap check for an existing SFDX project -- no skill load required)
2.5. platform-custom-object-generate (if the prompt requires a new custom Salesforce object the org doesn't have -- MUST complete and deploy before step 3)
Execute each phase sequentially following the standard pattern in `references/phase-execution-pattern.md`. **CRITICAL: Always load the skill before executing.** Skipping or reordering phases produces broken apps.
- Load `experience-ui-bundle-project-generate`, offer templates. If chosen: skip Phase 1, continue at Phase 4. If declined: run `scripts/check-sfdx-project.sh`, create project if missing.
- Load `experience-ui-bundle-metadata-generate`. Determine hosting target FIRST. Run `sf template generate ui-bundle --template reactbasic`, configure meta XML with `<target>`.
Before proceeding to STEP 3 (Final Summary), validate that all required phases were executed. See `references/phase-completion-validation.md` for the full critical/warning checklist and exact error/warning text to report.
- [ ]**Hosting target resolved and deployed**: Meta XML contains `<target>ExperienceSite</target>` or `<target>CustomApplication</target>` (never left unset), and the matching Phase 7a or 7b infrastructure was generated and deployed -- not skipped
- [ ]**Data layer wired**: Components use the `@salesforce/platform-sdk` Data SDK (`createDataSDK().graphql`), with all entities/fields grounded against the org — not guessed (if data access phase was executed)
Never build UI before installing features. Never deploy before building. Dependencies are strict.
### 2. Replace All Boilerplate
Every generated app must feel purpose-built. Replace "React App" titles, "Vite + React" placeholders, and all default content with real app-specific text and branding.
### 3. Design with Intent
Follow the design thinking and frontend aesthetics guidance from `experience-ui-bundle-frontend-generate`. Every app should have a clear visual direction -- not generic defaults.