Imported from EmpoweredHouse/process-native-starter (
src/AGENTS.md). Install upstream withnpx skills add EmpoweredHouse/process-native-starter --skill src. Copyright stays with the author.
src/AGENTS.md
Scoped guide for editing the pns CLI itself.
Layout
index.ts— Commander entry point. Registersinitandvalidate.commands/init.ts— argument parsing, buildsTemplateVars, walksALL_STEPS.commands/validate.ts— auto-detects repo root by walking up looking for.ai/, then runslib/validate.ts.lib/steps.ts— the 10-step bootstrap pipeline (ALL_STEPSarray, executed in order).lib/template.ts—overlayTemplatesrecursive walker +__KEY__substitution.lib/discovery.ts— Phase 2 artifact seeding into.ai/reference/.lib/prerequisites.ts— tool version checks (step 1).lib/validate.ts— harness structure validator (@references, AGENTS.md/CLAUDE.md/lessons.md).lib/log.ts— chalk-coloured output helpers (log.step,log.success, etc.).templates/— files overlaid into generated projects. Excluded from tsconfig. Treated as opaque text/binary byoverlayTemplates.
The 10-step pipeline (lib/steps.ts)
Steps 1-5 shell out to upstream tools and must not be reordered:
step1CheckPrerequisites— fail fast ifelixir,mix,bun,node,git,psqlmissing.step2GeneratePhoenix—mix phx.new --umbrella --database postgres --install. Quirk: generator creates<otp_app>_umbrella/, step renames totargetDir. The--installflag is intentional — accepts the deps prompt up front so the run doesn't block on TTY.step3InitGsd—npx @opengsd/get-shit-done-redux@latest.step4InitAccrete—npx -y github:appunite/accrete init. Pulled from GitHub, not npm — the npm name is a stale placeholder.step5InstallSkills—npx skills initthennpx skills add <repo> --skill <name> -yfor each. The-yis load-bearing — without it, non-TTY invocations (CI, smoke) silently no-op.step6OverlayHarness— callsoverlayTemplates(templateDir, targetDir, vars)then copiesseed/state-template.md(with var substitution) andseed/config.jsonto<target>/.planning/.step7SeedDiscovery— optional. If--discovery-dirgiven, copies artifacts into<target>/.ai/reference/AND appends domain context toseed/foundation-prompt.mdin the starter repo itself (smoke snapshots and restores this).step8InitGsdSdk— currently a no-op marker; GSD SDK config happens on firstgsd-sdk init.step9StandardizeBun— runsbun installinapps/<otp_app>_web/assets/if apackage.jsonexists. Phoenix 1.7+ ships assets withoutpackage.json(esbuild/tailwind via Hex), so this typically skips.step10GitCommit—git init(if needed),git add -A, commit.
Adding a step: append to ALL_STEPS and bump TOTAL_STEPS. Each step receives the same StepContext (targetDir, vars, templateDir, seedDir, discoveryDir?).
Overlay rules (lib/template.ts)
- Never overwrite.
if (fs.existsSync(destPath)) { log.info("Skipping..."); continue; }. This is the contract that lets templates layer onto upstream output. - Substitution applies to file contents AND filenames/dirnames — naive
String.replaceAllover__KEY__. So a template path likeapps/__OTP_APP__/lib/foo.exresolves correctly. - Binary files (extensions in
BINARY_EXTENSIONS) are copied without substitution. - Don't change a Phoenix-generated file via
templates/— it'll be skipped because it already exists. Patch it in a step instead.
Template variables — keep these in sync
TemplateVars in src/lib/template.ts and PLACEHOLDER_KEYS in tests/e2e/lib/constants.ts must list the same keys. The validate-no-placeholder-leaks test relies on this.
User-supplied keys come from commands/init.ts flags. Derived keys (__OTP_APP_WEB__, __MODULE_NAME_WEB__, __ASSETS_DIR__, __DATE__) are computed in init.ts — not flags.
templates/ — what goes there
Files that should be overlaid onto every generated project, regardless of upstream tooling:
AGENTS.md,CLAUDE.md,QUICKSTART.md— the harness.coveralls.json— coverage config.e2e/— Playwright skeleton withpackage.json,playwright.config.ts,tests/.scripts/—check-decisions.sh,check-deps.shfor CI gates.
These are not part of the TypeScript build. tsconfig excludes them. Treat them as opaque overlay payload.
Build / typecheck / test
bun run build # bun build src/index.ts --outdir dist --target node
bun run dev -- init … # run from source, no rebuild needed
No standalone lint. Strict-mode tsc is implicit via bun build. The eval suite (tests/e2e/) is the only test layer; it runs against bootstrapped projects in $SMOKE_DIR, not against src/.
To debug a single bootstrap step, run bun run dev -- init against a temp dir and inspect the result.