| applyTo | ** |
|---|---|
| excludeAgent | code-review |
Skill reference: for the full architectural layer map, type-first design patterns, CLI option conventions, render sub-module extension playbook and test strategies read
.github/skills/feature.mdfirst.
Follow these steps when implementing a new feature in this repository.
- Read the issue description and acceptance criteria carefully.
- Identify which modules will host the new logic (check
src/types.ts,AGENTS.mdand existing modules for context). - If the feature introduces a new shared type, add it to
src/types.tsbefore touching anything else. - If the feature touches the CLI surface, the entry point is
github-code-search.ts(Commander subcommands).
| Layer | Location | Rule |
|---|---|---|
| Shared types | src/types.ts |
All new interfaces go here |
| Pure business logic | src/aggregate.ts, src/group.ts, src/render/ |
Pure functions only — no I/O |
| Output formatting | src/output.ts |
Markdown and JSON renderers |
| Rendering façade | src/render.ts |
Re-export new sub-module symbols here |
| API calls | src/api.ts |
Only place allowed to call GitHub REST API |
| TUI interaction | src/tui.ts |
Only place allowed to read stdin / write to TTY |
| CLI parsing | github-code-search.ts |
Commander options and subcommands |
| Auto-upgrade | src/upgrade.ts |
Binary self-replacement logic |
Never mix pure logic with I/O. If a new feature requires both, split it: write a pure function in the appropriate module and call it from api.ts, tui.ts or github-code-search.ts.
If the feature introduces a new rendering concern (e.g. a new display component):
- Create
src/render/<name>.tswith pure functions. - Export the new symbols from
src/render.ts(the façade). - Import from
src/render.tsin consumers — never directly fromsrc/render/<name>.ts.
- Create or update
src/<module>.test.ts(co-located with the source file). - Use
describe/it/expectfrom Bun's built-in test runner. - Tests must be self-contained: no network calls, no filesystem side effects.
- Cover edge cases: empty arrays, undefined/null guards, boundary values.
- Run
bun testto verify the full suite passes before considering the implementation done.
- If a new CLI option or subcommand is added, update
README.md(usage section, options table, examples). - If a new flag requires additional GitHub token scopes, document them in
README.mdandAGENTS.md.
Before opening the pull request, ensure every item passes:
bun test # all tests green
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:
feat/<short-description>(e.g.feat/json-output-type). - Commit message: imperative mood, e.g.
Add --output-type flag for JSON format. - 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: motivation, what changed, how to test manually.
Once the PR is merged into main, publish a minor (new feature) or major (breaking change) release:
bun pm version minor # new feature: 1.2.4 → 1.3.0
# or
bun pm version major # breaking change: 1.2.4 → 2.0.0
git checkout -b release/$(jq -r .version package.json)
git add package.json
git commit -S -m "v$(jq -r .version package.json)"
git tag v$(jq -r .version package.json)
git push origin release/$(jq -r .version package.json) --tagsThe tag push triggers cd.yaml which builds all-platform binaries and creates the GitHub Release automatically.
For minor and major releases, also write the blog post before pushing the tag:
- Create
docs/blog/release-v<X-Y-Z>.mdwith feature highlights - Add a row in
docs/blog/index.md
See the full release guide in AGENTS.md § Release process.