App Builder Project Initialization
Maps user intent to the right Adobe App Builder template and runs non-interactive aio app init. Default: @adobe/generator-app-excshell (SPA + actions). For headless/bare projects, use init-bare.
When a Developer Console project / workspace / API subscription does not yet exist, this skill walks the agent through creating them non-interactively by calling aio console … directly — see the Bootstrap section and references/bootstrap.md. The latest @adobe/aio-cli bundle exposes non-interactive aio console project create / workspace create / api list / workspace api add (with --license-config for services that require a product profile), and non-interactive aio app init --org/--project/--template-options. Together they remove every blocking "open the Developer Console UI and click" step from the agentic setup path. Just install the latest CLI (npm install -g @adobe/aio-cli) and use them.
Bootstrap the Developer Console (project, workspace, APIs)
If the user is starting from zero — no Developer Console project yet, or an existing project that is missing a workspace or API subscription — bootstrap that state before aio app init. Otherwise aio app init / aio app use / aio app deploy have nothing to wire the local app to.
The full bootstrap is just aio commands; call them directly, not through a wrapper script. They are already non-interactive in the recent plugin releases, and per-step calls let you react to "already exists" or "needs a product profile" responses without baking those decisions into bash.
Preflight
Make sure the CLI is current — that's what brings in the non-interactive Console + app init commands:
npm install -g @adobe/aio-cli
aio --version
Don't try to assert specific plugin versions; just take the latest. If a console or app subcommand below is rejected as "command not found" or "unknown flag" after this, the CLI install genuinely failed (PATH issue, permissions, registry mirror) — fix the install rather than working around it.
Confirm an org is selected (or pass --orgId on every command below):
aio console org list --json # if needed, then:
aio console org select <orgId>
Decision rule
| User state | Next action |
|---|---|
| "Create a project + workspace + add APIs from scratch" | Run the bootstrap chain (project → workspace → APIs), then aio app init. |
| Project exists, workspace missing | Skip project-create. Run aio console workspace create, then optionally aio console workspace api add. |
| Project + workspace exist, only need to add an API | Run aio console api list to discover service codes, then aio console workspace api add. |
| Everything already wired | Skip bootstrap. Go straight to Initialize via Script. |
Always check what already exists with aio console project list --json and aio console workspace api list --projectName <p> --workspaceName <w> --json before creating — these commands fail loudly on "already exists" and there is no built-in idempotency.
The bootstrap chain (raw commands)
Step 1 — create the Console project:
aio console project create -n my-project --json
# optional: -t "Title" -d "Description" -o <orgId>
Step 2 — create a workspace inside it (Stage is the conventional first non-Production workspace; pick a more descriptive name in long-lived shared projects):
aio console workspace create \
--projectName my-project \
--name Stage \
--json
# optional: --orgId <orgId> --title "Stage workspace"
Step 3 — discover and subscribe the APIs the app needs:
aio console api list --json # see all service codes available to the org
# entries flagged for whether they need a product profile
# Free-tier service:
aio console workspace api add \
--projectName my-project \
--workspaceName Stage \
--service-code AdobeIOManagementAPISDK \
--json
# Service that requires a product profile:
aio console workspace api add \
--projectName my-project \
--workspaceName Stage \
--service-code AdobeAnalyticsSDK \
--license-config AdobeAnalyticsSDK=AnalyticsProductionProfile \
--json
--service-code accepts a comma-separated list to subscribe several free-tier services in one call. --license-config is repeatable when several profile-bound services are added together.
Recover from per-step failures
| Failure | What to do |
|---|---|
project create fails with "already exists" |
Read aio console project list --json, reuse the existing project's name, and continue at step 2. |
workspace create fails with "already exists" |
List workspaces with aio console workspace list --projectName <p> --json and continue at step 3. |
workspace api add returns "product profile required" |
The service code requires --license-config. Ask the user (or the org admin) for the profile name and retry with --license-config CODE=PROFILE. |
| Any step returns an org-selection error | Pass --orgId <id> explicitly, or aio console org select <id> once before retrying. |
Wire the local app to the bootstrapped state
Two equivalent ways to point a fresh aio app init at the project/workspace you just created:
Pass them as flags to
inititself (cleanest):skills/adobe/appbuilder-project-init/scripts/init.sh init \ "@adobe/generator-app-excshell" ./my-project \ --org <orgId> --project my-projectThe wrapper passes
--org/--project/--template-optionsstraight through toaio app init, on top of the existing-y --no-login --no-installflags.Run
aio app useafter init (works on any plugin version):cd ./my-project aio app use --no-input # adopts the currently selected project/workspace, no prompts
Either route ends with the local .aio and .env pointing at the workspace you just bootstrapped, so aio app deploy publishes to the right namespace.
Fast Path (for clear requests)
When the user's intent maps unambiguously to a single template — for example, they name a template directly or describe an app that clearly matches exactly one entry below — skip straight to Initialize via Script below. Use the matched template and any project name the user provided (or a sensible default).
Examples of fast-path triggers:
- "Create an App Builder app using
@adobe/generator-app-excshell" → use that template, run init - "Set up an Asset Compute worker" → maps unambiguously to
@adobe/generator-app-asset-compute, run init - "Create a new App Builder app" (no specifics) → defaults to
@adobe/generator-app-excshell, run init - "Initialize a bare project" → use
init-bare, run init
If there is any ambiguity — multiple templates could fit, or the user's constraints are unclear — use the full template decision table and workflow below.
Template Decision Table
Pick the template that matches the user's intent. When unclear, default to @adobe/generator-app-excshell.
| User wants | Template |
|---|---|
| SPA with actions + React UI | @adobe/generator-app-excshell |
| AEM Content Fragment Console extension | @adobe/aem-cf-admin-ui-ext-tpl |
| AEM React SPA (WKND-based) | @adobe/generator-app-aem-react |
| Adobe API Mesh (GraphQL) | @adobe/generator-app-api-mesh |
| Asset Compute custom worker | @adobe/generator-app-asset-compute |
| Remote server on App Builder | @adobe/generator-app-remote-mcp-server-generic |
| Bare / from-scratch project (no pre-scaffolded actions or UI) | init.sh init-bare |
For a headless/backend-only request, prefer init-bare when possible. If the user still needs a template that generates UI files, plan a post-init cleanup so the final project has no web-src frontend directory or web manifest wiring.
Initialize via Script
The aio app * wrappers go through a single script: scripts/init.sh. (Console bootstrap commands are called directly — see the Bootstrap section above for the rationale.)
Note: In this snapshot the scripts live at
skills/adobe/appbuilder-project-init/scripts/. Other installs may use.cursor/plugins/…,.augment/skills/, or.github/skills/— adjust the prefix, but keep theadobe/segment.
With a template:
skills/adobe/appbuilder-project-init/scripts/init.sh init "@adobe/generator-app-excshell" ./my-project
With a template, fully wired to a specific Console org/project (no post-init aio app use needed):
skills/adobe/appbuilder-project-init/scripts/init.sh init \
"@adobe/generator-app-excshell" ./my-project \
--org <orgId> --project my-project
--org, --project, --template-options (base64-encoded JSON), and --no-config-validation are passed straight through to aio app init. Use the latest @adobe/aio-cli so they're all recognised; --no-config-validation is the escape hatch for the rare case where a partial scaffold shouldn't yet have to pass schema validation.
Bare project (no template):
skills/adobe/appbuilder-project-init/scripts/init.sh init-bare ./my-project
Use init-bare only when the user explicitly wants to configure everything from scratch. In that case, "bare" means the generated project should stay minimal:
app.config.yamlexists with an empty or minimalapplication.runtimeManifestpackage.jsonexists with only the basic project dependencies- No pre-scaffolded
src/,web-src/, oractions/directories
Why this matters: if the user asked for a bare project, pre-generated actions or web assets contradict that intent and remove the clean starting point they requested.
The script outputs JSON with success, path, and output fields. Check success before proceeding.
Full Workflow (for ambiguous or complex requests)
Step 1 — Gather intent
Ask the user (or infer from conversation context):
| Question | Examples |
|---|---|
| What type of app? | SPA shell, headless API, AEM extension, Asset Compute worker, API Mesh, remote server |
| Needs a UI? | Yes (React Spectrum in ExC Shell), No (actions only) |
| Extension point? | dx/excshell/1, aem/cf-console-admin/1, dx/asset-compute/worker/1, or N/A |
| Additional actions? | Names and purposes of custom actions beyond the default |
| Console state? | Existing project + workspace? Or do we need to create them and subscribe APIs first? |
| APIs needed? | e.g. Adobe I/O Management, Analytics, Target — including any that require a product profile |
If the user simply says "create an App Builder app" with no specifics, default to @adobe/generator-app-excshell.
If the Console state is "from scratch" or unknown, run the Bootstrap the Developer Console flow before continuing to template selection. See references/bootstrap.md for the full agentic bootstrap playbook.
Step 2 — Select template
Consult the Template Decision Table above and references/templates.md to map the user's intent to a template.
Step 3 — Initialize, customize, validate
Follow the Initialize via Script, Post-init customization, and Validate sections below.
Post-init Customization
Consult references/templates.md for template-specific post-init guidance. Common tasks:
- Install dependencies — Run
npm installin the project directory. The init script uses--no-installto keep initialization fast, but dependencies are required before building or testing. - For API Mesh projects, verify
mesh.jsonis at the project root — Afteraio app initwith@adobe/generator-app-api-mesh, confirm./mesh.jsonexists before treating the scaffold as ready. If the file only exists atnode_modules/@adobe/generator-app-api-mesh/templates/mesh.json, copy it into place withcp node_modules/@adobe/generator-app-api-mesh/templates/mesh.json ./mesh.json. The file undernode_modules/is the generator's template source, not the project's active API Mesh configuration. Then customize the rootmesh.jsonwith the user's real source handlers; for multi-backend scenarios, configure at least two handlers. - Clean up bare-project scaffolding if needed — After
init-bare, inspect the generated project. If the initializer createdactions/,src/, orweb-src/, remove those directories before continuing. A bare project should not keep auto-generated action code or web assets. - Headless cleanup after template init — If the user wants a headless project with no frontend, delete any generated UI directory after
aio app init:rm -rf web-src/or the template-specific path such asrm -rf src/<extension>/web-src/. Then remove matchingweb-srcconfig fromapp.config.yamlorext.config.yamlif present, especiallyweb: web-srcandoperations.view/impl: index.htmlentries. This avoids unnecessary frontend build artifacts and stale manifest wiring in a backend-only project. - Add actions — If the user later wants custom actions, run
cd ./my-project && skills/adobe/appbuilder-project-init/scripts/init.sh add-action "my-action". - Add web assets — Only if the user later decides the bare project needs a UI, run
skills/adobe/appbuilder-project-init/scripts/init.sh add-web-assets. - Edit ext.config.yaml directly — Customize action definitions:
- Set
runtime: nodejs:22for production. Stage workspaces also acceptruntime: nodejs:24. - Add
inputs:for environment variables the action needs - Set
annotations.require-adobe-auth: trueif the action needs IMS tokens - Set
web: 'yes'orweb: 'raw'depending on HTTP access needs
- Edit app.config.yaml — For multi-extension projects, add
$includeentries. - Apply action boilerplate — Use the
appbuilder-action-scaffolderskill's boilerplate pattern for production-ready action code with logging, input validation, and error handling.
Validate
Verify the project structure by checking these items directly:
app.config.yamlexists and contains valid YAML- All
$includepaths resolve to real files ext.config.yaml(if present) hasruntimeManifest.packageswith at least one action- Action JS files exist at all declared
function:paths package.jsonexists withname,version, and an Adobe SDK dependency (@adobe/aio-sdkor@adobe/aio-lib-core-logging)- No root-level
runtimeManifestinapp.config.yaml(see Manifest guardrail below)
Read the relevant files and verify each check. Fix any issues before proceeding.
Build, Test, Deploy (optional)
If the user wants to go beyond scaffolding:
aio app build # Build
aio app test # Run tests
aio app deploy # Deploy to Adobe I/O Runtime
aio app dev # Run locally for development (use `aio app run` instead if actions use State SDK, Files SDK, or sequences)
Manifest guardrail
Extension projects: Actions are defined under runtimeManifest in ext.config.yaml, referenced via $include from app.config.yaml.
Standalone apps: Actions go under application.runtimeManifest in app.config.yaml.
Do not place a root-level runtimeManifest directly in app.config.yaml: the CLI ignores those actions, so they will not deploy. If you see this shape, move it under application.runtimeManifest or into ext.config.yaml.
Troubleshooting & Edge Cases
aioCLI not installed: Ifaio --versionreturnscommand not foundor fails, stop before initialization. Ask the user to install Adobe I/O CLI, completeaio auth login, and retry only after the CLI is available.npm installfails after init: The scaffold can still be created because init runs with--no-install, but builds/tests will fail until dependencies install cleanly. Capture the first package error, confirm the Node/npm version is compatible, rerunnpm installfrom the project root, and only continue once it succeeds.- Template choice is ambiguous: If the request could map to multiple templates, ask one clarifying question about UI vs headless, extension point, or target Adobe product. If the user has no preference, default to
@adobe/generator-app-excshelland state that assumption explicitly. - Project directory already exists or is not empty: Do not overwrite it silently. Ask whether to use a different directory, clear the existing folder, or initialize into a new path.
aio console …subcommand or flag not recognised: Almost always means the CLI bundle is stale. Runnpm install -g @adobe/aio-cliand retry — that's the supported way to refresh every plugin (console, app, runtime, ims-oauth, telemetry). Only dig deeper if the same command still fails after a clean reinstall.- Workspace API add fails with "product profile required": The service code needs a product profile. Re-run
aio console api list --jsonto confirm, ask the user (or org admin) for the profile name, and retry with--license-config CODE=PROFILE. - No org selected: Console bootstrap commands will fail with an org-selection error. Run
aio console org listthenaio console org select <orgId>(or pass--orgIdto every command) before retrying. - Validation errors from a freshly scaffolded but partially edited project: Recent
aio app *versions validateapp.config.yamlby default against an OpenWhisk-aligned schema. The validation runs on everyaio app *command that reads or writes the manifest — concretely:aio app init,aio app add (action|web-assets|extension|event|service),aio app delete (action|web-assets|extension|event|service),aio app build,aio app deploy,aio app undeploy,aio app run,aio app dev,aio app use, andaio app info. The escape hatch flag is the same on all of them:--no-config-validation. Use it on the single command you need to unblock (e.g.aio app build --no-config-validationwhile you're still mid-refactor), then drop it as soon as the manifest is whole. Don't bake it into scripts — silent drift between local config and the deployed shape is exactly what the validator was added to catch. - Template listing hangs behind a corporate proxy: Older CLI bundles didn't honour
HTTP_PROXY/HTTPS_PROXYduring the template registry SSL handshake. Runnpm install -g @adobe/aio-clito pick up the proxy fix, confirmHTTPS_PROXYis exported in the same shell, and retry.
Chaining with other skills
After initialization, hand off to:
appbuilder-action-scaffolder— For scaffolding actions with playbook, checklist, boilerplate templates, and manifest validationappbuilder-ui-scaffolder— Build React Spectrum UI for ExC Shell SPAs and AEM extensions
Pattern Quick-Reference
| Task | Reference | Command |
|---|---|---|
| Bootstrap Console project + workspace + APIs | references/bootstrap.md | aio console project create → aio console workspace create → aio console workspace api add |
| Discover org's available APIs | references/bootstrap.md | aio console api list --json |
| Subscribe an existing workspace to an API | references/bootstrap.md | aio console workspace api add --service-code … [--license-config …] |
| Initialize an App Builder project from a template | references/templates.md | scripts/init.sh init |
| Wire local app to a Console workspace post-init | references/bootstrap.md | scripts/init.sh init … --org … --project … or aio app use --no-input |
| Debug project init issues | references/debugging.md | — |
References
- references/bootstrap.md — Agentic Developer Console bootstrap (project, workspace, API subscriptions) via raw
aio console …commands from the latest@adobe/aio-cli - references/templates.md — Template catalog with intent mapping and per-template post-init guidance
- references/debugging.md — Troubleshooting guide for init failures, Node/npm issues, login problems, and first-run errors