# Code Style & Gotchas > Part of [AGENTS.md](../AGENTS.md) โ€” project guidance for AI coding agents. ## Code Style - **install.js:** CommonJS, Node.js built-ins only (no external deps), ANSI colors via `COLORS` constant, readline-based prompts - **plan2code-loop & plan2code-metrics:** TypeScript + ESM, built with tsup (target ES2022, moduleResolution: bundler) - External deps: `@inquirer/prompts`, `chalk`, `execa`, `ora` - Interactive CLI via `@inquirer/prompts` (select, input, confirm) - **File operations:** Synchronous fs in all packages ## Gotchas / Pitfalls - **Version sync:** When adding a new version to `CHANGELOG.md`, also update `version.json` and `package.json` (root) to match. Check `README.md` for any version badges or references that need updating. The installer displays the version from `version.json` in its header. All three files (`CHANGELOG.md`, `version.json`, `package.json`) must always show the same version number. - **CHANGELOG ordering:** Entries in `CHANGELOG.md` must be in reverse-chronological order โ€” newest version at the top, oldest at the bottom. New entries are always inserted immediately after the file header. - **CHANGELOG house format is not Keep a Changelog:** version headings are `## vX.Y.Z` โ€” with a `v` prefix and **no date**. The release date is recorded only in `version.json`'s `releaseDate`. Category headings carry emoji: `### โœจ Added`, `### ๐Ÿ”ง Changed`, `### ๐Ÿ› Fixed`, `### ๐Ÿ’ฅ Breaking`, `### ๐Ÿ—‘๏ธ Removed`, `### ๐Ÿ“š Documentation`. Older entries contain one-off variants (`๐ŸŽ Added`, `๐Ÿ“ฆ Updated`, `๐Ÿ“ Documentation`, `๐ŸŽ๏ธ Improved`, `๐Ÿงช Testing`) โ€” do not introduce new ones. The `.claude/skills/plan2code-changelog/` skill automates version selection and formatting; use it rather than hand-rolling an entry. - **PowerShell mangles the CHANGELOG emoji:** `Get-Content` / `Select-String` render the `###` heading emoji as `?` under the default Windows console encoding, so a heading audit done that way reports garbage. Read `CHANGELOG.md` with a file-read or grep tool instead. - **`.claude/skills/` is tracked, not ignored:** repo-local skills (`plan2code-changelog`, `plan2code-publish`, `sync-repo`) live there and are committed. Nothing in `.gitignore` touches `.claude/`, so a new skill only needs `git add`. Per the Failure Log convention in `AGENTS.md`, a correction that is a *workflow* rather than a rule belongs here as a skill, linked from AGENTS.md โ€” not as a Failure log line. - **Loop `.gitignore` setup:** `ensureGitignore()` runs at startup in `Controller.run()` as a pre-flight step, not just inside `createTaskCommit()`. This is critical for phase mode where the Node controller doesn't handle commits โ€” without it, `git add -A` would stage spec files. - **Workflow file character limit:** All `src/plan2code-*.md` files must be โ‰ค 11,000 characters. A husky pre-commit hook enforces this. The limit predates v2.2.0's single-format skill build and is retained as prompt-size discipline; generated `SKILL.md` files add a small YAML header. - **`skills/` is a committed build artifact:** edit `src/`, run `npm run build:skills`, and commit the regenerated skills in the same change. `npm test` runs `install.js --verify-skills` and fails on missing, unexpected, or stale files. Never edit `skills/` by hand. - **Metrics internal prompts have no char limit:** Files in `plan2code-metrics/src/prompts/` are NOT subject to the 11,000 char limit โ€” only `src/plan2code-*.md` consumer-facing prompts are. - **User Feedback table format:** The `## User Feedback` markdown table in `overview.md` has a strict format the collector regex depends on. Field names must be exactly `Rating`, `Reason`, `Went Well`, `Went Poorly`. Pipe characters in values must be escaped as `\|`. - **PLAN-DRAFT confidence numbers are scraped by regex:** when a `specs//PLAN-DRAFT-*.md` contains no `` comment, `collector.ts` falls back to prose scraping (`collector.ts:186-241`). The overall-confidence pattern requires a literal `%`, but the four *breakdown* patterns (`collector.ts:201-204`) do **not** โ€” `/[Rr]equirements?[:\s|]+(\d{1,2})/` and its siblings match a bare dimension word followed by whitespace, a colon, or a pipe and then digits. So a PLAN-DRAFT written by anything other than `/plan2code-1-plan` Phase 7 must keep both the `%` sign **and** bare `Requirements` / `Feasibility` / `Integration` / `Risk` followed by a number off the page โ€” including innocent table rows like `| Requirements | 11 |`. Otherwise the metrics pipeline records a planning-step confidence that no planning step produced. `/plan2code-0-pathfinder` works around this by hyphenating the labels (`Requirements-clarity 22/25`), which breaks the character class. - **Reference file sizing guideline:** Files in `src/plan2code-*-references/` directories target ~100-200 lines each (soft guideline; evaluate splitting above 300). They are NOT subject to the 11,000 character limit. The pre-commit hook (`validate-char-count.js`) only checks `src/plan2code-*.md` flat files โ€” subdirectory contents are automatically excluded. - **The splitting guideline has a hard ceiling โ€” reference files cannot always be split:** each new reference costs the orchestrator a `Read references/.md` line plus its fallback blockquote (~150-200 chars), and orchestrators near the 11,000 limit have no room to spend. References now stay nested under every generated skill, so the old flat-file path-rewrite constraint no longer applies. When a reference legitimately exceeds 300 lines (e.g. `plan2code-0-pathfinder-references/chart.md`), that is an accepted trade-off, not an oversight.