github-search-cli 9.3.0 → 9.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,238 @@
1
+ # Changelog
2
+
3
+ All notable changes to `github-search-cli` (published as the `ghfind` binary).
4
+
5
+ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). Published versions and dates mirror [npm](https://www.npmjs.com/package/github-search-cli?activeTab=versions).
6
+
7
+ ---
8
+
9
+ ## [Unreleased] — 9.4.1
10
+
11
+ ### Changed
12
+
13
+ - **TUI overlay registry seam** — `src/tui.ts` is 2,867 lines and was the
14
+ most-changed file in the repo (28 of the last 200 commits). A new
15
+ `src/tui/overlays/registry.ts` introduces the seam that future
16
+ migrations will consume: `Overlay` interface plus `OVERLAYS` array and
17
+ `getOverlay()` lookup. The first overlay (`help`) is extracted behind
18
+ it. Behaviour is unchanged. Migration is gradual; subsequent commits
19
+ move one overlay at a time and rewire `showOverlay()` to query the
20
+ registry.
21
+
22
+ ### Added
23
+
24
+ - 6 guard tests in `tests/overlay-registry.test.ts` pin the registry
25
+ contract and source-grep `src/tui.ts` to fail on drift between the
26
+ registered ids and the dispatcher's union type.
27
+
28
+ ---
29
+
30
+ ## [9.4.0] — 2026-08-28
31
+
32
+ Release tracking for bookmarked repos, plus a bookmarks page and toast notifications in the TUI.
33
+
34
+ ### Added
35
+
36
+ **Release tracker** — follow releases of repos you've bookmarked
37
+
38
+ - `src/releases.ts` — checks each bookmarked repo against `GET /repos/{owner}/{repo}/releases?per_page=5`
39
+ - Seen state is `lastSeenAt` per bookmark; "new" means published after that timestamp
40
+ - ETag conditional requests + `GITHUB_TOKEN` when available to conserve rate budget
41
+ - Prereleases shown and tagged `[pre]`; drafts never shown
42
+ - `ghfind --releases` prints the new-release feed, then marks everything seen; `--releases --json` for machine output
43
+ - Opening the Notifications panel (Space → System → Notifications) now runs a check in the background and files each new release as a `🚀` notification
44
+
45
+ **Bookmarks page** — bookmarks are now a first-class mode, not an overlay
46
+
47
+ - Reachable from the landing screen (`b`, or `Enter` on the new button) and from Space → Navigate → Bookmarks
48
+ - `Enter` opens the repo in a browser, `d` removes, `Esc` / `←` returns to landing
49
+ - `SessionState.mode` accepts `"bookmarks"`, so a restart restores you onto the page
50
+
51
+ **Landing bookmarks button** — fourth selectable row below the three mode cards, with a live count (`4 saved` / `none yet`) refreshed on every visit
52
+
53
+ **Toast popup** — top-right rounded card confirming bookmark changes; green border for bookmarked, yellow for unbookmarked, auto-hides after 2s
54
+
55
+ **`b` keybinding** — toggles bookmark on the selected repo from the main view (previously only reachable via Space → Repo → Bookmark)
56
+
57
+ **Diagnostics: `ghfind --doctor`** — environment troubleshooting command for the interactive TUI
58
+
59
+ - 10 checks: runtime, bundled Bun, system Bun, Node version, build output, source, TTY, config validity, GitHub token, state/cache dirs
60
+ - Per-check status: green `PASS`, yellow `WARN`, red `FAIL`; non-zero exit on any FAIL so scripts can detect broken installs
61
+ - `src/doctor.ts` is purely diagnostic (no TUI, no network) and exits with code 1 if any check fails
62
+ - `bin/ghfind.js` Strategy 1 now prefers the bundled `vendor/bun` (downloaded by `postinstall.js`) and falls back to a system-installed `bun` on PATH; doctor confirms which one wins
63
+
64
+ **Error report on uncaught exceptions** — never auto-posts
65
+
66
+ - When `ghfind` hits an unexpected error, builds a pre-filled `https://github.com/codersdfs/search-cli/issues/new?title=...&body=...&labels=bug` URL with the error class, message, stack, command line, and environment (ghfind version, runtime, platform)
67
+ - Tries to open the URL in the user's default browser (Bun.spawn when available, child_process.spawn detached fallback for Node); prints the URL when no browser can be launched
68
+ - Known user-facing errors (`SearchCliError` subclasses) keep their existing friendly message and skip the report flow
69
+ - `src/error-report.ts` is the new module; `tests/error-report.test.ts` covers URL format, ANSI stripping, long-message truncation, non-Error throwables, env + command in body
70
+
71
+ ### Fixed
72
+
73
+ - Landing screen vanished after the bookmarks page landed — `showLanding()` revealed `landingBox` before `hideMainContent()` hid it again; ordering corrected
74
+ - Arrow keys moved the landing selection _and_ the bookmarks list at the same time — the landing handler only checked `currentMode`, which opening bookmarks doesn't change. Now gated on `landingKeysActive(mode, overlay)`
75
+ - `Enter` on the landing bookmarks button immediately opened the first bookmark in a browser — the same key event reached the global handler after the page opened. Consumed keys now call `key.stopPropagation()`
76
+ - `q` inside the bookmarks overlay quit the app instead of closing it — same double-handling root cause
77
+ - `tests/tips.test.ts` imported a `TipRotator` class that `src/tips.ts` never exported, so its module-load error was misattributed to whichever test file ran next. Added the class and `defaultRotator`; behavior unchanged
78
+
79
+ ### Changed
80
+
81
+ - Help screen: new "Bookmarks Page" section; `b` / `c` / `t` documented under Main View; Landing section documents the button; "Overlay Keys" no longer lists bookmarks
82
+ - Leader menu "Notifications" now reads "View alerts — checks bookmarks for new releases"
83
+ - Landing hint line includes `[b]ookmarks`
84
+ - `Bookmark` type gains `lastSeenAt`; `src/bookmarks.ts` exports `getLastSeen()` / `markSeen()`
85
+
86
+ ### Internal
87
+
88
+ - Extracted `src/toast.ts` and `src/landing.ts` so the toast, button, and key-routing predicates are testable without booting the TUI
89
+ - Tests: 187 passing — `tests/landing.test.ts` (30), `tests/toast.test.ts` (6), `tests/releases.test.ts`, `tests/tips.test.ts`, `tests/doctor.test.ts` (2), `tests/error-report.test.ts` (6)
90
+
91
+ ---
92
+
93
+ ## [9.3.0] — 2026-08-24
94
+
95
+ ### Fixed
96
+
97
+ - `c` keybinding in the TUI not adding repos to comparison — a missing closing brace in the space-key handler broke every later key handler (`c`, `t`, `?`)
98
+ - README viewer now renders full markdown (headings, code blocks, lists, tables, blockquotes, rules) instead of stripping formatting
99
+
100
+ ### Changed
101
+
102
+ - Widened compare table columns (min 35 chars) and added Description + URL rows
103
+ - Compare table shows up to 5 topics per repo (was 3)
104
+
105
+ ---
106
+
107
+ ## [9.2.1] — 2026-08-23
108
+
109
+ ### Added
110
+
111
+ - npm package search (beta)
112
+ - New landing screen with selectable mode cards
113
+
114
+ ### Fixed
115
+
116
+ - TUI layout issues on small terminals
117
+ - Trending not visible when launched from the landing screen — `loadTrending()` was the only mode switch that didn't set `body.visible`
118
+ - Trending tabs now fetch independently, with an active-tab underline
119
+
120
+ ### Changed
121
+
122
+ - Removed the bundled Bun binary from the npm package; it is downloaded at install time on all platforms
123
+ - Package size reduced from 39.5 MB to 100 KB
124
+ - Postinstall no longer fails `npm install` when the Bun download fails (graceful fallback)
125
+ - Removed `bun` from the engines field — Bun need not be pre-installed
126
+ - Non-interactive modes (`--json`, `--csv`, …) run on Node.js 20+ alone
127
+
128
+ ---
129
+
130
+ ## [9.1.1] — 2026-08-11
131
+
132
+ ### Fixed
133
+
134
+ - Postinstall now exits with code 1 on Bun download failure
135
+ - Removed dead Strategy 3 fallback in `bin/ghfind.js` (Node cannot import `.ts`)
136
+
137
+ ### Changed
138
+
139
+ - Bundle `vendor/` and `dist/` in the npm package for offline install
140
+ - Bundled Bun updated from 1.3.12 to 1.3.14
141
+
142
+ ---
143
+
144
+ ## [9.1.0] — 2026-08-07
145
+
146
+ ### Added
147
+
148
+ - Automatic update checking against the npm registry, with a Y/N/L modal (install now / skip / dismiss)
149
+ - Leader menu (Space) consolidating all contextual actions
150
+ - Topic explorer, notifications panel, and saved searches overlay
151
+ - Activity graph toggle (commit chart fullscreen)
152
+ - README viewer
153
+ - Tab auto-complete for search qualifiers
154
+ - PageUp / PageDown navigation
155
+ - `Ctrl+X` clears history, `Ctrl+C` clears all notifications
156
+
157
+ ### Fixed
158
+
159
+ - Postinstall downloads the Bun binary correctly on all platforms
160
+ - Zip asset names match Bun's current release naming
161
+ - Zip parsing uses the central directory instead of local file headers
162
+ - `postinstall` uses `node` instead of `bun run`, so Bun need not be pre-installed
163
+ - TUI works on Node.js 20+ via the downloaded Bun binary
164
+
165
+ ### Changed
166
+
167
+ - Removed `vendor/` from the npm package (Bun downloaded at install time)
168
+ - Improved export error handling and format selection
169
+
170
+ ---
171
+
172
+ ## [0.9.0] — 2026-07-31
173
+
174
+ ### Added
175
+
176
+ - Watch mode (`--watch`) for polling a query
177
+ - Notifications panel and UI refinements
178
+
179
+ ### Fixed
180
+
181
+ - Trending browser fixes
182
+
183
+ ---
184
+
185
+ ## [0.8.2] — 2026-07-31
186
+
187
+ ### Fixed
188
+
189
+ - TUI stability fixes; rewritten keybindings reference
190
+
191
+ ---
192
+
193
+ ## [0.8.1] — 2026-07-27
194
+
195
+ ### Fixed
196
+
197
+ - Follow-up fixes to the 0.8.0 breaking change
198
+
199
+ ---
200
+
201
+ ## [0.8.0] — 2026-07-26
202
+
203
+ ### Added
204
+
205
+ - Trending browser, deep-dive, compare, export, share, topics, saved searches
206
+ - Activity graph, README viewer, notifications panel
207
+
208
+ **Breaking:** entry point and command surface changed; 0.8.1 shipped the same day as an emergency follow-up
209
+
210
+ ---
211
+
212
+ ## [0.7.0] — 2026-07-25
213
+
214
+ ### Added
215
+
216
+ - Bookmarks and search history
217
+
218
+ ---
219
+
220
+ ## [0.6.1] — 2026-07-24
221
+
222
+ ### Fixed
223
+
224
+ - Fixes for the initial release
225
+
226
+ ---
227
+
228
+ ## [0.6.0] — 2026-07-23
229
+
230
+ ### Added
231
+
232
+ - First public release: repo search with qualifiers, sorting, and JSON output
233
+
234
+ ---
235
+
236
+ ## A note on version numbers
237
+
238
+ The jump from `0.9.0` to `9.1.0` was a one-time renumbering, not 9 major releases. The `9.x` line begins with the update checker and leader menu. There is no `9.0.0`, and `9.2.0` was never published — `9.2.1` superseded it before release.
package/README.md CHANGED
@@ -192,67 +192,43 @@ cd ghfind
192
192
  # With Bun (recommended for TUI)
193
193
  bun install
194
194
  bun start # TUI
195
- bun test # 131 tests
195
+ bun test # 179 tests
196
196
  bun run build # build dist/
197
197
 
198
198
  # Or with npm
199
199
  npm install
200
200
  npm start # TUI (requires Node 20+)
201
- npm test # 131 tests
201
+ npm test # 179 tests
202
202
  npm run build # build dist/
203
203
  ```
204
204
 
205
205
  ---
206
- ### v0.9.3
207
- - Fixed `c` keybinding in TUI not adding repos to comparison — missing closing brace in space-key handler broke all subsequent key handlers (`c`, `t`, `?`)
208
- - Widened compare table columns (min 35 chars) and added Description + URL rows for richer side-by-side comparison
209
- - Compare table now shows up to 5 topics per repo (was 3)
210
- - README viewer now renders full markdown (headings, code blocks, lists, tables, blockquotes, rules) instead of stripping formatting
211
- ---
212
- ### v0.9.2
213
-
214
- - Remove bundled Bun binary from npm package (now downloaded at install time for all platforms)
215
- - Package size reduced from 39.5 MB to 100 KB
216
- - Postinstall no longer fails npm install on Bun download failure (graceful fallback)
217
- - Removed `bun` from engines field (users no longer need Bun pre-installed)
218
- - Non-interactive modes (`--json`, `--csv`, etc.) work with just Node.js 20+
219
-
220
- ### v0.9.1
221
-
222
- - bug fix TUI layout issues on small terminals
223
- - npm package search(beta)
224
- - a new landing screen
225
-
226
- ### v0.9.0
227
-
228
- - Bundle `vendor/` and `dist/` in npm package for offline install support
229
- - Remove dead Strategy 3 fallback in `bin/ghfind.js` (Node cannot import `.ts`)
230
- - Fix postinstall to exit with code 1 on Bun download failure
231
- - Update bundled Bun version from 1.3.12 to 1.3.14
232
-
233
-
234
- ### v0.8.2
235
-
236
- - Added automatic update checking against the npm registry
237
- - Added leader menu (Space) consolidating all contextual actions
238
- - Added update modal with Y/N/L (install now / skip / dismiss)
239
- - Added topic explorer, notifications panel, and saved searches overlay
240
- - Added activity graph toggle (commit chart fullscreen)
241
- - Added README viewer (full markdown rendering in TUI)
242
- - Added result auto-complete for search qualifiers (Tab)
243
- - Added PageUp/PageDown for quick navigation
244
- - Added Ctrl+X to clear history, Ctrl+C to clear all notifications
245
- - Improved export error handling and format selection
246
- - Updated keybindings reference
247
-
248
- ### v0.8.1
249
-
250
- - Fixed postinstall to download Bun binary correctly on all platforms
251
- - Fixed zip asset names to match Bun's current release naming
252
- - Fixed zip parsing to use central directory instead of local file headers
253
- - Removed `vendor/` from npm package (Bun binary downloaded at install time)
254
- - Changed `postinstall` to use `node` instead of `bun run` (works without Bun pre-installed)
255
- - TUI now works on Node.js 20+ via bundled Bun binary
206
+
207
+ ## Changelog
208
+
209
+ Recent releases (full history in [CHANGELOG.md](CHANGELOG.md)):
210
+
211
+ ### v9.3.0
212
+ - Fixed `c` keybinding in TUI not adding repos to comparison — a missing closing brace in the space-key handler broke every later key handler (`c`, `t`, `?`)
213
+ - README viewer renders full markdown (headings, code blocks, lists, tables, blockquotes, rules) instead of stripping formatting
214
+ - Widened compare table columns (min 35 chars), added Description + URL rows, and raised the topic cap to 5 per repo
215
+
216
+ ### v9.2.1
217
+ - npm package search (beta) and a new landing screen
218
+ - Removed the bundled Bun binary — downloaded at install time instead; package size 39.5 MB → 100 KB
219
+ - Postinstall failures no longer break `npm install`; `bun` dropped from engines
220
+ - Fixed TUI layout on small terminals, trending visibility from the landing screen, and independent trending-tab fetches
221
+
222
+ ### v9.1.1
223
+ - Bundle `vendor/` and `dist/` for offline install
224
+ - Postinstall exits non-zero on Bun download failure; bundled Bun 1.3.12 → 1.3.14
225
+
226
+ ### v9.1.0
227
+ - Automatic update checking against the npm registry, with a Y/N/L modal
228
+ - Leader menu (Space) consolidating all contextual actions
229
+ - Topic explorer, notifications panel, saved searches, activity graph, README viewer
230
+ - Tab qualifier auto-complete, PageUp/PageDown, `Ctrl+X` clear history, `Ctrl+C` clear notifications
231
+ - TUI runs on Node.js 20+ via the downloaded Bun binary
256
232
 
257
233
  ---
258
234
 
package/bin/ghfind.js CHANGED
@@ -3,9 +3,11 @@
3
3
  * ghfind — npm bin entry point.
4
4
  * Requires Node.js >= 20 or Bun.
5
5
  *
6
- * Strategy 1: Use a Bun binary from vendor/ (downloaded by postinstall) to
7
- * run TypeScript source directly. Strategy 2: Fall back to the bundled
8
- * dist/cli.js with Node.js (works for non-interactive modes).
6
+ * Strategy 1: Use a Bun binary to run TypeScript source directly. Prefers the
7
+ * bundled vendor/bun (downloaded by postinstall), then falls back to a
8
+ * system-installed `bun` on PATH. Only runnable binaries are considered.
9
+ * Strategy 2: Fall back to the bundled dist/cli.js with Node.js (works for
10
+ * non-interactive modes).
9
11
  */
10
12
  import { existsSync } from "fs";
11
13
  import { spawnSync } from "child_process";
@@ -16,7 +18,11 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
16
18
  const PKG_DIR = join(__dirname, "..");
17
19
 
18
20
  // Path to bundled Bun binary
19
- const BUN_BIN = join(PKG_DIR, "vendor", platform() === "win32" ? "bun.exe" : "bun");
21
+ const BUN_BIN = join(
22
+ PKG_DIR,
23
+ "vendor",
24
+ platform() === "win32" ? "bun.exe" : "bun",
25
+ );
20
26
 
21
27
  // Path to bundled dist
22
28
  const distCli = join(PKG_DIR, "dist", "cli.js");
@@ -24,13 +30,51 @@ const distCli = join(PKG_DIR, "dist", "cli.js");
24
30
  // Path to source
25
31
  const srcCli = join(PKG_DIR, "src", "cli.ts");
26
32
 
27
- // Strategy 1: Use bundled Bun to run source directly (always works, no Node FFI needed)
28
- if (existsSync(BUN_BIN) && existsSync(srcCli)) {
29
- const result = spawnSync(BUN_BIN, ["run", srcCli, ...process.argv.slice(2)], {
30
- stdio: "inherit",
31
- env: { ...process.env, GHFIND_BUNDLED: "1" },
32
- });
33
- process.exit(result.status ?? 0);
33
+ /** Returns "bun" if a system Bun is available on PATH, else undefined. */
34
+ function systemBun() {
35
+ try {
36
+ const res = spawnSync("bun", ["--version"], {
37
+ encoding: "utf8",
38
+ timeout: 15000,
39
+ });
40
+ return res.status === 0 ? "bun" : undefined;
41
+ } catch {
42
+ return undefined;
43
+ }
44
+ }
45
+
46
+ /** Returns true if the given Bun binary actually runs. */
47
+ function bunRuns(bin) {
48
+ try {
49
+ const res = spawnSync(bin, ["--version"], {
50
+ encoding: "utf8",
51
+ timeout: 15000,
52
+ });
53
+ return res.status === 0;
54
+ } catch {
55
+ return false;
56
+ }
57
+ }
58
+
59
+ // Strategy 1: Use Bun to run source directly (bundled binary first, then system bun)
60
+ if (existsSync(srcCli)) {
61
+ const candidates = [];
62
+ if (existsSync(BUN_BIN)) candidates.push(BUN_BIN);
63
+ const sysBun = systemBun();
64
+ if (sysBun) candidates.push(sysBun);
65
+
66
+ for (const bunBin of candidates) {
67
+ if (!bunRuns(bunBin)) continue;
68
+ const result = spawnSync(
69
+ bunBin,
70
+ ["run", srcCli, ...process.argv.slice(2)],
71
+ {
72
+ stdio: "inherit",
73
+ env: { ...process.env, GHFIND_BUNDLED: "1" },
74
+ },
75
+ );
76
+ process.exit(result.status ?? 0);
77
+ }
34
78
  }
35
79
 
36
80
  // Strategy 2: Use bundled dist/cli.js with Node (non-interactive only on Node 23+)