github-search-cli 0.8.0 → 0.8.2
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/README.md +181 -144
- package/bin/ghfind.js +54 -13
- package/completions/ghfind.fish +18 -18
- package/completions/ghfind.zsh +26 -26
- package/demo.svg +65 -65
- package/package.json +18 -10
- package/scripts/brew.rb +32 -0
- package/scripts/build.ts +19 -0
- package/scripts/generate-svg-demo.js +168 -0
- package/scripts/postinstall.js +106 -0
- package/src/bookmarks.ts +69 -69
- package/src/cli.ts +239 -239
- package/src/compare.ts +46 -46
- package/src/config.ts +65 -65
- package/src/deepdive.ts +118 -118
- package/src/errors.ts +59 -59
- package/src/explore.ts +29 -29
- package/src/export.ts +63 -63
- package/src/help.ts +112 -112
- package/src/history.ts +91 -91
- package/src/init.ts +55 -55
- package/src/notifications.ts +65 -65
- package/src/open-url.ts +16 -16
- package/src/output.ts +67 -67
- package/src/pipe.ts +54 -54
- package/src/saved-searches.ts +58 -58
- package/src/search.ts +555 -555
- package/src/session.ts +36 -36
- package/src/share.ts +54 -54
- package/src/status.ts +61 -61
- package/src/themes.ts +52 -52
- package/src/tips.ts +27 -27
- package/src/trending.ts +558 -556
- package/src/tui.ts +1682 -1665
- package/src/types.ts +139 -139
- package/src/watch.ts +62 -62
package/demo.svg
CHANGED
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 803" width="900" height="803">
|
|
3
|
-
<defs>
|
|
4
|
-
<style>
|
|
5
|
-
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&display=swap');
|
|
6
|
-
</style>
|
|
7
|
-
<filter id="shadow" x="-5%" y="-5%" width="115%" height="115%">
|
|
8
|
-
<feDropShadow dx="0" dy="4" stdDeviation="8" flood-color="#000" flood-opacity="0.4"/>
|
|
9
|
-
</filter>
|
|
10
|
-
</defs>
|
|
11
|
-
|
|
12
|
-
<rect width="100%" height="100%" fill="#0d0d1a"/>
|
|
13
|
-
|
|
14
|
-
<!-- Window -->
|
|
15
|
-
<rect x="12" y="10" width="876" height="783" fill="#1e1e2e" rx="8" filter="url(#shadow)"/>
|
|
16
|
-
<rect x="12" y="10" width="876" height="36" fill="#181825" rx="8"/>
|
|
17
|
-
<rect x="12" y="46" width="876" height="2" fill="#313244"/>
|
|
18
|
-
|
|
19
|
-
<!-- Traffic lights -->
|
|
20
|
-
<circle cx="24" cy="28" r="5" fill="#f38ba8"/>
|
|
21
|
-
<circle cx="42" cy="28" r="5" fill="#f9e2af"/>
|
|
22
|
-
<circle cx="60" cy="28" r="5" fill="#a6e3a1"/>
|
|
23
|
-
<text x="450" y="34" fill="#6c7086" font-family="'JetBrains Mono','Fira Code',monospace" font-size="13" text-anchor="middle">search-cli — terminal GitHub browser</text>
|
|
24
|
-
|
|
25
|
-
<g font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">
|
|
26
|
-
<text x="14" y="62" fill="#6c7086" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">search-cli — GitHub repo browser [t]rending [/]search [g]raph [r]efresh [q]uit</text>
|
|
27
|
-
<rect x="14" y="69" width="860" height="54.5" fill="#1e1e2e" stroke="#89b4fa" stroke-width="1" rx="3"/>
|
|
28
|
-
<text x="22" y="88" fill="#89b4fa" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">> language:TypeScript stars:>1000</text>
|
|
29
|
-
<text x="14" y="150.2" fill="#6c7086" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">sort: stars limit: 50 (s=cycle sort l=cycle limit)</text>
|
|
30
|
-
<rect x="14" y="159.3" width="432" height="378" fill="#1e1e2e" stroke="#45475a" stroke-width="1" rx="3"/>
|
|
31
|
-
<text x="22" y="177.5" fill="#89b4fa" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14"> Results </text>
|
|
32
|
-
<rect x="18" y="178.20000000000002" width="424" height="20" fill="#2d5bcf" rx="3"/>
|
|
33
|
-
<text x="24" y="198.5" fill="#ffffff" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">shadcn/ui ★ 78.5k</text>
|
|
34
|
-
<text x="24" y="221.6" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">vercel/next.js ★ 129k</text>
|
|
35
|
-
<text x="24" y="244.7" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">tailwindlabs/tailwindcss ★ 84.2k</text>
|
|
36
|
-
<text x="24" y="267.8" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">tauri-apps/tauri ★ 84.1k</text>
|
|
37
|
-
<text x="24" y="290.9" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">oven-sh/bun ★ 74.5k</text>
|
|
38
|
-
<text x="24" y="314" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">n8n-io/n8n ★ 54.4k</text>
|
|
39
|
-
<text x="24" y="337.1" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">astral-sh/ruff ★ 36.1k</text>
|
|
40
|
-
<text x="24" y="360.20000000000005" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">missive/emoji-mart ★ 8.8k</text>
|
|
41
|
-
<text x="24" y="383.3" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">sharkdp/bat ★ 50.3k</text>
|
|
42
|
-
<text x="24" y="406.4" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">BurntSushi/ripgrep ★ 48.8k</text>
|
|
43
|
-
<text x="24" y="429.5" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">jdx/mise ★ 14.3k</text>
|
|
44
|
-
<text x="24" y="452.6" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">nektos/act ★ 56.1k</text>
|
|
45
|
-
<text x="24" y="475.70000000000005" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">astral-sh/uv ★ 40.2k</text>
|
|
46
|
-
<text x="24" y="498.8" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">zed-industries/zed ★ 52k</text>
|
|
47
|
-
<rect x="450" y="159.3" width="432" height="378" fill="#1e1e2e" stroke="#45475a" stroke-width="1" rx="3"/>
|
|
48
|
-
<text x="456" y="177.5" fill="#a6e3a1" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14"> Details </text>
|
|
49
|
-
<text x="458" y="198.5" fill="#6c7086" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">Name shadcn/ui</text>
|
|
50
|
-
<text x="458" y="221.6" fill="#6c7086" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">Stars 78,500</text>
|
|
51
|
-
<text x="458" y="244.7" fill="#6c7086" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">Forks 4,200</text>
|
|
52
|
-
<text x="458" y="267.8" fill="#6c7086" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">Lang TypeScript</text>
|
|
53
|
-
<text x="458" y="290.9" fill="#6c7086" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">Updated 2026-07-12</text>
|
|
54
|
-
<text x="458" y="314" fill="#6c7086" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">Topics react, ui, components, shadcn</text>
|
|
55
|
-
<text x="458" y="360.20000000000005" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">Beautifully designed components built with Radix UI and</text>
|
|
56
|
-
<text x="458" y="383.3" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">Tailwind CSS.</text>
|
|
57
|
-
<text x="458" y="429.5" fill="#89b4fa" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">https://github.com/shadcn/ui</text>
|
|
58
|
-
<rect x="14" y="489" width="860" height="25" fill="#181825" rx="3"/>
|
|
59
|
-
<rect x="14" y="489" width="860" height="2" fill="#45475a"/>
|
|
60
|
-
<text x="18" y="521.9" fill="#6c7086" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">15,842 results (↑↓ nav Enter open o browser Ctrl+R history)</text>
|
|
61
|
-
<rect x="338.79999999999995" y="70" width="5.76" height="16" fill="#89b4fa" opacity="0.8">
|
|
62
|
-
<animate attributeName="opacity" values="0.8;0.1;0.8" dur="1s" repeatCount="indefinite"/>
|
|
63
|
-
</rect>
|
|
64
|
-
|
|
65
|
-
</g>
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 803" width="900" height="803">
|
|
3
|
+
<defs>
|
|
4
|
+
<style>
|
|
5
|
+
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&display=swap');
|
|
6
|
+
</style>
|
|
7
|
+
<filter id="shadow" x="-5%" y="-5%" width="115%" height="115%">
|
|
8
|
+
<feDropShadow dx="0" dy="4" stdDeviation="8" flood-color="#000" flood-opacity="0.4"/>
|
|
9
|
+
</filter>
|
|
10
|
+
</defs>
|
|
11
|
+
|
|
12
|
+
<rect width="100%" height="100%" fill="#0d0d1a"/>
|
|
13
|
+
|
|
14
|
+
<!-- Window -->
|
|
15
|
+
<rect x="12" y="10" width="876" height="783" fill="#1e1e2e" rx="8" filter="url(#shadow)"/>
|
|
16
|
+
<rect x="12" y="10" width="876" height="36" fill="#181825" rx="8"/>
|
|
17
|
+
<rect x="12" y="46" width="876" height="2" fill="#313244"/>
|
|
18
|
+
|
|
19
|
+
<!-- Traffic lights -->
|
|
20
|
+
<circle cx="24" cy="28" r="5" fill="#f38ba8"/>
|
|
21
|
+
<circle cx="42" cy="28" r="5" fill="#f9e2af"/>
|
|
22
|
+
<circle cx="60" cy="28" r="5" fill="#a6e3a1"/>
|
|
23
|
+
<text x="450" y="34" fill="#6c7086" font-family="'JetBrains Mono','Fira Code',monospace" font-size="13" text-anchor="middle">search-cli — terminal GitHub browser</text>
|
|
24
|
+
|
|
25
|
+
<g font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">
|
|
26
|
+
<text x="14" y="62" fill="#6c7086" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">search-cli — GitHub repo browser [t]rending [/]search [g]raph [r]efresh [q]uit</text>
|
|
27
|
+
<rect x="14" y="69" width="860" height="54.5" fill="#1e1e2e" stroke="#89b4fa" stroke-width="1" rx="3"/>
|
|
28
|
+
<text x="22" y="88" fill="#89b4fa" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">> language:TypeScript stars:>1000</text>
|
|
29
|
+
<text x="14" y="150.2" fill="#6c7086" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">sort: stars limit: 50 (s=cycle sort l=cycle limit)</text>
|
|
30
|
+
<rect x="14" y="159.3" width="432" height="378" fill="#1e1e2e" stroke="#45475a" stroke-width="1" rx="3"/>
|
|
31
|
+
<text x="22" y="177.5" fill="#89b4fa" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14"> Results </text>
|
|
32
|
+
<rect x="18" y="178.20000000000002" width="424" height="20" fill="#2d5bcf" rx="3"/>
|
|
33
|
+
<text x="24" y="198.5" fill="#ffffff" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">shadcn/ui ★ 78.5k</text>
|
|
34
|
+
<text x="24" y="221.6" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">vercel/next.js ★ 129k</text>
|
|
35
|
+
<text x="24" y="244.7" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">tailwindlabs/tailwindcss ★ 84.2k</text>
|
|
36
|
+
<text x="24" y="267.8" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">tauri-apps/tauri ★ 84.1k</text>
|
|
37
|
+
<text x="24" y="290.9" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">oven-sh/bun ★ 74.5k</text>
|
|
38
|
+
<text x="24" y="314" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">n8n-io/n8n ★ 54.4k</text>
|
|
39
|
+
<text x="24" y="337.1" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">astral-sh/ruff ★ 36.1k</text>
|
|
40
|
+
<text x="24" y="360.20000000000005" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">missive/emoji-mart ★ 8.8k</text>
|
|
41
|
+
<text x="24" y="383.3" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">sharkdp/bat ★ 50.3k</text>
|
|
42
|
+
<text x="24" y="406.4" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">BurntSushi/ripgrep ★ 48.8k</text>
|
|
43
|
+
<text x="24" y="429.5" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">jdx/mise ★ 14.3k</text>
|
|
44
|
+
<text x="24" y="452.6" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">nektos/act ★ 56.1k</text>
|
|
45
|
+
<text x="24" y="475.70000000000005" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">astral-sh/uv ★ 40.2k</text>
|
|
46
|
+
<text x="24" y="498.8" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">zed-industries/zed ★ 52k</text>
|
|
47
|
+
<rect x="450" y="159.3" width="432" height="378" fill="#1e1e2e" stroke="#45475a" stroke-width="1" rx="3"/>
|
|
48
|
+
<text x="456" y="177.5" fill="#a6e3a1" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14"> Details </text>
|
|
49
|
+
<text x="458" y="198.5" fill="#6c7086" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">Name shadcn/ui</text>
|
|
50
|
+
<text x="458" y="221.6" fill="#6c7086" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">Stars 78,500</text>
|
|
51
|
+
<text x="458" y="244.7" fill="#6c7086" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">Forks 4,200</text>
|
|
52
|
+
<text x="458" y="267.8" fill="#6c7086" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">Lang TypeScript</text>
|
|
53
|
+
<text x="458" y="290.9" fill="#6c7086" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">Updated 2026-07-12</text>
|
|
54
|
+
<text x="458" y="314" fill="#6c7086" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">Topics react, ui, components, shadcn</text>
|
|
55
|
+
<text x="458" y="360.20000000000005" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">Beautifully designed components built with Radix UI and</text>
|
|
56
|
+
<text x="458" y="383.3" fill="#cdd6f4" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">Tailwind CSS.</text>
|
|
57
|
+
<text x="458" y="429.5" fill="#89b4fa" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">https://github.com/shadcn/ui</text>
|
|
58
|
+
<rect x="14" y="489" width="860" height="25" fill="#181825" rx="3"/>
|
|
59
|
+
<rect x="14" y="489" width="860" height="2" fill="#45475a"/>
|
|
60
|
+
<text x="18" y="521.9" fill="#6c7086" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">15,842 results (↑↓ nav Enter open o browser Ctrl+R history)</text>
|
|
61
|
+
<rect x="338.79999999999995" y="70" width="5.76" height="16" fill="#89b4fa" opacity="0.8">
|
|
62
|
+
<animate attributeName="opacity" values="0.8;0.1;0.8" dur="1s" repeatCount="indefinite"/>
|
|
63
|
+
</rect>
|
|
64
|
+
|
|
65
|
+
</g>
|
|
66
66
|
</svg>
|
package/package.json
CHANGED
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "github-search-cli",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"description": "Terminal-native GitHub search — search, trending, bookmarks, history, deep-dive, compare, export, and more. All keyboard-driven, no browser needed.",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"packageManager": "bun@1",
|
|
7
|
+
"volta": {
|
|
8
|
+
"extensions": [".ts"]
|
|
9
|
+
},
|
|
6
10
|
"bin": {
|
|
7
11
|
"ghfind": "bin/ghfind.js"
|
|
8
12
|
},
|
|
13
|
+
"bun": {
|
|
14
|
+
"smol": true
|
|
15
|
+
},
|
|
9
16
|
"files": [
|
|
10
17
|
"bin/",
|
|
11
18
|
"src/",
|
|
19
|
+
"scripts/",
|
|
12
20
|
"completions/",
|
|
13
21
|
"demo.svg",
|
|
14
22
|
"LICENSE",
|
|
@@ -16,12 +24,13 @@
|
|
|
16
24
|
],
|
|
17
25
|
"scripts": {
|
|
18
26
|
"start": "bun run src/cli.ts",
|
|
19
|
-
"build": "tsup
|
|
20
|
-
"prepublishOnly": "
|
|
21
|
-
"test": "
|
|
27
|
+
"build": "tsup",
|
|
28
|
+
"prepublishOnly": "bun run build",
|
|
29
|
+
"test": "bun test",
|
|
22
30
|
"dev": "bun run --watch src/tui.ts",
|
|
23
|
-
"
|
|
24
|
-
"format": "prettier --
|
|
31
|
+
"postinstall": "node scripts/postinstall.js",
|
|
32
|
+
"format:check": "bunx prettier --check .",
|
|
33
|
+
"format": "bunx prettier --write ."
|
|
25
34
|
},
|
|
26
35
|
"dependencies": {
|
|
27
36
|
"@opentui/core": "^0.4.3"
|
|
@@ -31,12 +40,11 @@
|
|
|
31
40
|
"@types/node": "^20.0.0",
|
|
32
41
|
"prettier": "^3.2.0",
|
|
33
42
|
"tsup": "^8.0.0",
|
|
34
|
-
"
|
|
35
|
-
"typescript": "^5.3.0",
|
|
36
|
-
"vitest": "^1.2.0"
|
|
43
|
+
"typescript": "^5.3.0"
|
|
37
44
|
},
|
|
38
45
|
"engines": {
|
|
39
|
-
"node": ">=20.0.0"
|
|
46
|
+
"node": ">=20.0.0",
|
|
47
|
+
"bun": ">=1.0.0"
|
|
40
48
|
},
|
|
41
49
|
"repository": {
|
|
42
50
|
"type": "git",
|
package/scripts/brew.rb
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
class SearchCli < Formula
|
|
5
|
+
desc "Interactive GitHub repository browser for the terminal"
|
|
6
|
+
homepage "https://github.com/frank/search-cli"
|
|
7
|
+
version "0.1.0"
|
|
8
|
+
license "MIT"
|
|
9
|
+
|
|
10
|
+
on_macos do
|
|
11
|
+
if Hardware::CPU.arm?
|
|
12
|
+
url "https://github.com/frank/search-cli/releases/download/v#{version}/search-cli-darwin-arm64"
|
|
13
|
+
sha256 "SHA256_PLACEHOLDER"
|
|
14
|
+
else
|
|
15
|
+
url "https://github.com/frank/search-cli/releases/download/v#{version}/search-cli-darwin-x64"
|
|
16
|
+
sha256 "SHA256_PLACEHOLDER"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
on_linux do
|
|
21
|
+
url "https://github.com/frank/search-cli/releases/download/v#{version}/search-cli-linux-x64"
|
|
22
|
+
sha256 "SHA256_PLACEHOLDER"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def install
|
|
26
|
+
bin.install "search-cli"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
test do
|
|
30
|
+
assert_match "search-cli", shell_output("#{bin}/search-cli --version")
|
|
31
|
+
end
|
|
32
|
+
end
|
package/scripts/build.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build script — compile ghfind for distribution.
|
|
3
|
+
* Usage: npm run build
|
|
4
|
+
*/
|
|
5
|
+
import { execFileSync } from "child_process";
|
|
6
|
+
|
|
7
|
+
async function main() {
|
|
8
|
+
console.log("Building ghfind...");
|
|
9
|
+
|
|
10
|
+
// ESM bundle via tsup
|
|
11
|
+
execFileSync("npx", ["tsup", "src/cli.ts", "--format", "esm", "--target", "node20", "--out-dir", "dist", "--external", "@opentui/core"], { stdio: "inherit" });
|
|
12
|
+
|
|
13
|
+
console.log("✓ dist/cli.js (Node.js ESM bundle)");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
main().catch((err) => {
|
|
17
|
+
console.error("Build failed:", err.message);
|
|
18
|
+
process.exit(1);
|
|
19
|
+
});
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Generate an SVG screenshot of ghfind matching the actual TUI layout.
|
|
4
|
+
* Single frame with blinking cursor — honest and accurate.
|
|
5
|
+
*
|
|
6
|
+
* Usage: node scripts/generate-svg-demo.js > demo.svg
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const C = {
|
|
10
|
+
bg: "#1e1e2e",
|
|
11
|
+
surface: "#181825",
|
|
12
|
+
text: "#cdd6f4",
|
|
13
|
+
muted: "#6c7086",
|
|
14
|
+
blue: "#89b4fa",
|
|
15
|
+
green: "#a6e3a1",
|
|
16
|
+
yellow: "#f9e2af",
|
|
17
|
+
red: "#f38ba8",
|
|
18
|
+
teal: "#94e2d5",
|
|
19
|
+
border: "#45475a",
|
|
20
|
+
selBg: "#2d5bcf",
|
|
21
|
+
selText: "#ffffff",
|
|
22
|
+
star: "#f9e2af",
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const FW = 9.6, FH = 21, PX = 14, PY = 12, WIN_H = 36;
|
|
26
|
+
const W = 90, H = 35;
|
|
27
|
+
const SW = Math.round(W * FW + PX * 2 + 8);
|
|
28
|
+
const SH = Math.round(H * FH + PY * 2 + WIN_H + 8);
|
|
29
|
+
|
|
30
|
+
const esc = s => String(s).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");
|
|
31
|
+
|
|
32
|
+
const repos = [
|
|
33
|
+
{fn:"shadcn/ui",s:78500,l:"TypeScript"},
|
|
34
|
+
{fn:"vercel/next.js",s:129000,l:"TypeScript"},
|
|
35
|
+
{fn:"tailwindlabs/tailwindcss",s:84200,l:"CSS"},
|
|
36
|
+
{fn:"tauri-apps/tauri",s:84100,l:"Rust"},
|
|
37
|
+
{fn:"oven-sh/bun",s:74500,l:"Zig"},
|
|
38
|
+
{fn:"n8n-io/n8n",s:54400,l:"TypeScript"},
|
|
39
|
+
{fn:"astral-sh/ruff",s:36100,l:"Rust"},
|
|
40
|
+
{fn:"missive/emoji-mart",s:8800,l:"TypeScript"},
|
|
41
|
+
{fn:"sharkdp/bat",s:50300,l:"Rust"},
|
|
42
|
+
{fn:"BurntSushi/ripgrep",s:48800,l:"Rust"},
|
|
43
|
+
{fn:"jdx/mise",s:14300,l:"Rust"},
|
|
44
|
+
{fn:"nektos/act",s:56100,l:"Go"},
|
|
45
|
+
{fn:"astral-sh/uv",s:40200,l:"Rust"},
|
|
46
|
+
{fn:"zed-industries/zed",s:52000,l:"Rust"},
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
const f = n => n >= 1000 ? `★ ${(n/1000).toFixed(1).replace(/\.0$/,"")}k` : `★ ${n}`;
|
|
50
|
+
const num = n => n.toLocaleString();
|
|
51
|
+
|
|
52
|
+
function tx(x, y, text, fill, cls="") {
|
|
53
|
+
const c = cls ? ` class="${cls}"` : "";
|
|
54
|
+
return `<text x="${x}" y="${y}" fill="${fill}" font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14"${c}>${esc(text)}</text>\n`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function rx(x, y, w, h, fill, stroke="", r=0) {
|
|
58
|
+
const s = stroke ? ` stroke="${stroke}" stroke-width="1"` : "";
|
|
59
|
+
const rc = r ? ` rx="${r}"` : "";
|
|
60
|
+
return `<rect x="${x}" y="${y}" width="${w}" height="${h}" fill="${fill}"${s}${rc}/>\n`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let svg = "";
|
|
64
|
+
|
|
65
|
+
// ─── Header ──
|
|
66
|
+
svg += tx(PX, PY+WIN_H+14, "ghfind — GitHub repo browser [t]rending [/]search [g]raph [r]efresh [q]uit", C.muted);
|
|
67
|
+
|
|
68
|
+
// ─── Search box (blue border, 3 lines height) ──
|
|
69
|
+
const sbY = PY+WIN_H+1*FH;
|
|
70
|
+
svg += rx(PX, sbY, W*FW-4, FH*2.5+2, C.bg, C.blue, 3);
|
|
71
|
+
svg += tx(PX+8, sbY+FH-2, "> language:TypeScript stars:>1000", C.blue);
|
|
72
|
+
|
|
73
|
+
// ─── Toolbar ──
|
|
74
|
+
svg += tx(PX, PY+WIN_H+4.2*FH+14, "sort: stars limit: 50 (s=cycle sort l=cycle limit)", C.muted);
|
|
75
|
+
|
|
76
|
+
// ─── Body: Results (left) + Detail (right) ──
|
|
77
|
+
const bY = 5.5;
|
|
78
|
+
const paneW = (W*FW-8)/2;
|
|
79
|
+
const pH = 18;
|
|
80
|
+
|
|
81
|
+
// Left pane background
|
|
82
|
+
svg += rx(PX, PY+WIN_H+(bY-0.2)*FH, paneW+4, pH*FH, C.bg, C.border, 3);
|
|
83
|
+
svg += tx(PX+8, PY+WIN_H+(bY)*FH+14, " Results ", C.blue);
|
|
84
|
+
|
|
85
|
+
// Results list
|
|
86
|
+
repos.forEach((r, i) => {
|
|
87
|
+
if (i >= 14) return;
|
|
88
|
+
const ry = bY + 1 + i * 1.1;
|
|
89
|
+
const isSel = i === 0;
|
|
90
|
+
if (isSel) {
|
|
91
|
+
svg += rx(PX+4, PY+WIN_H+(ry-0.3)*FH, paneW-4, FH-1, C.selBg, "", 3);
|
|
92
|
+
}
|
|
93
|
+
const fgc = isSel ? C.selText : C.text;
|
|
94
|
+
const line = `${r.fn} ${f(r.s)}`;
|
|
95
|
+
svg += tx(PX+10, PY+WIN_H+ry*FH+14, line, fgc);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Right pane background
|
|
99
|
+
svg += rx(PX+paneW+8, PY+WIN_H+(bY-0.2)*FH, paneW+4, pH*FH, C.bg, C.border, 3);
|
|
100
|
+
svg += tx(PX+paneW+14, PY+WIN_H+(bY)*FH+14, " Details ", C.green);
|
|
101
|
+
|
|
102
|
+
// Detail content (matches actual format from tui.ts line ~685)
|
|
103
|
+
const detail = [
|
|
104
|
+
`Name shadcn/ui`,
|
|
105
|
+
`Stars ${num(78500)}`,
|
|
106
|
+
`Forks ${num(4200)}`,
|
|
107
|
+
`Lang TypeScript`,
|
|
108
|
+
`Updated 2026-07-12`,
|
|
109
|
+
`Topics react, ui, components, shadcn`,
|
|
110
|
+
``,
|
|
111
|
+
`Beautifully designed components built with Radix UI and`,
|
|
112
|
+
`Tailwind CSS.`,
|
|
113
|
+
``,
|
|
114
|
+
`https://github.com/shadcn/ui`,
|
|
115
|
+
];
|
|
116
|
+
|
|
117
|
+
detail.forEach((line, i) => {
|
|
118
|
+
if (line === "") return;
|
|
119
|
+
const ry = bY + 1 + i * 1.1;
|
|
120
|
+
let fgc = C.text;
|
|
121
|
+
if (i <= 5) fgc = C.muted;
|
|
122
|
+
if (line.startsWith("http")) fgc = C.blue;
|
|
123
|
+
svg += tx(PX+paneW+16, PY+WIN_H+ry*FH+14, line, fgc);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
// ─── Bottom status bar ──
|
|
127
|
+
svg += rx(PX, PY+WIN_H+21*FH, W*FW-4, FH+4, C.surface, "", 3);
|
|
128
|
+
svg += rx(PX, PY+WIN_H+21*FH, W*FW-4, 2, C.border);
|
|
129
|
+
svg += tx(PX+4, PY+WIN_H+21.9*FH+14, "15,842 results (↑↓ nav Enter open o browser Ctrl+R history)", C.muted);
|
|
130
|
+
|
|
131
|
+
// ─── Cursor blinking after query text ──
|
|
132
|
+
const queryText = "language:TypeScript stars:>1000";
|
|
133
|
+
const cursorX = PX + 8 + 2 * FW + queryText.length * FW;
|
|
134
|
+
svg += `<rect x="${cursorX}" y="${PY + WIN_H + 1 * FH + 1}" width="${FW * 0.6}" height="16" fill="${C.blue}" opacity="0.8">
|
|
135
|
+
<animate attributeName="opacity" values="0.8;0.1;0.8" dur="1s" repeatCount="indefinite"/>
|
|
136
|
+
</rect>\n`;
|
|
137
|
+
|
|
138
|
+
// ─── Assemble ──
|
|
139
|
+
const output = `<?xml version="1.0" encoding="UTF-8"?>
|
|
140
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${SW} ${SH}" width="${SW}" height="${SH}">
|
|
141
|
+
<defs>
|
|
142
|
+
<style>
|
|
143
|
+
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&display=swap');
|
|
144
|
+
</style>
|
|
145
|
+
<filter id="shadow" x="-5%" y="-5%" width="115%" height="115%">
|
|
146
|
+
<feDropShadow dx="0" dy="4" stdDeviation="8" flood-color="#000" flood-opacity="0.4"/>
|
|
147
|
+
</filter>
|
|
148
|
+
</defs>
|
|
149
|
+
|
|
150
|
+
<rect width="100%" height="100%" fill="#0d0d1a"/>
|
|
151
|
+
|
|
152
|
+
<!-- Window -->
|
|
153
|
+
<rect x="${PX-2}" y="${PY-2}" width="${SW-PX*2+4}" height="${SH-PY*2+4}" fill="${C.bg}" rx="8" filter="url(#shadow)"/>
|
|
154
|
+
<rect x="${PX-2}" y="${PY-2}" width="${SW-PX*2+4}" height="36" fill="${C.surface}" rx="8"/>
|
|
155
|
+
<rect x="${PX-2}" y="${PY+34}" width="${SW-PX*2+4}" height="2" fill="#313244"/>
|
|
156
|
+
|
|
157
|
+
<!-- Traffic lights -->
|
|
158
|
+
<circle cx="${PX+10}" cy="${PY+16}" r="5" fill="#f38ba8"/>
|
|
159
|
+
<circle cx="${PX+28}" cy="${PY+16}" r="5" fill="#f9e2af"/>
|
|
160
|
+
<circle cx="${PX+46}" cy="${PY+16}" r="5" fill="#a6e3a1"/>
|
|
161
|
+
<text x="${SW/2}" y="${PY+22}" fill="${C.muted}" font-family="'JetBrains Mono','Fira Code',monospace" font-size="13" text-anchor="middle">ghfind — terminal GitHub browser</text>
|
|
162
|
+
|
|
163
|
+
<g font-family="'JetBrains Mono','Fira Code','Cascadia Code',monospace" font-size="14">
|
|
164
|
+
${svg}
|
|
165
|
+
</g>
|
|
166
|
+
</svg>`;
|
|
167
|
+
|
|
168
|
+
process.stdout.write(output);
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Postinstall script — ensures a Bun binary is available for ghfind.
|
|
4
|
+
*
|
|
5
|
+
* If vendor/bun or vendor/bun.exe already exists (bundled with the package),
|
|
6
|
+
* this is a no-op. Otherwise, it attempts to download the correct binary
|
|
7
|
+
* for the user's platform.
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, mkdirSync, chmodSync, writeFileSync } from "fs";
|
|
10
|
+
import { join, dirname } from "path";
|
|
11
|
+
import { fileURLToPath } from "url";
|
|
12
|
+
import { platform, arch } from "os";
|
|
13
|
+
import { inflateRawSync } from "zlib";
|
|
14
|
+
|
|
15
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
16
|
+
const ROOT = join(__dirname, "..");
|
|
17
|
+
const VENDOR_DIR = join(ROOT, "vendor");
|
|
18
|
+
|
|
19
|
+
const bunName = platform() === "win32" ? "bun.exe" : "bun";
|
|
20
|
+
const bunPath = join(VENDOR_DIR, bunName);
|
|
21
|
+
|
|
22
|
+
// Already bundled — nothing to do
|
|
23
|
+
if (existsSync(bunPath)) {
|
|
24
|
+
process.exit(0);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Skip in CI/test environments
|
|
28
|
+
if (process.env.GHFIND_SKIP_BUN === "1" || process.env.CI === "true") {
|
|
29
|
+
process.exit(0);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Try to download
|
|
33
|
+
const map = {
|
|
34
|
+
"win32-x64": "bun-windows-x64.zip",
|
|
35
|
+
"win32-arm64": "bun-windows-aarch64.zip",
|
|
36
|
+
"darwin-x64": "bun-darwin-x64.zip",
|
|
37
|
+
"darwin-arm64": "bun-darwin-aarch64.zip",
|
|
38
|
+
"linux-x64": "bun-linux-x64-musl.zip",
|
|
39
|
+
"linux-arm64": "bun-linux-aarch64-musl.zip",
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const key = `${platform()}-${arch}`;
|
|
43
|
+
const assetName = map[key];
|
|
44
|
+
const version = "1.3.12";
|
|
45
|
+
|
|
46
|
+
if (!assetName) {
|
|
47
|
+
console.error(`[ghfind] Unsupported platform: ${key}. Install Bun manually: https://bun.sh`);
|
|
48
|
+
process.exit(0);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const url = `https://github.com/oven-sh/bun/releases/download/bun-v${version}/${assetName}`;
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
mkdirSync(VENDOR_DIR, { recursive: true });
|
|
55
|
+
console.error(`[ghfind] Downloading Bun ${version} for ${key}...`);
|
|
56
|
+
|
|
57
|
+
const res = await fetch(url);
|
|
58
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
59
|
+
|
|
60
|
+
const buffer = Buffer.from(await res.arrayBuffer());
|
|
61
|
+
|
|
62
|
+
// Find the central directory file header signature (PK\x01\x02)
|
|
63
|
+
const cdSig = "PK\x01\x02";
|
|
64
|
+
let cdOffset = buffer.indexOf(cdSig, 0);
|
|
65
|
+
while (cdOffset !== -1) {
|
|
66
|
+
const nameLen = buffer.readUInt16LE(cdOffset + 28);
|
|
67
|
+
const extraLen = buffer.readUInt16LE(cdOffset + 30);
|
|
68
|
+
const commentLen = buffer.readUInt16LE(cdOffset + 32);
|
|
69
|
+
const localHeaderOffset = buffer.readUInt32LE(cdOffset + 42);
|
|
70
|
+
const compSize = buffer.readUInt32LE(cdOffset + 20);
|
|
71
|
+
const compMethod = buffer.readUInt16LE(cdOffset + 10);
|
|
72
|
+
const nameStart = cdOffset + 46;
|
|
73
|
+
const fileName = buffer.subarray(nameStart, nameStart + nameLen).toString("utf8");
|
|
74
|
+
|
|
75
|
+
if (fileName.endsWith(bunName)) {
|
|
76
|
+
// Read the local file header to get the actual data offset
|
|
77
|
+
const localSig = buffer.readUInt32LE(localHeaderOffset);
|
|
78
|
+
if (localSig !== 0x04034b50) throw new Error("Invalid local file header");
|
|
79
|
+
const localNameLen = buffer.readUInt16LE(localHeaderOffset + 26);
|
|
80
|
+
const localExtraLen = buffer.readUInt16LE(localHeaderOffset + 28);
|
|
81
|
+
const dataOffset = localHeaderOffset + 30 + localNameLen + localExtraLen;
|
|
82
|
+
|
|
83
|
+
let fileData;
|
|
84
|
+
if (compMethod === 0) {
|
|
85
|
+
// Stored (no compression)
|
|
86
|
+
fileData = buffer.subarray(dataOffset, dataOffset + compSize);
|
|
87
|
+
} else {
|
|
88
|
+
// Deflated
|
|
89
|
+
fileData = inflateRawSync(buffer.subarray(dataOffset, dataOffset + compSize));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
writeFileSync(bunPath, fileData);
|
|
93
|
+
if (platform() !== "win32") chmodSync(bunPath, 0o755);
|
|
94
|
+
console.error(`[ghfind] Bun installed to vendor/${bunName}`);
|
|
95
|
+
process.exit(0);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
cdOffset = buffer.indexOf(cdSig, cdOffset + 4);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
throw new Error("Bun binary not found in archive");
|
|
102
|
+
} catch (err) {
|
|
103
|
+
console.error(`[ghfind] Failed to download Bun: ${err instanceof Error ? err.message : String(err)}`);
|
|
104
|
+
console.error("[ghfind] Install Bun manually: https://bun.sh/docs/install");
|
|
105
|
+
process.exit(0);
|
|
106
|
+
}
|