Appearance
FAQ
Setup & initialization
Should I modify files in scripts/setup-core/?
No. scripts/setup-core/ is managed via git subtree from the webentor-setup package. Any changes you make will be lost on the next subtree update. Instead:
- Put feature toggles in
scripts/.env.setup - Put lifecycle logic in
scripts/hooks/<hook>.sh - Put reusable helpers in
scripts/project-specific/
See Overriding Setup Scripts for examples.
Where does scripts/ come from?
The starter template ships with no scripts/ directory. All setup scaffolding is generated by webentor-setup init after adding setup-core as a git subtree. See Setup & Init for the full flow.
Where do I add custom setup logic?
- Feature toggles →
scripts/.env.setup - Per-step logic →
scripts/hooks/<hook-name>.sh - Reusable helpers →
scripts/project-specific/ - Project-wide one-off scripts →
scripts/project-specific/
Can I use the stack without 1Password?
Yes. When webentor-setup init prompts "Use 1Password for .env?", answer n. Or pass --with-1password false to skip the prompt. You can also set it later in scripts/.env.setup:
dotenv
SETUP_1PASSWORD=false
SETUP_ENV_CHECK=falseThen manage your .env file manually. You can copy .env.example to .env and fill in values yourself, or fetch them from another secrets manager.
What is .webikon/project.json for?
It declares the project's identity for tooling that inspects the repo. It is created by webentor-setup init and holds four required fields plus one optional — nothing else:
json
{
"schema_version": 2,
"slug": "my-project",
"stack": "webentor-v2",
"theme_path": "web/app/themes/webentor-theme-v2",
"setup_cli_version": "1.1.0"
}slug— stable project identifier (a directory name is not one)stack— one ofwebentor-v2,webentor-v2-hybrid,webentor-v1,sage,classic. Project layout (Bedrock vs classic) is never encoded here; it is detected at runtime instead.theme_path— the theme that consumeswebentor-coresetup_cli_version— optional; see below
It caches exactly one version, deliberately. The retired v1 file (.webentor/project.json) recorded starterVersion, coreVersion, configsVersion, setupCliVersion and the setup toggles, and every one of them went stale the moment a package was updated without re-running init. Those facts are now read from the artifact that owns each one:
webentor-coreversion → the theme'svendor/composer/installed.jsonorcomposer.lock(core is a dependency of the theme, not of the project root)- starter release → root
composer.jsonversion @webikon/webentor-configsversion → the theme'snode_modules,pnpm-lock.yaml, orpackage.json- setup CLI version →
scripts/setup-core/composer.jsonversionwhen readable, otherwise thesetup_cli_versiondeclaration (see below) - DB sync / Typesense / 1Password toggles →
scripts/.env.setup. Nothing outside the checkout reads these, and no tooling acts on them. - PHP, WordPress, and theme versions → the WordPress runtime
Why setup_cli_version is the exception. Its artifact — scripts/setup-core/composer.json — lives under scripts/, which is deploy-excluded, so a deployed site cannot read it at all. The declaration carries the value across the deploy boundary. "Must not be derivable" therefore has a sharper reading than it looks: derivable in the repo is not derivable from a deployed site, and a reporter running against production only ever sees the latter.
init writes the field by mirroring that composer.json, and never substitutes the running CLI's own version — so a project with no scripts/setup-core/ (a hybrid, a plain Sage or classic project) gets no field, and must not have one added by hand. Because it is declared rather than derived, it is the one field that can go stale: a git subtree pull of setup-core moves the artifact without touching the declaration. webentor-setup doctor compares the two and exits 1 on mismatch, printing the exact fix, and webikon:update-webentor-packages-in-project blocks the update until they agree. Always fix the declaration to match the artifact, never the reverse.
It is not read by the bash setup runtime. Re-running init rewrites it but never overwrites a hand-set stack (pass --stack <value> to change it) and deletes .webentor/project.json if it is still there. stack, theme_path and setup_cli_version are the only fields worth correcting by hand.
What does webentor-setup doctor check?
doctor verifies that the minimum required tools are installed, that the project metadata file exists, and that its one declared version is current:
phpavailable in PATHcomposeravailable in PATHpnpmavailable in PATHwp(WP-CLI) available in PATH (optional)scripts/.env.setupexists.webikon/project.jsonexistssetup_cli_versionmatchesscripts/setup-core/composer.json— exit 1 on mismatch, or when the field is declared with no setup-core present.n/awhen the project has no setup-core and declares nothing.
Run it with:
bash
scripts/setup-core/bin/webentor-setup doctorRun it after every git subtree pull of setup-core — that is the operation that moves the artifact without touching the declaration.
Upgrading
How do I update setup-core to a newer version?
The webentor-setup remote already exists from the initial subtree add. Pull the new tag:
bash
git subtree pull \
--prefix=scripts/setup-core \
webentor-setup \
vX.Y.Z \
--squashA subtree pull is a two-part change: bump setup_cli_version in .webikon/project.json to match the new scripts/setup-core/composer.json in the same commit. Otherwise webentor-setup doctor exits 1 and the maintenance dashboard keeps reporting the old version, since production reads the declaration.
Validate the pull, then commit it. See Starter Upgrades for the full process.
For code changes a webentor-core update requires in your theme, run the matching codemod — pnpm dlx @webikon/webentor-codemods list.
webentor-core
How do I override a block provided by webentor-core?
Register your own block with the same name in your theme. WordPress uses the last registered version. Alternatively, use the webentor/skip_render_block_blade filter to bypass the Blade rendering pipeline for a specific block and render it yourself.
How do I use Cloudinary for images?
See the Cloudinary Integration guide.
Development
What PHP version is required?
PHP 8.3 or newer. The herd.yml and Dev Container configs target PHP 8.3.
What Node version is required?
Node 20 LTS or newer. The theme package.json specifies "node": ">=20".
What package manager should I use?
pnpm version 10.15.1 or newer (specified in root package.json).