| applyTo | ** |
|---|---|
| excludeAgent | code-review |
Skill reference: for architectural invariants, safe rename playbook, module extraction patterns, characterisation test strategy and
knipoutput interpretation read.github/skills/refactoring.mdfirst.
Follow these steps when refactoring existing code in this repository.
A good refactoring task has a clearly bounded scope. Before making any change, identify:
- Which module(s) are affected (consult
AGENTS.mdfor the layer map). - Whether the public API (exported symbols, CLI options) is changing or staying the same.
- Whether the refactoring is purely internal (no behavior change) or also simplifies the API.
Prefer behaviour-preserving refactorings. If the public API must change, document it explicitly in the PR.
This codebase enforces a strict layering:
- Pure functions must stay pure — do not introduce side effects (I/O, global state,
Date.now(),Math.random()) intoaggregate.ts,group.ts,output.ts, orrender/sub-modules. - I/O is isolated in
api.ts,tui.tsandgithub-code-search.ts. Keep it there. render.tsis a façade — if you move or rename symbols inrender/, update the re-exports inrender.tsaccordingly.types.tsis the single source of truth — if you merge or rename interfaces, update all usages across the codebase.
Before touching code:
bun test # baseline — all tests must be green before you startIf the area you are refactoring lacks tests, add tests before refactoring (characterisation tests). This ensures you can verify the refactoring is behaviour-preserving.
- Refactor one logical unit at a time (one function, one module boundary).
- Run
bun testafter each meaningful step to catch regressions early. - Avoid mixing a refactoring with a feature addition in the same commit; separate concerns.
If you rename an exported function, type or constant:
- Update every import site across the codebase — use a global search before renaming.
- Update
render.tsif the renamed symbol is re-exported there. - Update
src/types.tsif it's a shared type. - Run
bun run knipto detect any forgotten reference.
Every exported symbol must be used. After a refactoring:
bun run knip # zero unused exports / importsRemove dead code rather than leaving it commented out.
bun test # full suite passes — same behaviour before and after
bun run lint # oxlint — zero errors
bun run format:check # oxfmt — no formatting diff
bun run knip # no unused exports or imports
bun run build.ts # binary compiles without errors- Branch name:
refactor/<short-description>(e.g.refactor/extract-filter-module). - Commit message: imperative mood, e.g.
Extract FilterStats helpers into render/filter.ts. - All commits must be signed (GPG or SSH). Configure once with
git config --global commit.gpgsign true. Commits pushed via the GitHub API (Copilot Coding Agent, MCP tools) are automatically Verified by GitHub. - PR description: what was restructured, why, and a note confirming no behaviour change.