|
| 1 | +<!-- GitHub Copilot / AI agent instructions for `gh-wrapped-cli` --> |
| 2 | + |
| 3 | +# Brief |
| 4 | + |
| 5 | +This file gives targeted, actionable guidance for an AI coding agent working on the `gh-wrapped-cli` repository (GitHub Wrapped CLI). Focus on the files and patterns listed below — they capture the app's architecture, developer flows, and important platform/OS quirks. |
| 6 | + |
| 7 | +**Why this matters:** the app is a CLI + image-exporter that fetches GitHub data, analyzes it, renders a terminal UI (Ink) and optionally exports images (Satori → Sharp/Resvg). Many behaviors are implemented by coordinating multiple files (data fetch → analysis → UI → export worker). |
| 8 | + |
| 9 | +**Quick facts** |
| 10 | +- **Runtime:** ESM + TypeScript (built to run under Bun; Node used for the export worker) |
| 11 | +- **Preferred runner:** `bun` (recommended in `README.md`) — use `bun install`, `bun run build`, `bun run dev`, `bun start` |
| 12 | +- **Key dirs/files:** `src/index.tsx`, `src/ui.tsx`, `src/github.ts`, `src/github-graphql*.ts`, `src/analytics.ts`, `src/export.ts`, `src/export-worker.mjs`, `src/types.ts`, `src/fonts/` |
| 13 | + |
| 14 | +**Commands** |
| 15 | +- Install deps: `bun install` (or `npm install`) |
| 16 | +- Dev (hot reload with Bun): `bun run dev` |
| 17 | +- Build: `bun run build` |
| 18 | +- Run locally: `bun start` or `bunx github-wrapped-2025` |
| 19 | + |
| 20 | +**Important runtime notes** |
| 21 | +- Exports use a Node worker (`src/export-worker.mjs`) invoked via file-based IPC (temp JSON files). This is intentional to avoid Bun + WASM and Windows pipe issues — do not replace this with a naive child pipe without handling the Windows case. |
| 22 | +- Fonts used for exports live in `src/fonts/PressStart2P-Regular.ttf` and are loaded as ArrayBuffer for Satori. |
| 23 | +- The app supports `GITHUB_TOKEN` env var and an interactive token prompt (see `src/ui.tsx` and `README.md`). |
| 24 | + |
| 25 | +**Architecture & data flow (high level)** |
| 26 | +- Entry: `src/index.tsx` — detects username from git config and calls `GitHubWrappedApp` (Ink render). The Ink render is a long-lived single render (never unmounts). |
| 27 | +- Data layer: `src/github.ts` (Octokit REST client) and `src/github-graphql*.ts` (GraphQL client). Use REST for repository & commit listings; GraphQL holds richer queries (e.g., lines changed). |
| 28 | +- Analysis: `src/analytics.ts` (streaks, top languages, archetype, achievements). When adding metrics, update types in `src/types.ts` and keep analyzer pure. |
| 29 | +- UI: `src/ui.tsx` — multiple “slides” and input flows. Prefer adding isolated components (e.g., new slide components) and keep animation hooks stable (note: the repo currently returns immediate values to avoid re-render loops). |
| 30 | +- Export: `src/export.ts` orchestrates Satori rendering and uses `src/export-worker.mjs` to produce PNG/SVG via Sharp/Resvg in Node. The export writes temp input/output files and reads results — respect that IPC contract when changing worker arguments. |
| 31 | + |
| 32 | +**Project-specific patterns & gotchas** |
| 33 | +- Pagination & scope: `GitHubClient.getCommitsForYear` only requests commits from the 10 most recently-updated repos (`repos.slice(0, 10)`). If you need more comprehensive coverage, update this logic and be mindful of rate limits. |
| 34 | +- Error handling: `src/github.ts` maps Octokit errors to user-friendly messages (404, 403 rate limit). Preserve these mappings when refactoring. |
| 35 | +- Terminal sizing: `src/ui.tsx` contains custom terminal-sizing math to approximate a visual square using terminal character aspect ratio (~2:1). UI adjustments should respect that logic to avoid layout regressions. |
| 36 | +- Animation hooks are intentionally simplified (no incremental animation) for stability. Re-introduce animations only after verifying no re-render loops in Ink. |
| 37 | +- Export worker: always run the worker under Node (`node export-worker.mjs <input> <output>`). On Windows and in Git Bash, Bun pipes are flaky — the file-based IPC and Node worker are deliberate. |
| 38 | + |
| 39 | +**Where to make changes for common tasks** |
| 40 | +- Add a new UI slide: update `src/ui.tsx`, export the component, and wire it into the slide list. Keep each slide a pure component consuming `WrappedStats`. |
| 41 | +- Add new analysis metric: add types in `src/types.ts`, compute in `src/analytics.ts`, and surface the value via the stats object passed to UI and export. |
| 42 | +- Modify export layout/appearance: edit `src/export-worker.mjs` (JSX used by Satori) or `src/export.ts` (font loading, exporter orchestration). Remember worker uses Node and Sharp/Satori; test on Windows. |
| 43 | +- Increase commit coverage: update `src/github.ts` `getCommitsForYear` (adjust repo selection and pagination). Update rate-limit handling and consider requiring `GITHUB_TOKEN` in tests. |
| 44 | + |
| 45 | +**Examples & snippets (copyable)** |
| 46 | +- Run app locally (recommended): |
| 47 | + - `bun install` |
| 48 | + - `bun run build` |
| 49 | + - `bun start` |
| 50 | + |
| 51 | +- Run export worker directly for debugging: |
| 52 | + - `node src/export-worker.mjs /path/to/input.json /path/to/output.json` |
| 53 | + - Input JSON shape: `{ "stats": <WrappedStats>, "filename": "./out.png", "format": "png" }` |
| 54 | + |
| 55 | +**Files to read first (quick orientation)** |
| 56 | +- `src/index.tsx` — CLI entry, Ink render lifecycle |
| 57 | +- `src/ui.tsx` — main terminal UI and input flows |
| 58 | +- `src/github.ts` — REST-based GitHub client (Octokit) and pagination decisions |
| 59 | +- `src/github-graphql*.ts` — GraphQL queries for richer data (lines changed, etc.) |
| 60 | +- `src/analytics.ts` — calculations and achievement rules (deterministic) |
| 61 | +- `src/export.ts` + `src/export-worker.mjs` — the export orchestration and worker contract |
| 62 | + |
| 63 | +**Testing & verification guidance** |
| 64 | +- Use `bun run dev` for iterating UI changes (fast). Use `bun run build` then `bun start` to replicate production behavior. |
| 65 | +- For export changes, run the worker directly with `node` and a synthetic `input.json` containing a minimal `WrappedStats` object to validate Satori → Sharp rendering. |
| 66 | + |
| 67 | +If anything in this guidance is unclear or you want more detail for a specific area (e.g., GraphQL queries, export fonts, or how achievements are calculated), tell me which part and I will expand or update this file. |
0 commit comments