|
| 1 | +# github-code-search — Agent instructions |
| 2 | + |
| 3 | +This file provides context for AI coding agents (GitHub Copilot, Claude, Gemini, etc.) working in this repository. |
| 4 | + |
| 5 | +## What this project does |
| 6 | + |
| 7 | +`github-code-search` is an interactive CLI (powered by [Bun](https://bun.sh)) to search GitHub code across an organisation. It aggregates results per repository, displays a keyboard-driven TUI and lets the user select extracts before printing structured markdown or JSON output. A `query` subcommand and an `upgrade` subcommand are exposed via [Commander](https://github.com/tj/commander.js). |
| 8 | + |
| 9 | +## Runtime & toolchain |
| 10 | + |
| 11 | +| Tool | Version | |
| 12 | +|------|---------| |
| 13 | +| **Bun** | ≥ 1.0 (runtime, bundler, test runner, package manager) | |
| 14 | +| **TypeScript** | via Bun (no separate `tsc` invocation needed at runtime) | |
| 15 | +| **oxlint** | linter (`bun run lint`) | |
| 16 | +| **oxfmt** | formatter (`bun run format`) | |
| 17 | +| **knip** | dead-code detector (`bun run knip`) | |
| 18 | + |
| 19 | +There is **no Node.js / npm** involved. Always use `bun` commands. |
| 20 | + |
| 21 | +## Bootstrap |
| 22 | + |
| 23 | +```bash |
| 24 | +bun install # install dependencies (reads bunfig.toml + package.json) |
| 25 | +``` |
| 26 | + |
| 27 | +`bunfig.toml` sets `smol = true` (lighter install). No additional setup step is needed. |
| 28 | + |
| 29 | +## Build commands |
| 30 | + |
| 31 | +```bash |
| 32 | +bun run build.ts # compile a self-contained binary → dist/github-code-search |
| 33 | +bun run build.ts --target=bun-darwin-arm64 # cross-compile (see CONTRIBUTING.md for all targets) |
| 34 | +``` |
| 35 | + |
| 36 | +The build script (`build.ts`) injects the git commit SHA, target OS and architecture into the binary. The produced binary has no runtime dependency and can be distributed as a single file. |
| 37 | + |
| 38 | +## Running tests |
| 39 | + |
| 40 | +```bash |
| 41 | +bun test # run the whole test suite |
| 42 | +bun test --watch # re-run on file changes (development) |
| 43 | +``` |
| 44 | + |
| 45 | +All tests use Bun's built-in test runner (`@jest/globals`-compatible API: `describe`, `it`, `expect`). No additional testing library is needed. The setup file is `src/test-setup.ts` (referenced in `bunfig.toml`). |
| 46 | + |
| 47 | +## Linting & formatting |
| 48 | + |
| 49 | +```bash |
| 50 | +bun run lint # oxlint — must pass before submitting |
| 51 | +bun run format # oxfmt write (auto-fix) |
| 52 | +bun run format:check # oxfmt check (CI check) |
| 53 | +bun run knip # detect unused exports / files |
| 54 | +``` |
| 55 | + |
| 56 | +Always run `bun run lint` and `bun run format:check` before considering a change complete. |
| 57 | + |
| 58 | +## Project layout |
| 59 | + |
| 60 | +``` |
| 61 | +github-code-search.ts # CLI entry point — Commander subcommands: query, upgrade |
| 62 | +build.ts # Build script (Bun.build) |
| 63 | +bunfig.toml # Bun configuration (smol install, test preload) |
| 64 | +tsconfig.json # TypeScript configuration |
| 65 | +knip.json # knip (dead-code) configuration |
| 66 | +
|
| 67 | +src/ |
| 68 | + types.ts # All shared TypeScript interfaces (TextMatchSegment, |
| 69 | + # TextMatch, CodeMatch, RepoGroup, Row, TeamSection, |
| 70 | + # OutputFormat, OutputType) |
| 71 | + api.ts # GitHub REST API client (search, team fetching) |
| 72 | + aggregate.ts # Result grouping & filtering (applyFiltersAndExclusions) |
| 73 | + group.ts # groupByTeamPrefix — team-prefix grouping logic |
| 74 | + render.ts # Façade re-exporting sub-modules + top-level |
| 75 | + # renderGroups() / renderHelpOverlay() |
| 76 | + tui.ts # Interactive keyboard-driven UI (navigation, filter mode, |
| 77 | + # help overlay, selection) |
| 78 | + output.ts # Text (markdown) and JSON output formatters |
| 79 | + upgrade.ts # Auto-upgrade logic (fetch latest GitHub release, replace binary) |
| 80 | +
|
| 81 | + render/ |
| 82 | + highlight.ts # Syntax highlighting (language detection + token rules) |
| 83 | + filter.ts # FilterStats + buildFilterStats |
| 84 | + rows.ts # buildRows, rowTerminalLines, isCursorVisible |
| 85 | + summary.ts # buildSummary, buildSummaryFull, buildSelectionSummary |
| 86 | + selection.ts # applySelectAll, applySelectNone |
| 87 | +
|
| 88 | + *.test.ts # Unit tests co-located with source files |
| 89 | + test-setup.ts # Global test setup (Bun preload) |
| 90 | +``` |
| 91 | + |
| 92 | +## Key architectural principles |
| 93 | + |
| 94 | +- **Pure functions first.** All business logic lives in pure, side-effect-free functions (`aggregate.ts`, `group.ts`, `output.ts`, `render/` sub-modules). This makes them straightforward to unit-test. |
| 95 | +- **Side effects are isolated.** API calls (`api.ts`), TTY interaction (`tui.ts`) and CLI parsing (`github-code-search.ts`) are the only side-effectful surfaces. |
| 96 | +- **`render.ts` is a façade.** It re-exports everything from `render/` and adds two top-level rendering functions. Consumers import from `render.ts`, not directly from sub-modules. |
| 97 | +- **`types.ts` is the single source of truth** for all shared interfaces. Any new shared type must go there. |
| 98 | +- **No classes** — the codebase uses plain TypeScript interfaces and functions throughout. |
| 99 | + |
| 100 | +## Writing tests |
| 101 | + |
| 102 | +- Test files are named `<module>.test.ts` and sit next to their source file. |
| 103 | +- Use `describe` / `it` / `expect` from Bun's test runner. |
| 104 | +- Only pure functions need tests; `tui.ts` and `api.ts` are not unit-tested. |
| 105 | +- When adding a function to an existing module, add the corresponding test case in the existing `<module>.test.ts`. |
| 106 | +- When creating a new module that contains pure functions, create a companion `<module>.test.ts`. |
| 107 | +- Tests must be self-contained: no network calls, no filesystem side effects. |
| 108 | + |
| 109 | +## Development notes |
| 110 | + |
| 111 | +- **TypeScript throughout** — no `.js` files in `src/`. |
| 112 | +- Bun executes `.ts` files directly; no transpilation step is needed to run the CLI locally (`bun github-code-search.ts query ...`). |
| 113 | +- The `--exclude-repositories` and `--exclude-extracts` options accept both short (`repoName`) and long (`org/repoName`) forms — this normalisation happens in `aggregate.ts`. |
| 114 | +- The `--group-by-team-prefix` option requires a `read:org` GitHub token scope; this is documented in `README.md`. |
| 115 | +- The `upgrade` subcommand replaces the running binary in-place using `src/upgrade.ts`; be careful with filesystem operations there. |
| 116 | +- `picocolors` is the only styling dependency; do not add `chalk` or similar. |
| 117 | +- Keep `knip` clean: every exported symbol must be used; every import must resolve. |
0 commit comments