After brmbh create client-site, the folder is named correctly and WordPress activates it — but the theme still identifies itself as the starter everywhere inside. Nothing in create personalizes the copied files.
Orientation
This repo is the CLI. The theme it scaffolds lives in a separate repo (THEME_REPO in src/registry.js:13).
node bin/brmbh.js help
# scaffold from a local theme checkout, no network:
node bin/brmbh.js create demo --from ../brmbh-agentic-wp-suite
Relevant flow: bin/brmbh.js → dispatch() in src/tool.js → src/commands/create.js. Step 2 of create calls materializeTheme() (src/registry.js), which either copies a local checkout or shallow-clones and deletes .git. After that the files are simply left as they came.
Current behaviour
The starter's identity survives verbatim:
style.css header → Theme Name: brmbh Agentic WP Suite, Text Domain: brmbh-agentic-wp-suite, plus a Theme URI pointing at the starter repo
package.json → "name": "brmbh-agentic-wp-suite", plus repository / homepage pointing at the starter
- The text domain string
brmbh-agentic-wp-suite appears 65 times across 25 files in the theme
Those 25 files fall into three groups, and they need different treatment:
Rewrite (real theme code — 20 files):
404.php, footer.php, functions.php, header.php, index.php, page.php, single.php, style.css, package.json, assets/src/scss/style.scss, inc/block-patterns.php, inc/bootstrap-nav-walker.php, inc/cli.php, inc/dependencies.php, inc/footer-menus.php, inc/gutenberg.php, inc/scaffold.php, inc/template-functions.php, my-acf-blocks/loader.php, my-acf-blocks/example-hero/block.json, template-parts/branding/site-logo.php
Judgement call: AGENTS/create-block.md and skills/wordpress/SKILL.md reference the text domain as the value agents should use when generating new blocks. If these are not updated, every block an agent generates later reintroduces the starter's text domain. They probably should be rewritten too.
Leave alone: README.md (the starter's own docs — arguably should be deleted from the scaffold entirely), tools/env/production.env.example and tools/env/staging.env.example (these use the string as a deploy path/dir hint; check what it means before touching), package-lock.json (regenerated by npm install in step 3 anyway).
A blind repo-wide find/replace is therefore not the right implementation.
Why it matters
- Appearance → Themes shows "brmbh Agentic WP Suite" on every client site.
- Two brmbh-derived themes on one install share a text domain, so their translation strings collide.
- Every new project starts with the same manual find/replace across 20+ files.
Proposed fix
Add a personalization step to src/commands/create.js between step 2 (materialize) and step 3 (npm install — important, since it rewrites package.json).
- Rewrite the
style.css header block: Theme Name → titleCase(slug), Text Domain → slug, reset Version to 0.1.0, drop or blank Theme URI.
- Rewrite
package.json: name → slug, drop repository / homepage / description.
- Replace the text domain string across the "rewrite" file list above.
- Delete the starter's own meta files from the scaffold (
README.md, CLAUDE.md, LICENSE?) — decide which.
Helpers that already exist: slugify(), titleCase(), readText(), writeText(), render() in src/fsutil.js. UI methods for reporting: ui.step() / ui.ok() / ui.warn() (src/ui.js).
Report the result through the existing envelope — e.g. add personalized: { themeName, textDomain, filesRewritten } to the object returned by run(), so --json consumers see it.
Design question worth deciding now: hardcode the old text domain in the CLI, or let the theme repo declare it? A brmbh.template.json in the starter (listing its own text domain, the files to rewrite, the files to delete) means improving the starter never requires a CLI release. Hardcoding is fine for v1, but the constant will silently rot if the starter ever renames itself.
Acceptance
node bin/brmbh.js create acme-site --from ../brmbh-agentic-wp-suite --skip-install
grep -r "brmbh-agentic-wp-suite" acme-site --exclude-dir=node_modules # → no hits in theme code
head -20 acme-site/style.css # → Theme Name: Acme Site / Text Domain: acme-site
Theme still builds (npm install && npm run build) and activates cleanly in WordPress.
After
brmbh create client-site, the folder is named correctly and WordPress activates it — but the theme still identifies itself as the starter everywhere inside. Nothing increatepersonalizes the copied files.Orientation
This repo is the CLI. The theme it scaffolds lives in a separate repo (
THEME_REPOinsrc/registry.js:13).Relevant flow:
bin/brmbh.js→dispatch()insrc/tool.js→src/commands/create.js. Step 2 ofcreatecallsmaterializeTheme()(src/registry.js), which either copies a local checkout or shallow-clones and deletes.git. After that the files are simply left as they came.Current behaviour
The starter's identity survives verbatim:
style.cssheader →Theme Name: brmbh Agentic WP Suite,Text Domain: brmbh-agentic-wp-suite, plus aTheme URIpointing at the starter repopackage.json→"name": "brmbh-agentic-wp-suite", plusrepository/homepagepointing at the starterbrmbh-agentic-wp-suiteappears 65 times across 25 files in the themeThose 25 files fall into three groups, and they need different treatment:
Rewrite (real theme code — 20 files):
404.php,footer.php,functions.php,header.php,index.php,page.php,single.php,style.css,package.json,assets/src/scss/style.scss,inc/block-patterns.php,inc/bootstrap-nav-walker.php,inc/cli.php,inc/dependencies.php,inc/footer-menus.php,inc/gutenberg.php,inc/scaffold.php,inc/template-functions.php,my-acf-blocks/loader.php,my-acf-blocks/example-hero/block.json,template-parts/branding/site-logo.phpJudgement call:
AGENTS/create-block.mdandskills/wordpress/SKILL.mdreference the text domain as the value agents should use when generating new blocks. If these are not updated, every block an agent generates later reintroduces the starter's text domain. They probably should be rewritten too.Leave alone:
README.md(the starter's own docs — arguably should be deleted from the scaffold entirely),tools/env/production.env.exampleandtools/env/staging.env.example(these use the string as a deploy path/dir hint; check what it means before touching),package-lock.json(regenerated bynpm installin step 3 anyway).A blind repo-wide find/replace is therefore not the right implementation.
Why it matters
Proposed fix
Add a personalization step to
src/commands/create.jsbetween step 2 (materialize) and step 3 (npm install — important, since it rewritespackage.json).style.cssheader block:Theme Name→titleCase(slug),Text Domain→slug, resetVersionto0.1.0, drop or blankTheme URI.package.json:name→slug, droprepository/homepage/description.README.md,CLAUDE.md,LICENSE?) — decide which.Helpers that already exist:
slugify(),titleCase(),readText(),writeText(),render()insrc/fsutil.js. UI methods for reporting:ui.step()/ui.ok()/ui.warn()(src/ui.js).Report the result through the existing envelope — e.g. add
personalized: { themeName, textDomain, filesRewritten }to the object returned byrun(), so--jsonconsumers see it.Design question worth deciding now: hardcode the old text domain in the CLI, or let the theme repo declare it? A
brmbh.template.jsonin the starter (listing its own text domain, the files to rewrite, the files to delete) means improving the starter never requires a CLI release. Hardcoding is fine for v1, but the constant will silently rot if the starter ever renames itself.Acceptance
Theme still builds (
npm install && npm run build) and activates cleanly in WordPress.