Skip to content

Commit bc1ef49

Browse files
committed
05: Update documentation for Bun 1.4 migration
- Update AGENTS.md: Bun >= 1.4 requirement, add terminal.ts module description - Add architectural rule: terminal.ts is sole Bun API call site - Update README.md: Add Requirements section with Bun >= 1.4 and GitHub Token scopes - Update docs/architecture/components.md: Add Terminal API wrapper component - Update docs/architecture/containers.md: Add Terminal resizing section documenting SIGWINCH handler, live redraw, and Bun.Terminal clarification - Document Unicode handling: emoji, CJK, grapheme clusters Fixes: #145
1 parent 9fdab01 commit bc1ef49

4 files changed

Lines changed: 25 additions & 1 deletion

File tree

‎AGENTS.md‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ This file provides context for AI coding agents (GitHub Copilot, Claude, Gemini,
1010

1111
| Tool | Version |
1212
| -------------- | -------------------------------------------------------- |
13-
| **Bun** | ≥ 1.0 (runtime, bundler, test runner, package manager) |
13+
| **Bun** | ≥ 1.4 (runtime, bundler, test runner, package manager) |
1414
| **TypeScript** | via Bun (no separate `tsc` invocation needed at runtime) |
1515
| **oxlint** | linter (`bun run lint`) |
1616
| **oxfmt** | formatter (`bun run format`) |
@@ -93,6 +93,8 @@ src/
9393
# + refreshCompletions() — overwrites existing completion file
9494
9595
render/
96+
terminal.ts # Bun 1.4+ native API wrappers (stringWidth, stripANSI, sliceAnsi)
97+
# sole authorized call site for these APIs
9698
highlight.ts # Syntax highlighting (language detection + token rules)
9799
filter.ts # FilterStats + buildFilterStats
98100
filter-match.ts # Pure pattern matchers — makeExtractMatcher, makeRepoMatcher
@@ -110,6 +112,7 @@ src/
110112
- **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.
111113
- **Side effects are isolated.** API calls (`api.ts`, `api-utils.ts`), TTY interaction (`tui.ts`) and CLI parsing (`github-code-search.ts`) are the only side-effectful surfaces. `api-utils.ts` hosts shared retry/pagination helpers that perform network I/O and must not be used outside `api.ts`. `cache.ts` hosts disk-cache helpers that perform filesystem I/O and must not be used outside `api.ts`.
112114
- **`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.
115+
- **`render/terminal.ts` is the sole Bun API call site.** All calls to `Bun.stringWidth()`, `Bun.stripANSI()`, and `Bun.sliceAnsi()` must go through the `terminal.ts` wrapper functions (`visibleWidth()`, `stripAnsi()`, `clipToWidth()`, `hasAnsi()`). This centralizes terminal handling logic and makes it easy to verify correct Unicode handling (graphemes, emoji, CJK, ZWJ sequences).
113116
- **`types.ts` is the single source of truth** for all shared interfaces. Any new shared type must go there.
114117
- **No classes** — the codebase uses plain TypeScript interfaces and functions throughout.
115118

‎README.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ keyboard-driven TUI, fine-grained extract selection, markdown/JSON output.
1212

1313
![Demo](demo/demo.gif)
1414

15+
## Requirements
16+
17+
- **Bun** ≥ 1.4 (runtime and package manager)
18+
- **GitHub Token** with `repo` and `read:org` scopes
19+
1520
## Quick start
1621

1722
**macOS / Linux**

‎docs/architecture/components.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ C4Component
6060
Container(tui, "TUI", "src/tui.ts", "Calls render functions<br/>on every redraw;<br/>formats output on Enter")
6161
6262
Container_Boundary(render, "src/render/ — pure functions") {
63+
Component(terminal, "Terminal API wrapper", "src/render/terminal.ts", "visibleWidth()<br/>stripAnsi()<br/>clipToWidth()<br/>hasAnsi()")
6364
Component(rows, "Row builder", "src/render/rows.ts", "buildRows()<br/>rowTerminalLines()<br/>isCursorVisible()")
6465
Component(summary, "Summary builder", "src/render/summary.ts", "buildSummary()<br/>buildSummaryFull()<br/>buildSelectionSummary()")
6566
Component(filter, "Filter stats", "src/render/filter.ts", "buildFilterStats()<br/>FilterStats — visible/hidden counts")
@@ -116,6 +117,7 @@ C4Component
116117
| **Selection helpers** | `src/render/selection.ts` | `applySelectAll()` — marks all visible rows as selected (respects filter target); `applySelectNone()` — deselects all visible rows. |
117118
| **Syntax highlighter** | `src/render/highlight.ts` | `highlightFragment()` — maps file extension to a language token ruleset and applies ANSI escape sequences. Falls back to plain text for unknown extensions. |
118119
| **Team pick bar** | `src/render/team-pick.ts` | `renderTeamPickHeader()` — renders the ANSI pick-mode candidate bar shown when the user presses `p` on a multi-team section header. Focused candidate is highlighted in bold magenta; others are dimmed. |
120+
| **Terminal API wrapper** | `src/render/terminal.ts` | `visibleWidth()` — measures terminal columns (Bun.stringWidth); `stripAnsi()` — removes escape codes (Bun.stripANSI); `clipToWidth()` — truncates to N columns preserving partial reset (Bun.sliceAnsi); `hasAnsi()` — detects presence of codes. Sole authorized call site for Bun 1.4+ ANSI APIs. |
119121
| **Output formatter** | `src/output.ts` | `buildOutput()` — entry point for both `--format markdown` and `--format json` serialisation of the confirmed selection. |
120122

121123
## Design principles

‎docs/architecture/containers.md‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,17 @@ C4Container
117117
4. **TUI** receives `RepoGroup[]`, renders the browser, and waits for user input.
118118
5. On `Enter`, **TUI** returns the selection → **CLI parser** calls **Output renderer**.
119119
6. **Output renderer** prints markdown or JSON to stdout.
120+
121+
## Terminal resizing and SIGWINCH
122+
123+
**The TUI responds to live terminal resize events.** When the user resizes their terminal window during an interactive session:
124+
125+
1. The operating system sends the `SIGWINCH` signal to the process.
126+
2. The **TUI** installs a `SIGWINCH` handler before entering the keyboard event loop.
127+
3. The handler reads the new `process.stdout.rows` and `process.stdout.columns` values.
128+
4. If dimensions have changed, the handler calls `redraw()` to re-render with the new layout.
129+
5. The user sees an immediate, flicker-free refresh without needing to press any key.
130+
131+
When the **TUI** exits (via Ctrl+C, `q`, `Enter`, or `Esc`), the handler is unregistered via `process.off("SIGWINCH", onResize)` to ensure clean cleanup. The **Terminal API wrapper** (`src/render/terminal.ts`) uses `Bun.stringWidth()`, `Bun.stripANSI()`, and `Bun.sliceAnsi()` to measure and truncate text accurately, accounting for emoji, CJK characters, and multi-code-point grapheme clusters.
132+
133+
**Note on `Bun.Terminal`:** This project uses Bun's low-level ANSI/stringWidth APIs, not the high-level `Bun.Terminal` class (which is designed for PTY subprocess management, not TUI rendering).

0 commit comments

Comments
 (0)