Skip to content

fix(create-bestax): scaffold polish — ship .gitignore (with *.tsbuildinfo), PM-aware next steps, strictPort recovery guidance - #506

Merged
allxsmith merged 6 commits into
mainfrom
fix/create-bestax-scaffold-polish-371
Aug 13, 2026
Merged

allxsmith merged 6 commits into
mainfrom
fix/create-bestax-scaffold-polish-371

Conversation

@allxsmith

@allxsmith allxsmith commented Aug 12, 2026 •

Copy link
Copy Markdown
Owner

Three scaffold-polish items from the 10-run skill-loop eval (#363), all in create-bestax.

1. Ship a scaffold .gitignore (via rename-on-copy) and ignore *.tsbuildinfo

npm strips literal .gitignore files from published tarballs, so although both templates tracked one, apps scaffolded from the registry shipped with no .gitignore at all. The templates now track _gitignore and copyDirectory renames it back on copy (fs.move with overwrite: true, keyed by a TEMPLATE_RENAMES map).

Both ignore files also gain *.tsbuildinfo, and the vite-ts template redirects tsBuildInfoFile into node_modules/.tmp (mirroring what tsconfig.node.json already did) as belt and braces.

Eval evidence: run i09 burned ~7 diagnosis turns on a stale-buildinfo TS5083 after a pnpm add, and its artifact shipped with the buildinfo committed — both impossible once the buildinfo lives under node_modules and is ignored anyway.

2. Print next steps for the invoking package manager

display.ts hardcoded pnpm install / pnpm dev even though the scaffold is deliberately PM-agnostic (.claude/launch.json uses npm run dev for exactly that reason). The success screen now detects the invoking PM from npm_config_user_agent (falling back to npm) and prints <pm> install / <pm> run dev — a shape valid for all four supported PMs. The template README's pnpm commands are deliberately untouched (out of scope for this pass).

3. strictPort port-collision recovery guidance

--strictPort stays — a busy 5173 must fail loudly, not point the browser preview at nothing. What was missing is what to do next: eval run i04 hit exactly this collision when an orphaned dev server from an earlier session owned the port. The generated CLAUDE.md now names that cause and the recovery — kill the orphan (lsof -ti:5173 | xargs kill) and relaunch, never move the app to another port. LAUNCH_JSON is byte-identical; the AI development docs guide gets the same note.

Testing

  • pnpm --filter create-bestax test: 8 suites, 222 tests green; coverage 98.36% statements / 89.16% branches / 100% functions / 98.30% lines (thresholds 95/78/95/95).
  • npm pack --dry-run: templates/vite/_gitignore and templates/vite-ts/_gitignore both appear in the tarball file list.
  • e2e: scaffolded a real app with the built CLI and ran the Playwright suite against its preview server with --ignore-snapshots — 10/10 pass (the visual baselines are Linux-only by design and update via the CI workflow). The e2e scaffold helper now hard-fails if a scaffold lacks .gitignore, alongside the existing launch.json guard.
  • Manual smoke outside the repo: both templates' output contains .gitignore with *.tsbuildinfo (and no _gitignore residue); npm_config_user_agent="pnpm/…" flips next steps to pnpm, unset falls back to npm.
  • pnpm all: green.

Closes #371

Summary by CodeRabbit

  • New Features

    • Generated projects now include a standard .gitignore file.
    • TypeScript build information is ignored and stored in a temporary directory.
    • Setup instructions now adapt installation and development commands to npm, pnpm, Yarn, or Bun.
  • Bug Fixes

    • Improved guidance for resolving port 5173 conflicts by identifying and stopping orphaned development servers instead of changing ports.
  • Documentation

    • Updated AI development guidance to reflect the improved port conflict recovery process.

…gnore *.tsbuildinfo

npm strips literal .gitignore files from published tarballs, so the
templates' tracked .gitignore never reached published scaffolds — apps
created from the registry got no .gitignore at all. Track the file as
_gitignore instead and have copyDirectory rename it back on copy.

Both ignore files also gain *.tsbuildinfo so an incremental tsc run can
never commit its build info, and the vite-ts template redirects
tsBuildInfoFile into node_modules/.tmp (mirroring tsconfig.node.json)
as belt and braces. The e2e scaffold helper now hard-fails if a real
scaffold lacks .gitignore.

Refs #371
The success screen hardcoded pnpm commands even when the CLI was run
via npm, yarn, or bun. Detect the invoking package manager from
npm_config_user_agent (falling back to npm) and print `<pm> install` /
`<pm> run dev`, a shape valid for all four supported PMs.

Refs #371
…nerated CLAUDE.md

When 5173 is busy, --strictPort makes the dev server fail loudly by
design — but the generated CLAUDE.md never said what to do next, and
an agent's natural workaround (moving the app to another port) points
the browser-preview manifest at nothing. Tell agents the usual cause
is an orphaned dev server from an earlier session and give the exact
recovery (lsof -ti:5173 | xargs kill, then relaunch). LAUNCH_JSON
itself is unchanged.

Closes #371
…uide

Mirror the recovery guidance the scaffolder now writes into generated
CLAUDE.md files: a busy 5173 usually means an orphaned dev server, and
the fix is killing it, not moving the app to another port.
Copilot AI balanced review requested due to automatic review settings August 12, 2026 19:27
@coderabbitai

coderabbitai Bot commented Aug 12, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ddb1cecb-4bc3-4efb-9edb-6ee2054cc65b

📥 Commits

Reviewing files that changed from the base of the PR and between 1b7eca3 and b5a3692.

📒 Files selected for processing (3)
  • create-bestax/src/__tests__/constants.test.ts
  • create-bestax/src/constants.ts
  • docs/docs/guides/getting-started/ai-development.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • create-bestax/src/tests/constants.test.ts
  • docs/docs/guides/getting-started/ai-development.md
  • create-bestax/src/constants.ts

Walkthrough

The scaffold detects the invoking package manager, converts _gitignore templates to .gitignore, ignores TypeScript build artifacts, verifies scaffold output, and documents recovery for port 5173 conflicts.

Changes

Scaffold polish

Layer / File(s) Summary
Package-manager-aware next steps
create-bestax/src/package-manager.ts, create-bestax/src/display.ts, create-bestax/src/__tests__/package-manager.test.ts, create-bestax/src/__tests__/display.test.ts
Package-manager detection supports npm, pnpm, yarn, and bun. Success output uses the detected package manager.
Template output and build artifacts
create-bestax/src/file-system.ts, create-bestax/src/project-creator.ts, create-bestax/templates/*, create-bestax/src/__tests__/file-system.test.ts, create-bestax/src/__tests__/project-creator.test.ts, create-bestax/e2e/utils/scaffold.ts
Template copying renames _gitignore to .gitignore, verifies the generated file, and ignores *.tsbuildinfo.
Strict-port recovery guidance
create-bestax/src/constants.ts, create-bestax/src/__tests__/constants.test.ts, docs/docs/guides/getting-started/ai-development.md
Generated guidance and documentation identify orphaned servers on port 5173 and provide a termination command.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Mergeability Score: ⚪ Minimal · up to b5a36

The PR improves generated project files, package-manager-specific next steps, and strict-port recovery guidance without a supplied actionable merge-blocking risk; it is merge-ready after normal checks and review.

Possibly related PRs

Suggested labels: released, documentation

Suggested reviewers: bestaxbot

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the three main scaffold changes: .gitignore support, package-manager-aware commands, and strictPort recovery guidance.
Description check ✅ Passed The description provides a detailed change summary, affected package, linked issue, testing evidence, and additional implementation context.
Linked Issues check ✅ Passed The changes satisfy issue #371 by adding build-info ignores, package-manager-aware commands, and listener-scoped strictPort recovery guidance.
Out of Scope Changes check ✅ Passed The implementation and related tests and documentation remain within the three scaffold-polish objectives defined by issue #371.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/create-bestax-scaffold-polish-371

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Polishes create-bestax scaffolds with reliable ignore files, package-manager-aware next steps, and port-collision guidance.

Changes:

  • Restores .gitignore during template copying and relocates TypeScript build metadata.
  • Detects npm, pnpm, Yarn, or Bun for displayed commands.
  • Documents strict-port recovery and expands automated coverage.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
docs/docs/guides/getting-started/ai-development.md Documents port-collision recovery.
create-bestax/templates/vite/_gitignore Ignores TypeScript build metadata.
create-bestax/templates/vite-ts/_gitignore Ignores TypeScript build metadata.
create-bestax/templates/vite-ts/tsconfig.json Relocates build metadata under node_modules.
create-bestax/src/project-creator.ts Configures template-file renaming.
create-bestax/src/package-manager.ts Detects the invoking package manager.
create-bestax/src/file-system.ts Adds post-copy renaming support.
create-bestax/src/display.ts Prints package-manager-specific commands.
create-bestax/src/constants.ts Adds strict-port recovery guidance.
create-bestax/src/__tests__/project-creator.test.ts Verifies rename configuration.
create-bestax/src/__tests__/package-manager.test.ts Tests package-manager detection.
create-bestax/src/__tests__/file-system.test.ts Tests file renaming behavior.
create-bestax/src/__tests__/display.test.ts Tests generated next steps.
create-bestax/src/__tests__/constants.test.ts Tests collision guidance.
create-bestax/e2e/utils/scaffold.ts Requires scaffolded .gitignore.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +208 to +210
If 5173 is already taken, the usual cause is an orphaned dev server from an earlier session;
the generated CLAUDE.md tells agents to kill it (`lsof -ti:5173 | xargs kill`) rather than
move ports. See the [LLMs guide](/docs/guides/llms) for the full AI tooling story.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b5a3692 — the guide now mirrors the listener-scoped command (lsof -tiTCP:5173 -sTCP:LISTEN | xargs kill), matching the generated CLAUDE.md guidance updated in 5fe5397.

Comment thread create-bestax/src/constants.ts Outdated
Comment on lines +222 to +224
the command. \`--strictPort\` failing because 5173 is busy means an orphaned dev server from an
earlier session owns the port — kill it (\`lsof -ti:5173 | xargs kill\`) and relaunch; don't
move the app to another port.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5fe5397 — the generated guidance now uses lsof -tiTCP:5173 -sTCP:LISTEN | xargs kill, which selects only the listening process, so connected clients (e.g. the preview browser) can no longer be caught. On confirming orphan-hood first: the listener on the app's own strict port is the dev server in practice, and the guidance stays deliberately terse; an agent that wants to inspect can run the same lsof invocation without -t.

@github-actions

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://3c3f71e0.bestax.pages.dev

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
create-bestax/src/__tests__/constants.test.ts (1)

245-253: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Update the assertion with the safer recovery command.

The test currently requires lsof -ti:5173 | xargs kill. After the production guidance is narrowed to the TCP listener, assert the listener-only command and keep the orphaned-server wording check.

This follows the cross-layer contract between CLAUDE_MD and the generated scaffold.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@create-bestax/src/__tests__/constants.test.ts` around lines 245 - 253, Update
the test for CLAUDE_MD in the strictPort collision case to assert the safer
TCP-listener-only recovery command instead of the current broad lsof command,
while retaining the --strictPort and orphaned dev server assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@create-bestax/src/constants.ts`:
- Around line 222-224: The strict-port recovery guidance must identify only the
TCP listener orphaned dev server before terminating it. Update
create-bestax/src/constants.ts lines 222-224 to use listener-only discovery,
verify the PID, and kill only that process; update
create-bestax/src/__tests__/constants.test.ts lines 245-253 to assert the safe
command; and mirror the same guidance in
docs/docs/guides/getting-started/ai-development.md lines 208-210.

---

Nitpick comments:
In `@create-bestax/src/__tests__/constants.test.ts`:
- Around line 245-253: Update the test for CLAUDE_MD in the strictPort collision
case to assert the safer TCP-listener-only recovery command instead of the
current broad lsof command, while retaining the --strictPort and orphaned dev
server assertions.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 2058f30e-b5ca-4021-b985-a494333306e7

📥 Commits

Reviewing files that changed from the base of the PR and between 39b8271 and 1b7eca3.

📒 Files selected for processing (15)
  • create-bestax/e2e/utils/scaffold.ts
  • create-bestax/src/__tests__/constants.test.ts
  • create-bestax/src/__tests__/display.test.ts
  • create-bestax/src/__tests__/file-system.test.ts
  • create-bestax/src/__tests__/package-manager.test.ts
  • create-bestax/src/__tests__/project-creator.test.ts
  • create-bestax/src/constants.ts
  • create-bestax/src/display.ts
  • create-bestax/src/file-system.ts
  • create-bestax/src/package-manager.ts
  • create-bestax/src/project-creator.ts
  • create-bestax/templates/vite-ts/_gitignore
  • create-bestax/templates/vite-ts/tsconfig.json
  • create-bestax/templates/vite/_gitignore
  • docs/docs/guides/getting-started/ai-development.md

Comment thread create-bestax/src/constants.ts Outdated
@allxsmith
allxsmith requested review from bestaxbot and a balanced review from Copilot August 12, 2026 22:30

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deep review — 0 blocking · 1 advisory

# Severity Area Finding Location
1 🔵 Advisory Robustness The strictPort recovery command shipped to every generated CLAUDE.md is Unix-only (lsof -ti:5173 | xargs kill); an agent following it literally on Windows fails, though the substantive guidance ("kill the orphan, don't move ports") still lands. create-bestax/src/constants.ts:223

Overall: The change is sound and cleanly scoped to three small, independent polish items in create-bestax. The riskiest piece — the _gitignore rename-on-copy — is the standard CRA/Vite workaround for npm stripping literal .gitignore from tarballs, and it is implemented correctly: copyDirectory's new renames param is optional and guarded, TEMPLATE_RENAMES is only threaded through copyTemplate, fs.move uses overwrite: true, and _gitignore (not stripped) ships via the package's files: ["templates"]. PM detection and <pm> run dev are valid across all four supported managers, and the guidance changes are docs-only. Nothing urgent for the human here — 222 tests pass and the logic held up under inspection.

Residual risk: the "scaffold ships without .gitignore" failure class could still recur only if —

  • a new dotfile template (e.g. .npmrc, .env.example) gets added later: npm would strip it too and there is no automated check that a .-prefixed template file has a matching TEMPLATE_RENAMES entry. Refuted for now — the only dotfile in either template dir is _gitignore, and the e2e scaffold.ts guard hard-fails if .gitignore regresses. Worth keeping in mind if more dotfiles get templated.
  • the copy path silently no-ops: refuted — the rename is existsSync-guarded and unit-tested for present/absent/omitted cases, and _gitignore is tracked in git and lands via files: ["templates"].
  • *.tsbuildinfo leaks anyway: refuted — the real buildinfo comes from tsconfig.node.json (composite: true), already redirected under node_modules/.tmp, and both ignore files now list *.tsbuildinfo. The added tsBuildInfoFile on the main tsconfig.json is a harmless no-op today (no incremental/composite + noEmit) — defensible belt-and-braces, not a defect.

🏄 Mellow little clean-up set, dude — patched the missing .gitignore leak, made the next-steps mirror whatever PM paddled in, and left a note to stop bailing to a new port when 5173's clogged. No gnarly wipeouts in the lineup, tests all glassy green. Ship it. 🌊

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated no new comments.

Suppressed comments (2)

create-bestax/src/constants.ts:223

  • lsof -ti:5173 matches every TCP/UDP socket involving this port, not just the listener, so an existing browser connection can add the browser PID to xargs kill. A collision also does not prove that the listener is orphaned. Have the agent inspect the listener first and, once confirmed, target only lsof -tiTCP:5173 -sTCP:LISTEN; keep the mirrored docs and test expectation in sync.
the command. \`--strictPort\` failing because 5173 is busy means an orphaned dev server from an
earlier session owns the port — kill it (\`lsof -ti:5173 | xargs kill\`) and relaunch; don't

docs/docs/guides/getting-started/ai-development.md:209

  • This recovery command is broader than the text claims: lsof -ti:5173 can return client and UDP processes in addition to the listening server, and piping those PIDs to kill may terminate unrelated applications. Document inspection of the owner first and restrict the eventual lookup to lsof -tiTCP:5173 -sTCP:LISTEN, synchronized with the generated CLAUDE.md guidance.
If 5173 is already taken, the usual cause is an orphaned dev server from an earlier session;
the generated CLAUDE.md tells agents to kill it (`lsof -ti:5173 | xargs kill`) rather than

…tener

A plain lsof -ti:5173 matches every socket touching the port — clients
with 5173 as their remote endpoint included — so an agent following the
generated guidance could kill the preview browser along with the orphan.
lsof -tiTCP:5173 -sTCP:LISTEN selects only the listening dev server.

Refs #371
Keep the AI development guide in sync with the generated CLAUDE.md:
the recovery kill targets only the TCP listener on 5173, not every
process with a socket touching the port.
Copilot AI review requested due to automatic review settings August 13, 2026 00:27
@allxsmith

Copy link
Copy Markdown
Owner Author

Review follow-up, all threads addressed:

  • Listener-scoped recovery command (Copilot inline x2, CodeRabbit inline + nitpick): real issue — lsof -ti:5173 also matches clients whose remote endpoint is 5173, so the kill could take out the preview browser. Fixed in 5fe5397 (generated CLAUDE.md + the constants test assertion, per the nitpick) and b5a3692 (docs guide mirror). The command is now lsof -tiTCP:5173 -sTCP:LISTEN | xargs kill.
  • Deep review advisory (Unix-only lsof): acknowledged, deliberately unchanged. The environments Claude Code runs in (macOS, Linux, WSL) all ship lsof; a PowerShell variant for native Windows would roughly double the paragraph in every generated CLAUDE.md for a rare case, and the platform-neutral instruction — kill the orphan, never move ports — still lands as the review itself notes.

@github-actions

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://42cb5d2b.bestax.pages.dev

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated no new comments.

@allxsmith
allxsmith merged commit 494106a into main Aug 13, 2026
63 checks passed
@allxsmith
allxsmith deleted the fix/create-bestax-scaffold-polish-371 branch August 13, 2026 02:11
@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 5.10.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 4.1.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 2.0.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 1.0.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] create-bestax: scaffold polish — gitignore *.tsbuildinfo, PM-neutral next-steps, strictPort fallback

2 participants