github-search-cli 9.3.0 → 9.4.0

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,192 @@
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.0
10
+
11
+ Release tracking for bookmarked repos, plus a bookmarks page and toast notifications in the TUI.
12
+
13
+ ### Added
14
+
15
+ **Release tracker** — follow releases of repos you've bookmarked
16
+ - `src/releases.ts` — checks each bookmarked repo against `GET /repos/{owner}/{repo}/releases?per_page=5`
17
+ - Seen state is `lastSeenAt` per bookmark; "new" means published after that timestamp
18
+ - ETag conditional requests + `GITHUB_TOKEN` when available to conserve rate budget
19
+ - Prereleases shown and tagged `[pre]`; drafts never shown
20
+ - `ghfind --releases` prints the new-release feed, then marks everything seen; `--releases --json` for machine output
21
+ - Opening the Notifications panel (Space → System → Notifications) now runs a check in the background and files each new release as a `🚀` notification
22
+
23
+ **Bookmarks page** — bookmarks are now a first-class mode, not an overlay
24
+ - Reachable from the landing screen (`b`, or `Enter` on the new button) and from Space → Navigate → Bookmarks
25
+ - `Enter` opens the repo in a browser, `d` removes, `Esc` / `←` returns to landing
26
+ - `SessionState.mode` accepts `"bookmarks"`, so a restart restores you onto the page
27
+
28
+ **Landing bookmarks button** — fourth selectable row below the three mode cards, with a live count (`4 saved` / `none yet`) refreshed on every visit
29
+
30
+ **Toast popup** — top-right rounded card confirming bookmark changes; green border for bookmarked, yellow for unbookmarked, auto-hides after 2s
31
+
32
+ **`b` keybinding** — toggles bookmark on the selected repo from the main view (previously only reachable via Space → Repo → Bookmark)
33
+
34
+ **Diagnostics: `ghfind --doctor`** — environment troubleshooting command for the interactive TUI
35
+ - 10 checks: runtime, bundled Bun, system Bun, Node version, build output, source, TTY, config validity, GitHub token, state/cache dirs
36
+ - Per-check status: green `PASS`, yellow `WARN`, red `FAIL`; non-zero exit on any FAIL so scripts can detect broken installs
37
+ - `src/doctor.ts` is purely diagnostic (no TUI, no network) and exits with code 1 if any check fails
38
+ - `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
39
+
40
+ **Error report on uncaught exceptions** — never auto-posts
41
+ - 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)
42
+ - 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
43
+ - Known user-facing errors (`SearchCliError` subclasses) keep their existing friendly message and skip the report flow
44
+ - `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
45
+
46
+ ### Fixed
47
+ - Landing screen vanished after the bookmarks page landed — `showLanding()` revealed `landingBox` before `hideMainContent()` hid it again; ordering corrected
48
+ - 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)`
49
+ - `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()`
50
+ - `q` inside the bookmarks overlay quit the app instead of closing it — same double-handling root cause
51
+ - `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
52
+
53
+ ### Changed
54
+ - Help screen: new "Bookmarks Page" section; `b` / `c` / `t` documented under Main View; Landing section documents the button; "Overlay Keys" no longer lists bookmarks
55
+ - Leader menu "Notifications" now reads "View alerts — checks bookmarks for new releases"
56
+ - Landing hint line includes `[b]ookmarks`
57
+ - `Bookmark` type gains `lastSeenAt`; `src/bookmarks.ts` exports `getLastSeen()` / `markSeen()`
58
+
59
+ ### Internal
60
+ - Extracted `src/toast.ts` and `src/landing.ts` so the toast, button, and key-routing predicates are testable without booting the TUI
61
+ - 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)
62
+
63
+ ---
64
+
65
+ ## [9.3.0] — 2026-08-24
66
+
67
+ ### Fixed
68
+ - `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`, `?`)
69
+ - README viewer now renders full markdown (headings, code blocks, lists, tables, blockquotes, rules) instead of stripping formatting
70
+
71
+ ### Changed
72
+ - Widened compare table columns (min 35 chars) and added Description + URL rows
73
+ - Compare table shows up to 5 topics per repo (was 3)
74
+
75
+ ---
76
+
77
+ ## [9.2.1] — 2026-08-23
78
+
79
+ ### Added
80
+ - npm package search (beta)
81
+ - New landing screen with selectable mode cards
82
+
83
+ ### Fixed
84
+ - TUI layout issues on small terminals
85
+ - Trending not visible when launched from the landing screen — `loadTrending()` was the only mode switch that didn't set `body.visible`
86
+ - Trending tabs now fetch independently, with an active-tab underline
87
+
88
+ ### Changed
89
+ - Removed the bundled Bun binary from the npm package; it is downloaded at install time on all platforms
90
+ - Package size reduced from 39.5 MB to 100 KB
91
+ - Postinstall no longer fails `npm install` when the Bun download fails (graceful fallback)
92
+ - Removed `bun` from the engines field — Bun need not be pre-installed
93
+ - Non-interactive modes (`--json`, `--csv`, …) run on Node.js 20+ alone
94
+
95
+ ---
96
+
97
+ ## [9.1.1] — 2026-08-11
98
+
99
+ ### Fixed
100
+ - Postinstall now exits with code 1 on Bun download failure
101
+ - Removed dead Strategy 3 fallback in `bin/ghfind.js` (Node cannot import `.ts`)
102
+
103
+ ### Changed
104
+ - Bundle `vendor/` and `dist/` in the npm package for offline install
105
+ - Bundled Bun updated from 1.3.12 to 1.3.14
106
+
107
+ ---
108
+
109
+ ## [9.1.0] — 2026-08-07
110
+
111
+ ### Added
112
+ - Automatic update checking against the npm registry, with a Y/N/L modal (install now / skip / dismiss)
113
+ - Leader menu (Space) consolidating all contextual actions
114
+ - Topic explorer, notifications panel, and saved searches overlay
115
+ - Activity graph toggle (commit chart fullscreen)
116
+ - README viewer
117
+ - Tab auto-complete for search qualifiers
118
+ - PageUp / PageDown navigation
119
+ - `Ctrl+X` clears history, `Ctrl+C` clears all notifications
120
+
121
+ ### Fixed
122
+ - Postinstall downloads the Bun binary correctly on all platforms
123
+ - Zip asset names match Bun's current release naming
124
+ - Zip parsing uses the central directory instead of local file headers
125
+ - `postinstall` uses `node` instead of `bun run`, so Bun need not be pre-installed
126
+ - TUI works on Node.js 20+ via the downloaded Bun binary
127
+
128
+ ### Changed
129
+ - Removed `vendor/` from the npm package (Bun downloaded at install time)
130
+ - Improved export error handling and format selection
131
+
132
+ ---
133
+
134
+ ## [0.9.0] — 2026-07-31
135
+
136
+ ### Added
137
+ - Watch mode (`--watch`) for polling a query
138
+ - Notifications panel and UI refinements
139
+
140
+ ### Fixed
141
+ - Trending browser fixes
142
+
143
+ ---
144
+
145
+ ## [0.8.2] — 2026-07-31
146
+
147
+ ### Fixed
148
+ - TUI stability fixes; rewritten keybindings reference
149
+
150
+ ---
151
+
152
+ ## [0.8.1] — 2026-07-27
153
+
154
+ ### Fixed
155
+ - Follow-up fixes to the 0.8.0 breaking change
156
+
157
+ ---
158
+
159
+ ## [0.8.0] — 2026-07-26
160
+
161
+ ### Added
162
+ - Trending browser, deep-dive, compare, export, share, topics, saved searches
163
+ - Activity graph, README viewer, notifications panel
164
+
165
+ **Breaking:** entry point and command surface changed; 0.8.1 shipped the same day as an emergency follow-up
166
+
167
+ ---
168
+
169
+ ## [0.7.0] — 2026-07-25
170
+
171
+ ### Added
172
+ - Bookmarks and search history
173
+
174
+ ---
175
+
176
+ ## [0.6.1] — 2026-07-24
177
+
178
+ ### Fixed
179
+ - Fixes for the initial release
180
+
181
+ ---
182
+
183
+ ## [0.6.0] — 2026-07-23
184
+
185
+ ### Added
186
+ - First public release: repo search with qualifiers, sorting, and JSON output
187
+
188
+ ---
189
+
190
+ ## A note on version numbers
191
+
192
+ 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+)