github-search-cli 9.7.0 → 9.7.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 +29 -0
- package/README.md +7 -5
- package/bin/ghfind.js +5 -5
- package/dist/cli.js +255 -110
- package/package.json +3 -2
- package/release-notes/9.7.1.md +62 -0
- package/scripts/build.ts +1 -1
- package/scripts/postinstall.js +8 -8
- package/src/cli.ts +21 -13
- package/src/compare.ts +5 -5
- package/src/config.ts +3 -3
- package/src/deepdive.ts +0 -1
- package/src/doctor.ts +144 -8
- package/src/error-report.ts +14 -8
- package/src/export.ts +1 -1
- package/src/history.ts +5 -5
- package/src/init.ts +2 -2
- package/src/login.ts +4 -4
- package/src/markdown-render.ts +13 -13
- package/src/mcp-server.ts +4 -3
- package/src/open-url.ts +16 -5
- package/src/output.ts +1 -1
- package/src/package-browser.ts +1 -1
- package/src/releases.ts +1 -14
- package/src/search-state.ts +1 -4
- package/src/search.ts +3 -4
- package/src/share.ts +2 -2
- package/src/storage.ts +4 -4
- package/src/themes.ts +1 -0
- package/src/trending-parser.ts +3 -4
- package/src/trending.ts +7 -7
- package/src/tui.ts +38 -42
- package/src/update-check.ts +96 -34
- package/src/version.ts +3 -3
- package/src/watch.ts +1 -1
package/dist/cli.js
CHANGED
|
@@ -62,14 +62,14 @@ function flattenHtml(html) {
|
|
|
62
62
|
}
|
|
63
63
|
function parseRepoLink(block) {
|
|
64
64
|
const anchor = block.match(
|
|
65
|
-
/<a[^>]*?href="\/([A-Za-z0-9._-]+)\/([
|
|
65
|
+
/<a[^>]*?href="\/([A-Za-z0-9._-]+)\/([^"?#]+)"[^>]*class="Link"/
|
|
66
66
|
);
|
|
67
67
|
if (!anchor) return void 0;
|
|
68
68
|
return { owner: anchor[1], name: anchor[2] };
|
|
69
69
|
}
|
|
70
70
|
function parseStars(block) {
|
|
71
71
|
const starsMatch = block.match(
|
|
72
|
-
/href="\/[
|
|
72
|
+
/href="\/[^/"]+\/[^/"]+\/stargazers"[^>]*>.*?<\/svg>\s*(\d[\d,]*)/
|
|
73
73
|
);
|
|
74
74
|
return starsMatch ? parseInt(starsMatch[1].replace(/,/g, ""), 10) : 0;
|
|
75
75
|
}
|
|
@@ -91,9 +91,8 @@ function parseTrendingHtml(html) {
|
|
|
91
91
|
const flat = flattenHtml(html);
|
|
92
92
|
const repos = [];
|
|
93
93
|
const articleRe = /<article class="Box-row">(.*?)<\/article>/gi;
|
|
94
|
-
let match;
|
|
95
94
|
let rank = 0;
|
|
96
|
-
|
|
95
|
+
for (const match of flat.matchAll(articleRe)) {
|
|
97
96
|
rank++;
|
|
98
97
|
const block = match[1];
|
|
99
98
|
const link = parseRepoLink(block);
|
|
@@ -240,7 +239,7 @@ function suggestFor(input) {
|
|
|
240
239
|
return QUALIFIER_SUGGESTIONS[trimmed];
|
|
241
240
|
}
|
|
242
241
|
const matches = KNOWN_QUALIFIERS.filter((k) => k.startsWith(trimmed));
|
|
243
|
-
return matches.map((k) => k
|
|
242
|
+
return matches.map((k) => `${k}:`);
|
|
244
243
|
}
|
|
245
244
|
function tokenize(input) {
|
|
246
245
|
const tokens = [];
|
|
@@ -353,7 +352,6 @@ function githubSortParam(sort) {
|
|
|
353
352
|
return { sort: "forks", order: "desc" };
|
|
354
353
|
case "updated":
|
|
355
354
|
return { sort: "updated", order: "desc" };
|
|
356
|
-
case "best-match":
|
|
357
355
|
default:
|
|
358
356
|
return {};
|
|
359
357
|
}
|
|
@@ -378,7 +376,6 @@ function rankRepos(repos, strategy) {
|
|
|
378
376
|
case "updated":
|
|
379
377
|
copy.sort(byKey((r) => Date.parse(r.updatedAt)));
|
|
380
378
|
break;
|
|
381
|
-
case "best-match":
|
|
382
379
|
default:
|
|
383
380
|
break;
|
|
384
381
|
}
|
|
@@ -585,6 +582,7 @@ function trendingRepoToRepo(r) {
|
|
|
585
582
|
}
|
|
586
583
|
var TrendingAdapter = class {
|
|
587
584
|
name = "trending";
|
|
585
|
+
// biome-ignore lint/correctness/noUnusedPrivateClassMembers: part of the adapter constructor contract — callers pass a shared logger (search.ts:757) even though this adapter currently logs nothing itself.
|
|
588
586
|
logger;
|
|
589
587
|
constructor(logger2 = noopLogger) {
|
|
590
588
|
this.logger = logger2;
|
|
@@ -740,12 +738,17 @@ import {
|
|
|
740
738
|
} from "@opentui/core";
|
|
741
739
|
|
|
742
740
|
// src/open-url.ts
|
|
741
|
+
import { spawn } from "child_process";
|
|
743
742
|
function openUrl(url) {
|
|
744
743
|
try {
|
|
745
744
|
const p = process.platform;
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
745
|
+
const cmd = p === "win32" ? "explorer" : p === "darwin" ? "open" : "xdg-open";
|
|
746
|
+
if (typeof Bun !== "undefined") {
|
|
747
|
+
Bun.spawn([cmd, url]);
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
const child = spawn(cmd, [url], { detached: true, stdio: "ignore" });
|
|
751
|
+
child.unref();
|
|
749
752
|
} catch {
|
|
750
753
|
}
|
|
751
754
|
}
|
|
@@ -935,7 +938,7 @@ function formatPackageLine(pack) {
|
|
|
935
938
|
const nameStr = `${pack.name}@${pack.version}`.padEnd(28).slice(0, 28);
|
|
936
939
|
const dlStr = `\u2193 ${fmtCount(pack.downloads)}`.padEnd(20).slice(0, 20);
|
|
937
940
|
const scoreStr = `score ${pack.score.toFixed(2)}`.padEnd(12).slice(0, 12);
|
|
938
|
-
const desc = (pack.description ?? "").length > 60 ? (pack.description ?? "").slice(0, 57)
|
|
941
|
+
const desc = (pack.description ?? "").length > 60 ? `${(pack.description ?? "").slice(0, 57)}...` : pack.description ?? "";
|
|
939
942
|
const line1 = t`${bold(fg(C.nameText)(nameStr))}${fg(C.cyan)(dlStr)}${fg(C.gold)(scoreStr)}`;
|
|
940
943
|
const line2 = t`${dim(fg(C.descText)(` ${desc}`))}`;
|
|
941
944
|
const newline = { text: "\n", __isChunk: true };
|
|
@@ -1198,9 +1201,13 @@ var results = [];
|
|
|
1198
1201
|
function add(status, label, detail) {
|
|
1199
1202
|
results.push({ status, label, detail });
|
|
1200
1203
|
}
|
|
1201
|
-
function run(cmd, args) {
|
|
1204
|
+
function run(cmd, args, opts = {}) {
|
|
1202
1205
|
try {
|
|
1203
|
-
const res = spawnSync(cmd, args, {
|
|
1206
|
+
const res = spawnSync(cmd, args, {
|
|
1207
|
+
encoding: "utf8",
|
|
1208
|
+
timeout: 15e3,
|
|
1209
|
+
...opts
|
|
1210
|
+
});
|
|
1204
1211
|
return {
|
|
1205
1212
|
status: res.status,
|
|
1206
1213
|
stdout: res.stdout ?? "",
|
|
@@ -1375,6 +1382,97 @@ function checkDirs() {
|
|
|
1375
1382
|
}
|
|
1376
1383
|
}
|
|
1377
1384
|
}
|
|
1385
|
+
var PKG_NAME = "github-search-cli";
|
|
1386
|
+
var BIN_NAME = "ghfind";
|
|
1387
|
+
function runningVersion() {
|
|
1388
|
+
try {
|
|
1389
|
+
const pkg = JSON.parse(
|
|
1390
|
+
readFileSync(join(PKG_DIR, "package.json"), "utf8")
|
|
1391
|
+
);
|
|
1392
|
+
return pkg.version ?? "";
|
|
1393
|
+
} catch {
|
|
1394
|
+
return "";
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
function installVersionAt(shimPath) {
|
|
1398
|
+
const dir = dirname(shimPath);
|
|
1399
|
+
for (const ancestor of [dir, dirname(dir)]) {
|
|
1400
|
+
for (const sub of ["node_modules", join("lib", "node_modules")]) {
|
|
1401
|
+
const pkgJson = join(ancestor, sub, PKG_NAME, "package.json");
|
|
1402
|
+
if (existsSync(pkgJson)) {
|
|
1403
|
+
try {
|
|
1404
|
+
const pkg = JSON.parse(readFileSync(pkgJson, "utf8"));
|
|
1405
|
+
return { version: pkg.version ?? "", dir: dirname(pkgJson) };
|
|
1406
|
+
} catch {
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
const res = run(shimPath, ["--version"], {
|
|
1412
|
+
shell: platform() === "win32",
|
|
1413
|
+
timeout: 1e4
|
|
1414
|
+
});
|
|
1415
|
+
const m = /\d+\.\d+\.\d+/.exec(res.stdout);
|
|
1416
|
+
return m ? { version: m[0], dir } : null;
|
|
1417
|
+
}
|
|
1418
|
+
function checkInstallShadowing() {
|
|
1419
|
+
const isWin = platform() === "win32";
|
|
1420
|
+
const res = isWin ? run("where", [BIN_NAME]) : run("which", ["-a", BIN_NAME]);
|
|
1421
|
+
const shims = [
|
|
1422
|
+
...new Set(
|
|
1423
|
+
res.stdout.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0)
|
|
1424
|
+
)
|
|
1425
|
+
];
|
|
1426
|
+
if (shims.length === 0) {
|
|
1427
|
+
add("WARN", "Global installs", `${BIN_NAME} not found on PATH.`);
|
|
1428
|
+
return;
|
|
1429
|
+
}
|
|
1430
|
+
const running = runningVersion();
|
|
1431
|
+
const norm = (p) => isWin ? p.replace(/\\/g, "/").toLowerCase() : p;
|
|
1432
|
+
const seenDirs = /* @__PURE__ */ new Set();
|
|
1433
|
+
const stale = [];
|
|
1434
|
+
let knownCount = 0;
|
|
1435
|
+
let staleVersion = "";
|
|
1436
|
+
let staleDir = "";
|
|
1437
|
+
for (const shim of shims) {
|
|
1438
|
+
const info = installVersionAt(shim);
|
|
1439
|
+
const dirKey = norm(dirname(shim));
|
|
1440
|
+
if (seenDirs.has(dirKey)) continue;
|
|
1441
|
+
seenDirs.add(dirKey);
|
|
1442
|
+
knownCount++;
|
|
1443
|
+
const isRunningInstall = info !== null && norm(info.dir) === norm(PKG_DIR);
|
|
1444
|
+
if (!isRunningInstall && info !== null && running && info.version !== running) {
|
|
1445
|
+
stale.push(`${dirname(shim)} (v${info.version} \u2260 running v${running})`);
|
|
1446
|
+
staleVersion = info.version;
|
|
1447
|
+
staleDir = dirname(shim);
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
if (stale.length > 0 && knownCount > 1) {
|
|
1451
|
+
add(
|
|
1452
|
+
"WARN",
|
|
1453
|
+
"Global installs",
|
|
1454
|
+
`${knownCount} install(s) on PATH; stale copies shadowing updates \u2192 ${stale.join("; ")}. Remove with: npm uninstall -g ${PKG_NAME} --prefix <dir>`
|
|
1455
|
+
);
|
|
1456
|
+
} else if (stale.length > 0) {
|
|
1457
|
+
add(
|
|
1458
|
+
"PASS",
|
|
1459
|
+
"Global installs",
|
|
1460
|
+
`v${staleVersion} at ${staleDir} (running v${running || "?"} from source/build) \u2014 single install, nothing shadowed.`
|
|
1461
|
+
);
|
|
1462
|
+
} else if (knownCount > 1) {
|
|
1463
|
+
add(
|
|
1464
|
+
"PASS",
|
|
1465
|
+
"Global installs",
|
|
1466
|
+
`${knownCount} install(s) on PATH, all v${running || "?"}.`
|
|
1467
|
+
);
|
|
1468
|
+
} else {
|
|
1469
|
+
add(
|
|
1470
|
+
"PASS",
|
|
1471
|
+
"Global installs",
|
|
1472
|
+
`v${running || "?"} at ${dirname(shims[0])}.`
|
|
1473
|
+
);
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1378
1476
|
function printReport() {
|
|
1379
1477
|
const noColor = process.env.NO_COLOR !== void 0 || !process.stdout.isTTY;
|
|
1380
1478
|
const colors2 = (s, n) => {
|
|
@@ -1417,6 +1515,7 @@ async function runDoctor() {
|
|
|
1417
1515
|
checkConfig();
|
|
1418
1516
|
checkGithubToken();
|
|
1419
1517
|
checkDirs();
|
|
1518
|
+
checkInstallShadowing();
|
|
1420
1519
|
printReport();
|
|
1421
1520
|
const hasFail = results.some((r) => r.status === "FAIL");
|
|
1422
1521
|
process.exitCode = hasFail ? 1 : 0;
|
|
@@ -1429,7 +1528,7 @@ import {
|
|
|
1429
1528
|
version as nodeVersion,
|
|
1430
1529
|
versions as nodeVersions
|
|
1431
1530
|
} from "process";
|
|
1432
|
-
import { spawn } from "child_process";
|
|
1531
|
+
import { spawn as spawn2 } from "child_process";
|
|
1433
1532
|
|
|
1434
1533
|
// src/version.ts
|
|
1435
1534
|
import { readFileSync as readFileSync2 } from "fs";
|
|
@@ -1439,7 +1538,7 @@ var cached = null;
|
|
|
1439
1538
|
function getVersion() {
|
|
1440
1539
|
if (cached) return cached;
|
|
1441
1540
|
if (true) {
|
|
1442
|
-
cached = "9.7.
|
|
1541
|
+
cached = "9.7.1";
|
|
1443
1542
|
return cached;
|
|
1444
1543
|
}
|
|
1445
1544
|
try {
|
|
@@ -1515,14 +1614,15 @@ function tryOpenUrl(url) {
|
|
|
1515
1614
|
try {
|
|
1516
1615
|
const p = osPlatform;
|
|
1517
1616
|
if (typeof Bun !== "undefined") {
|
|
1518
|
-
if (p === "win32")
|
|
1519
|
-
|
|
1617
|
+
if (p === "win32") {
|
|
1618
|
+
Bun.spawn(["explorer", url]);
|
|
1619
|
+
} else if (p === "darwin") Bun.spawn(["open", url]);
|
|
1520
1620
|
else Bun.spawn(["xdg-open", url]);
|
|
1521
1621
|
return true;
|
|
1522
1622
|
}
|
|
1523
|
-
const cmd = p === "win32" ? "
|
|
1524
|
-
const args =
|
|
1525
|
-
const child =
|
|
1623
|
+
const cmd = p === "win32" ? "explorer" : p === "darwin" ? "open" : "xdg-open";
|
|
1624
|
+
const args = [url];
|
|
1625
|
+
const child = spawn2(cmd, args, { detached: true, stdio: "ignore" });
|
|
1526
1626
|
child.unref();
|
|
1527
1627
|
return true;
|
|
1528
1628
|
} catch {
|
|
@@ -1543,11 +1643,11 @@ function reportError(err, context = {
|
|
|
1543
1643
|
console.error("");
|
|
1544
1644
|
const opened = tryOpenUrl(url);
|
|
1545
1645
|
if (opened) {
|
|
1546
|
-
console.error(
|
|
1646
|
+
console.error(` \u2192 Opened: ${url}`);
|
|
1547
1647
|
} else {
|
|
1548
1648
|
console.error(" Copy this URL to file a bug report:");
|
|
1549
1649
|
console.error("");
|
|
1550
|
-
console.error(
|
|
1650
|
+
console.error(` ${url}`);
|
|
1551
1651
|
}
|
|
1552
1652
|
console.error("");
|
|
1553
1653
|
return url;
|
|
@@ -2148,7 +2248,8 @@ function appendJSONL(filename, obj) {
|
|
|
2148
2248
|
try {
|
|
2149
2249
|
appendFileSync(
|
|
2150
2250
|
join3(stateDir(), filename),
|
|
2151
|
-
JSON.stringify(obj)
|
|
2251
|
+
`${JSON.stringify(obj)}
|
|
2252
|
+
`,
|
|
2152
2253
|
"utf-8"
|
|
2153
2254
|
);
|
|
2154
2255
|
} catch {
|
|
@@ -2299,7 +2400,7 @@ async function fetchReleases(fullName, etag, token) {
|
|
|
2299
2400
|
Accept: "application/vnd.github+json"
|
|
2300
2401
|
};
|
|
2301
2402
|
if (etag) headers["If-None-Match"] = etag;
|
|
2302
|
-
if (token) headers
|
|
2403
|
+
if (token) headers.Authorization = `Bearer ${token}`;
|
|
2303
2404
|
const res = await fetch(
|
|
2304
2405
|
`https://api.github.com/repos/${fullName}/releases?per_page=${PER_REPO}`,
|
|
2305
2406
|
{ headers }
|
|
@@ -2536,7 +2637,7 @@ async function runInitWizard() {
|
|
|
2536
2637
|
const themeStr = await ask(` Theme [${themes.join("/")}] (tokyo-night): `);
|
|
2537
2638
|
const config = {
|
|
2538
2639
|
defaultSort: ["best-match", "stars", "updated", "forks"].includes(sortStr) ? sortStr : "best-match",
|
|
2539
|
-
defaultLimit: Math.min(100, Math.max(10, parseInt(limitStr) || 50)),
|
|
2640
|
+
defaultLimit: Math.min(100, Math.max(10, parseInt(limitStr, 10) || 50)),
|
|
2540
2641
|
theme: themes.includes(themeStr) ? themeStr : themes[0],
|
|
2541
2642
|
cacheTtlSeconds: 300,
|
|
2542
2643
|
defaultTab: "search"
|
|
@@ -2585,18 +2686,18 @@ function buildComparisonTable(repos) {
|
|
|
2585
2686
|
const header = ["".padEnd(14), ...names.map((n) => n.padEnd(colW))];
|
|
2586
2687
|
const sep = ["".padEnd(14, "\u2500"), ...names.map(() => "".padEnd(colW, "\u2500"))];
|
|
2587
2688
|
const lines = [
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2689
|
+
`\u250C${sep.map((s) => `\u2500${s}\u2500`).join("\u252C")}\u2510`,
|
|
2690
|
+
`\u2502${header.map((h) => ` ${h} `).join("\u2502")}\u2502`,
|
|
2691
|
+
`\u251C${sep.map((s) => `\u2500${s}\u2500`).join("\u253C")}\u2524`
|
|
2591
2692
|
];
|
|
2592
2693
|
for (const row of rows) {
|
|
2593
2694
|
const cells = [
|
|
2594
2695
|
row.label.padEnd(14),
|
|
2595
2696
|
...row.values.map((v) => v.padEnd(colW))
|
|
2596
2697
|
];
|
|
2597
|
-
lines.push(
|
|
2698
|
+
lines.push(`\u2502${cells.map((c) => ` ${c} `).join("\u2502")}\u2502`);
|
|
2598
2699
|
}
|
|
2599
|
-
lines.push(
|
|
2700
|
+
lines.push(`\u2514${sep.map((s) => `\u2500${s}\u2500`).join("\u2534")}\u2518`);
|
|
2600
2701
|
return lines.join("\n");
|
|
2601
2702
|
}
|
|
2602
2703
|
function comparisonRepo(r) {
|
|
@@ -3074,7 +3175,8 @@ function deleteHistoryEntry(index) {
|
|
|
3074
3175
|
);
|
|
3075
3176
|
writeRaw(
|
|
3076
3177
|
HISTORY_FILE,
|
|
3077
|
-
remaining.reverse().map((e) => JSON.stringify(e)).join("\n")
|
|
3178
|
+
`${remaining.reverse().map((e) => JSON.stringify(e)).join("\n")}
|
|
3179
|
+
`
|
|
3078
3180
|
);
|
|
3079
3181
|
}
|
|
3080
3182
|
function clearHistory() {
|
|
@@ -3086,7 +3188,8 @@ function rotateHistory() {
|
|
|
3086
3188
|
const trimmed = entries.slice(0, MAX_ENTRIES);
|
|
3087
3189
|
writeRaw(
|
|
3088
3190
|
HISTORY_FILE,
|
|
3089
|
-
trimmed.reverse().map((e) => JSON.stringify(e)).join("\n")
|
|
3191
|
+
`${trimmed.reverse().map((e) => JSON.stringify(e)).join("\n")}
|
|
3192
|
+
`
|
|
3090
3193
|
);
|
|
3091
3194
|
}
|
|
3092
3195
|
|
|
@@ -3171,12 +3274,12 @@ function renderMarkdown(md, opts = {}) {
|
|
|
3171
3274
|
if (codeLines.length === 0) return;
|
|
3172
3275
|
const maxLen = Math.max(...codeLines.map((l) => l.length), codeLang.length);
|
|
3173
3276
|
const barW = Math.min(maxLen + 4, width - 2);
|
|
3174
|
-
out.push(
|
|
3175
|
-
if (codeLang) out.push(
|
|
3277
|
+
out.push(`\u250C${"\u2500".repeat(barW)}\u2510`);
|
|
3278
|
+
if (codeLang) out.push(`\u2502 ${codeLang.padEnd(barW - 1)}\u2502`);
|
|
3176
3279
|
for (const cl of codeLines) {
|
|
3177
|
-
out.push(
|
|
3280
|
+
out.push(`\u2502 ${cl.padEnd(barW - 1)}\u2502`);
|
|
3178
3281
|
}
|
|
3179
|
-
out.push(
|
|
3282
|
+
out.push(`\u2514${"\u2500".repeat(barW)}\u2518`);
|
|
3180
3283
|
out.push("");
|
|
3181
3284
|
codeLines = [];
|
|
3182
3285
|
codeLang = "";
|
|
@@ -3198,16 +3301,16 @@ function renderMarkdown(md, opts = {}) {
|
|
|
3198
3301
|
const totalW = colW.reduce((a, b) => a + b, 0) + colCount * 3 - 1;
|
|
3199
3302
|
if (totalW > width) {
|
|
3200
3303
|
for (const row of dataRows) {
|
|
3201
|
-
out.push(
|
|
3304
|
+
out.push(` ${row.map((c) => c.trim()).join(" \u2502 ")}`);
|
|
3202
3305
|
}
|
|
3203
3306
|
} else {
|
|
3204
|
-
const sep =
|
|
3205
|
-
const mid =
|
|
3206
|
-
const end =
|
|
3307
|
+
const sep = `\u250C${colW.map((w) => "\u2500".repeat(w + 2)).join("\u252C")}\u2510`;
|
|
3308
|
+
const mid = `\u251C${colW.map((w) => "\u2500".repeat(w + 2)).join("\u253C")}\u2524`;
|
|
3309
|
+
const end = `\u2514${colW.map((w) => "\u2500".repeat(w + 2)).join("\u2534")}\u2518`;
|
|
3207
3310
|
out.push(sep);
|
|
3208
3311
|
dataRows.forEach((row, i) => {
|
|
3209
3312
|
const cells = colW.map((w, ci) => (row[ci] ?? "").trim().padEnd(w));
|
|
3210
|
-
out.push(
|
|
3313
|
+
out.push(`\u2502 ${cells.map((c) => ` ${c} `).join("\u2502")}\u2502`);
|
|
3211
3314
|
if (i === 0) out.push(mid);
|
|
3212
3315
|
});
|
|
3213
3316
|
out.push(end);
|
|
@@ -3238,7 +3341,7 @@ function renderMarkdown(md, opts = {}) {
|
|
|
3238
3341
|
return parts;
|
|
3239
3342
|
}
|
|
3240
3343
|
for (let i = 0; i < lines.length; i++) {
|
|
3241
|
-
|
|
3344
|
+
const line = lines[i];
|
|
3242
3345
|
if (/^```/.test(line)) {
|
|
3243
3346
|
if (inCodeBlock) {
|
|
3244
3347
|
flushCode();
|
|
@@ -3283,7 +3386,7 @@ function renderMarkdown(md, opts = {}) {
|
|
|
3283
3386
|
if (bqMatch) {
|
|
3284
3387
|
const inner = renderInline(bqMatch[1]);
|
|
3285
3388
|
for (const wl of wrapLine(inner, width - 4)) {
|
|
3286
|
-
out.push(
|
|
3389
|
+
out.push(`\u2502 ${wl}`);
|
|
3287
3390
|
}
|
|
3288
3391
|
continue;
|
|
3289
3392
|
}
|
|
@@ -3291,7 +3394,7 @@ function renderMarkdown(md, opts = {}) {
|
|
|
3291
3394
|
if (ulMatch) {
|
|
3292
3395
|
const indent = ulMatch[1].length;
|
|
3293
3396
|
const depth = Math.floor(indent / 2);
|
|
3294
|
-
const prefix = " ".repeat(depth)
|
|
3397
|
+
const prefix = `${" ".repeat(depth)}\u2022 `;
|
|
3295
3398
|
const inner = renderInline(ulMatch[2]);
|
|
3296
3399
|
for (const wl of wrapLine(inner, width - prefix.length)) {
|
|
3297
3400
|
out.push(prefix + wl);
|
|
@@ -3302,7 +3405,7 @@ function renderMarkdown(md, opts = {}) {
|
|
|
3302
3405
|
if (olMatch) {
|
|
3303
3406
|
const indent = olMatch[1].length;
|
|
3304
3407
|
const depth = Math.floor(indent / 2);
|
|
3305
|
-
const prefix = " ".repeat(depth)
|
|
3408
|
+
const prefix = `${" ".repeat(depth)}\u25E6 `;
|
|
3306
3409
|
const inner = renderInline(olMatch[2]);
|
|
3307
3410
|
for (const wl of wrapLine(inner, width - prefix.length)) {
|
|
3308
3411
|
out.push(prefix + wl);
|
|
@@ -3392,7 +3495,7 @@ var StatusManager = class {
|
|
|
3392
3495
|
};
|
|
3393
3496
|
|
|
3394
3497
|
// src/share.ts
|
|
3395
|
-
import { spawn as
|
|
3498
|
+
import { spawn as spawn3 } from "child_process";
|
|
3396
3499
|
function formatShare(repo, format2) {
|
|
3397
3500
|
switch (format2) {
|
|
3398
3501
|
case "markdown":
|
|
@@ -3410,7 +3513,7 @@ async function copyToClipboard(text) {
|
|
|
3410
3513
|
const p = process.platform;
|
|
3411
3514
|
const cmd = p === "win32" ? ["clip"] : p === "darwin" ? ["pbcopy"] : await findLinuxClipboard();
|
|
3412
3515
|
if (!cmd) return false;
|
|
3413
|
-
const proc =
|
|
3516
|
+
const proc = spawn3(cmd[0], cmd.slice(1), {
|
|
3414
3517
|
stdio: ["pipe", "ignore", "ignore"]
|
|
3415
3518
|
});
|
|
3416
3519
|
proc.stdin.write(text);
|
|
@@ -3473,9 +3576,10 @@ function nextTip() {
|
|
|
3473
3576
|
|
|
3474
3577
|
// src/update-check.ts
|
|
3475
3578
|
import { readFileSync as readFileSync5 } from "fs";
|
|
3476
|
-
import { join as join5, dirname as dirname3 } from "path";
|
|
3579
|
+
import { join as join5, dirname as dirname3, posix } from "path";
|
|
3477
3580
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3478
3581
|
var REGISTRY_URL = "https://registry.npmjs.org/github-search-cli/latest";
|
|
3582
|
+
var PKG_NAME2 = "github-search-cli";
|
|
3479
3583
|
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
3480
3584
|
var REQUEST_TIMEOUT_MS = 5e3;
|
|
3481
3585
|
var __dirname2 = dirname3(fileURLToPath3(import.meta.url));
|
|
@@ -3560,30 +3664,55 @@ function suppressUpdateNotices() {
|
|
|
3560
3664
|
suppressed: true
|
|
3561
3665
|
});
|
|
3562
3666
|
}
|
|
3563
|
-
|
|
3564
|
-
const
|
|
3565
|
-
const
|
|
3566
|
-
|
|
3667
|
+
function detectInstallLocation(pkgDir) {
|
|
3668
|
+
const norm = pkgDir.split("\\").join("/");
|
|
3669
|
+
const nodeModules = posix.dirname(norm);
|
|
3670
|
+
if (posix.basename(nodeModules) !== "node_modules") return null;
|
|
3671
|
+
const owner = posix.dirname(nodeModules);
|
|
3672
|
+
if (/(^|\/)\.bun(\/|$)/.test(owner)) return { channel: "bun" };
|
|
3673
|
+
const prefix = posix.basename(owner) === "lib" ? posix.dirname(owner) : owner;
|
|
3674
|
+
return { channel: "npm", prefix };
|
|
3675
|
+
}
|
|
3676
|
+
function buildUpdateCommand(loc) {
|
|
3677
|
+
if (loc.channel === "bun") return ["bun", "install", "-g", PKG_NAME2];
|
|
3678
|
+
const args = ["npm", "install", "-g"];
|
|
3679
|
+
if (loc.prefix) args.push("--prefix", loc.prefix);
|
|
3680
|
+
args.push(PKG_NAME2);
|
|
3681
|
+
return args;
|
|
3682
|
+
}
|
|
3683
|
+
function quoteWin32(arg) {
|
|
3684
|
+
return /\s/.test(arg) ? `"${arg}"` : arg;
|
|
3685
|
+
}
|
|
3686
|
+
async function performUpdate(location = detectInstallLocation(PKG_DIR2)) {
|
|
3687
|
+
if (!location) {
|
|
3688
|
+
debugLog(
|
|
3689
|
+
"Update skipped: the running install is not under a node_modules tree (compiled binary or dev checkout). Update it manually."
|
|
3690
|
+
);
|
|
3691
|
+
return false;
|
|
3692
|
+
}
|
|
3693
|
+
const argv = buildUpdateCommand(location);
|
|
3567
3694
|
try {
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
return proc.exitCode === 0;
|
|
3579
|
-
}
|
|
3580
|
-
const { spawn: spawn3 } = await import("child_process");
|
|
3581
|
-
return await new Promise((resolve) => {
|
|
3582
|
-
const proc = spawn3(cmd[0], cmd.slice(1), { stdio: "ignore" });
|
|
3583
|
-
proc.on("close", (code) => resolve(code === 0));
|
|
3584
|
-
proc.on("error", () => resolve(false));
|
|
3695
|
+
const { spawn: spawn4 } = await import("child_process");
|
|
3696
|
+
const useShell = process.platform === "win32";
|
|
3697
|
+
const proc = spawn4(
|
|
3698
|
+
argv[0],
|
|
3699
|
+
useShell ? argv.slice(1).map(quoteWin32) : argv.slice(1),
|
|
3700
|
+
{ stdio: ["ignore", "ignore", "pipe"], shell: useShell }
|
|
3701
|
+
);
|
|
3702
|
+
let stderr = "";
|
|
3703
|
+
proc.stderr?.on("data", (chunk) => {
|
|
3704
|
+
stderr += String(chunk);
|
|
3585
3705
|
});
|
|
3586
|
-
|
|
3706
|
+
const code = await new Promise((resolve) => {
|
|
3707
|
+
proc.on("close", (c) => resolve(c));
|
|
3708
|
+
proc.on("error", () => resolve(-1));
|
|
3709
|
+
});
|
|
3710
|
+
if (code !== 0) {
|
|
3711
|
+
debugLog(`Install failed (code ${code}): ${stderr.trim()}`);
|
|
3712
|
+
}
|
|
3713
|
+
return code === 0;
|
|
3714
|
+
} catch (e) {
|
|
3715
|
+
debugLog(`Update failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
3587
3716
|
return false;
|
|
3588
3717
|
}
|
|
3589
3718
|
}
|
|
@@ -3603,7 +3732,7 @@ function fetchReleaseNotes(version) {
|
|
|
3603
3732
|
try {
|
|
3604
3733
|
const changelogPath = join5(PKG_DIR2, "CHANGELOG.md");
|
|
3605
3734
|
const changelog = readFileSync5(changelogPath, "utf-8");
|
|
3606
|
-
const header =
|
|
3735
|
+
const header = `## [${version}]`;
|
|
3607
3736
|
const start = changelog.indexOf(header);
|
|
3608
3737
|
if (start === -1) return null;
|
|
3609
3738
|
const bodyStart = start + header.length;
|
|
@@ -3747,8 +3876,8 @@ async function launchBrowser(theme_override) {
|
|
|
3747
3876
|
let currentPage = 1;
|
|
3748
3877
|
let totalCount = 0;
|
|
3749
3878
|
let deepDiveActive = false;
|
|
3750
|
-
|
|
3751
|
-
|
|
3879
|
+
const compareList = [];
|
|
3880
|
+
const _quitArmed = false;
|
|
3752
3881
|
const header = new TextRenderable4(renderer, {
|
|
3753
3882
|
content: " ghfind \u2014 GitHub repo browser [/]search [Space]menu [\u2192]open [?]help [q]uit",
|
|
3754
3883
|
bg: colors.bg,
|
|
@@ -4611,6 +4740,7 @@ async function launchBrowser(theme_override) {
|
|
|
4611
4740
|
if (menuStack.length <= 1) return false;
|
|
4612
4741
|
const prev = menuStack[menuStack.length - 2];
|
|
4613
4742
|
const current = menuStack.pop();
|
|
4743
|
+
if (!current) return false;
|
|
4614
4744
|
leaderSelect.options = prev.entries.map((e) => ({
|
|
4615
4745
|
name: e.type === "category" ? ` ${e.icon} ${e.name} \u2192` : ` ${e.name}`,
|
|
4616
4746
|
description: e.description,
|
|
@@ -4927,17 +5057,17 @@ async function launchBrowser(theme_override) {
|
|
|
4927
5057
|
if (!cachedVersion) {
|
|
4928
5058
|
cachedVersion = getVersion();
|
|
4929
5059
|
}
|
|
4930
|
-
const
|
|
5060
|
+
const currentVersion = cachedVersion;
|
|
4931
5061
|
if (!state.lastInstalledVersion) return;
|
|
4932
|
-
if (state.lastInstalledVersion ===
|
|
4933
|
-
const notes = fetchReleaseNotes(
|
|
5062
|
+
if (state.lastInstalledVersion === currentVersion) return;
|
|
5063
|
+
const notes = fetchReleaseNotes(currentVersion);
|
|
4934
5064
|
const notesWidth = Math.max(
|
|
4935
5065
|
30,
|
|
4936
5066
|
Math.floor((process.stdout.columns || 80) * 0.55) - 8
|
|
4937
5067
|
);
|
|
4938
5068
|
const notesBlock = notes ? renderMarkdown(notes, { width: notesWidth }) : " No release notes found for this version.";
|
|
4939
5069
|
updateSelectedOption = 0;
|
|
4940
|
-
updateText.content = ` Updated ghfind ${state.lastInstalledVersion} \u2192 ${
|
|
5070
|
+
updateText.content = ` Updated ghfind ${state.lastInstalledVersion} \u2192 ${currentVersion}
|
|
4941
5071
|
|
|
4942
5072
|
${notesBlock}`;
|
|
4943
5073
|
renderUpdateOptions();
|
|
@@ -4948,8 +5078,8 @@ ${notesBlock}`;
|
|
|
4948
5078
|
if (cachedVersion === null) {
|
|
4949
5079
|
cachedVersion = getVersion();
|
|
4950
5080
|
}
|
|
4951
|
-
const
|
|
4952
|
-
const latest = process.env.DEBUG_FORCE_UPDATE || await checkForUpdate(
|
|
5081
|
+
const currentVersion = cachedVersion;
|
|
5082
|
+
const latest = process.env.DEBUG_FORCE_UPDATE || await checkForUpdate(currentVersion);
|
|
4953
5083
|
markUpdateChecked(latest ?? void 0);
|
|
4954
5084
|
if (latest) {
|
|
4955
5085
|
updateSelectedOption = 0;
|
|
@@ -4960,20 +5090,20 @@ ${notesBlock}`;
|
|
|
4960
5090
|
);
|
|
4961
5091
|
const notesBlock = notes ? renderMarkdown(notes, { width: notesWidth }) : ` A new version is available
|
|
4962
5092
|
|
|
4963
|
-
Current: ${
|
|
5093
|
+
Current: ${currentVersion}
|
|
4964
5094
|
Latest: ${latest}
|
|
4965
5095
|
|
|
4966
5096
|
Run "npm install -g ghfind"`;
|
|
4967
5097
|
updateText.content = ` A new version is available
|
|
4968
5098
|
|
|
4969
|
-
Current: ${
|
|
5099
|
+
Current: ${currentVersion}
|
|
4970
5100
|
Latest: ${latest}
|
|
4971
5101
|
|
|
4972
5102
|
${notesBlock}`;
|
|
4973
5103
|
renderUpdateOptions();
|
|
4974
5104
|
showOverlay("update");
|
|
4975
5105
|
} else {
|
|
4976
|
-
debugLog(`No update available (current: ${
|
|
5106
|
+
debugLog(`No update available (current: ${currentVersion})`);
|
|
4977
5107
|
}
|
|
4978
5108
|
}
|
|
4979
5109
|
function openUrlIfSelected() {
|
|
@@ -5018,7 +5148,7 @@ ${notesBlock}`;
|
|
|
5018
5148
|
}
|
|
5019
5149
|
function saveCurrentSearch() {
|
|
5020
5150
|
if (currentQueryInput) {
|
|
5021
|
-
const name = currentQueryInput.length > 40 ? currentQueryInput.slice(0, 37)
|
|
5151
|
+
const name = currentQueryInput.length > 40 ? `${currentQueryInput.slice(0, 37)}...` : currentQueryInput;
|
|
5022
5152
|
saveSearch(
|
|
5023
5153
|
name,
|
|
5024
5154
|
currentQueryInput,
|
|
@@ -5235,13 +5365,11 @@ ${notesBlock}`;
|
|
|
5235
5365
|
statusBar.content = ` ${text}`;
|
|
5236
5366
|
renderer.requestRender();
|
|
5237
5367
|
});
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
}, 2e3);
|
|
5244
|
-
}
|
|
5368
|
+
setTimeout(() => {
|
|
5369
|
+
if (currentOverlay === "none") {
|
|
5370
|
+
setStatus(nextTip());
|
|
5371
|
+
}
|
|
5372
|
+
}, 2e3);
|
|
5245
5373
|
function setStatus(msg) {
|
|
5246
5374
|
statusMgr.set("idle", msg);
|
|
5247
5375
|
}
|
|
@@ -5361,7 +5489,7 @@ ${notesBlock}`;
|
|
|
5361
5489
|
if (idx >= 0) {
|
|
5362
5490
|
const val = labelVals[idx];
|
|
5363
5491
|
label = val >= 1e3 ? `${(val / 1e3).toFixed(1).replace(/\.0$/, "")}k` : String(val);
|
|
5364
|
-
label = label.padStart(5)
|
|
5492
|
+
label = `${label.padStart(5)} `;
|
|
5365
5493
|
}
|
|
5366
5494
|
lines.push(`${label}\u2506${chars.join("")}`);
|
|
5367
5495
|
}
|
|
@@ -5795,7 +5923,8 @@ ${pack.description ?? ""}`;
|
|
|
5795
5923
|
if (key.name === "d") {
|
|
5796
5924
|
const sel = historySelect.getSelectedOption();
|
|
5797
5925
|
if (sel?.value) {
|
|
5798
|
-
|
|
5926
|
+
const idx = sel.value.index;
|
|
5927
|
+
if (idx !== void 0) deleteHistoryEntry(idx);
|
|
5799
5928
|
refreshHistory();
|
|
5800
5929
|
setStatus("Deleted history entry");
|
|
5801
5930
|
}
|
|
@@ -5814,6 +5943,7 @@ ${pack.description ?? ""}`;
|
|
|
5814
5943
|
if (sel?.value) {
|
|
5815
5944
|
const entry = sel.value.entry;
|
|
5816
5945
|
showOverlay("none");
|
|
5946
|
+
if (!entry) return;
|
|
5817
5947
|
if (entry.mode === "trending") {
|
|
5818
5948
|
if (entry.tab)
|
|
5819
5949
|
trendingTab = entry.tab;
|
|
@@ -5832,7 +5962,9 @@ ${pack.description ?? ""}`;
|
|
|
5832
5962
|
if (key.name === "d") {
|
|
5833
5963
|
const sel = bookmarksSelect.getSelectedOption();
|
|
5834
5964
|
if (sel?.value) {
|
|
5835
|
-
removeBookmark(
|
|
5965
|
+
removeBookmark(
|
|
5966
|
+
sel.value.repo?.fullName ?? ""
|
|
5967
|
+
);
|
|
5836
5968
|
refreshBookmarks();
|
|
5837
5969
|
setStatus("Bookmark removed");
|
|
5838
5970
|
}
|
|
@@ -5841,7 +5973,8 @@ ${pack.description ?? ""}`;
|
|
|
5841
5973
|
}
|
|
5842
5974
|
if (key.name === "enter" || key.name === "return") {
|
|
5843
5975
|
const sel = bookmarksSelect.getSelectedOption();
|
|
5844
|
-
if (sel?.value)
|
|
5976
|
+
if (sel?.value)
|
|
5977
|
+
openUrl(sel.value.repo?.url ?? "");
|
|
5845
5978
|
return;
|
|
5846
5979
|
}
|
|
5847
5980
|
return;
|
|
@@ -5850,7 +5983,7 @@ ${pack.description ?? ""}`;
|
|
|
5850
5983
|
if (key.name === "d") {
|
|
5851
5984
|
const sel = savedSelect.getSelectedOption();
|
|
5852
5985
|
if (sel?.value) {
|
|
5853
|
-
deleteSavedSearch(sel.value.name);
|
|
5986
|
+
deleteSavedSearch(sel.value.name ?? "");
|
|
5854
5987
|
refreshSavedSearches();
|
|
5855
5988
|
setStatus("Saved search deleted");
|
|
5856
5989
|
}
|
|
@@ -5885,7 +6018,7 @@ ${pack.description ?? ""}`;
|
|
|
5885
6018
|
if (sel?.value) {
|
|
5886
6019
|
const topic = sel.value;
|
|
5887
6020
|
showOverlay("none");
|
|
5888
|
-
searchInput.value = `topic:${topic.name}`;
|
|
6021
|
+
searchInput.value = `topic:${topic.name ?? ""}`;
|
|
5889
6022
|
showSearchMode();
|
|
5890
6023
|
doSearch(`topic:${topic.name}`);
|
|
5891
6024
|
}
|
|
@@ -6076,7 +6209,7 @@ ${pack.description ?? ""}`;
|
|
|
6076
6209
|
}
|
|
6077
6210
|
if (/^[1-5]$/.test(key.name)) {
|
|
6078
6211
|
if (currentMode === "trending") {
|
|
6079
|
-
const idx = parseInt(key.name) - 1;
|
|
6212
|
+
const idx = parseInt(key.name, 10) - 1;
|
|
6080
6213
|
if (idx >= 0 && idx < TAB_NAMES.length) {
|
|
6081
6214
|
trendingTab = TAB_NAMES[idx];
|
|
6082
6215
|
loadTrending();
|
|
@@ -6120,14 +6253,14 @@ ${pack.description ?? ""}`;
|
|
|
6120
6253
|
return;
|
|
6121
6254
|
}
|
|
6122
6255
|
});
|
|
6123
|
-
const
|
|
6124
|
-
if (!session
|
|
6256
|
+
const _currentVersion = getVersion();
|
|
6257
|
+
if (!session?.mode) {
|
|
6125
6258
|
showLanding(true);
|
|
6126
6259
|
}
|
|
6127
6260
|
checkForUpdateAndShow();
|
|
6128
6261
|
checkPostUpgradePanel();
|
|
6129
6262
|
renderer.start();
|
|
6130
|
-
if (session
|
|
6263
|
+
if (session?.mode) {
|
|
6131
6264
|
if (currentMode === "trending") {
|
|
6132
6265
|
loadTrending();
|
|
6133
6266
|
} else {
|
|
@@ -6801,7 +6934,8 @@ async function processServerLine(line, state, config) {
|
|
|
6801
6934
|
}
|
|
6802
6935
|
}
|
|
6803
6936
|
function writeStdout(line) {
|
|
6804
|
-
process.stdout.write(line
|
|
6937
|
+
process.stdout.write(`${line}
|
|
6938
|
+
`);
|
|
6805
6939
|
}
|
|
6806
6940
|
async function runMcpServer(options = {}) {
|
|
6807
6941
|
const state = {
|
|
@@ -6820,8 +6954,9 @@ async function runMcpServer(options = {}) {
|
|
|
6820
6954
|
let buffer = "";
|
|
6821
6955
|
process.stdin.on("data", (chunk) => {
|
|
6822
6956
|
buffer += chunk;
|
|
6823
|
-
|
|
6824
|
-
|
|
6957
|
+
for (; ; ) {
|
|
6958
|
+
const idx = buffer.indexOf("\n");
|
|
6959
|
+
if (idx < 0) break;
|
|
6825
6960
|
const line = buffer.slice(0, idx).trim();
|
|
6826
6961
|
buffer = buffer.slice(idx + 1);
|
|
6827
6962
|
if (!line) continue;
|
|
@@ -6879,7 +7014,7 @@ function parseArgs(args) {
|
|
|
6879
7014
|
doctor: false,
|
|
6880
7015
|
mcp: false
|
|
6881
7016
|
};
|
|
6882
|
-
|
|
7017
|
+
const queryParts = [];
|
|
6883
7018
|
for (let i = 0; i < args.length; i++) {
|
|
6884
7019
|
const arg = args[i];
|
|
6885
7020
|
switch (arg) {
|
|
@@ -6933,8 +7068,8 @@ function parseArgs(args) {
|
|
|
6933
7068
|
flags.login = true;
|
|
6934
7069
|
break;
|
|
6935
7070
|
case "--limit": {
|
|
6936
|
-
const parsed = parseInt(args[++i]);
|
|
6937
|
-
if (isNaN(parsed) || parsed < 1 || parsed > 100) {
|
|
7071
|
+
const parsed = parseInt(args[++i], 10);
|
|
7072
|
+
if (Number.isNaN(parsed) || parsed < 1 || parsed > 100) {
|
|
6938
7073
|
console.error(`Invalid limit: must be 1-100. Using default 50.`);
|
|
6939
7074
|
flags.limit = 50;
|
|
6940
7075
|
} else {
|
|
@@ -7174,7 +7309,12 @@ function printAgentSkill(name) {
|
|
|
7174
7309
|
}
|
|
7175
7310
|
async function runUserProfile(flags, outputFormat) {
|
|
7176
7311
|
try {
|
|
7177
|
-
const
|
|
7312
|
+
const user = flags.user ?? "";
|
|
7313
|
+
if (!user) {
|
|
7314
|
+
console.error("Usage: ghfind user <name> [--json] [--token <t>]");
|
|
7315
|
+
process.exit(1);
|
|
7316
|
+
}
|
|
7317
|
+
const profile = await fetchUserProfile(user, {
|
|
7178
7318
|
token: flags.token,
|
|
7179
7319
|
limit: flags.limit
|
|
7180
7320
|
});
|
|
@@ -7196,7 +7336,12 @@ async function runUserProfile(flags, outputFormat) {
|
|
|
7196
7336
|
}
|
|
7197
7337
|
async function runOrgProfile(flags, outputFormat) {
|
|
7198
7338
|
try {
|
|
7199
|
-
const
|
|
7339
|
+
const org = flags.org ?? "";
|
|
7340
|
+
if (!org) {
|
|
7341
|
+
console.error("Usage: ghfind org <name> [--json] [--token <t>]");
|
|
7342
|
+
process.exit(1);
|
|
7343
|
+
}
|
|
7344
|
+
const profile = await fetchOrgProfile(org, {
|
|
7200
7345
|
token: flags.token,
|
|
7201
7346
|
limit: flags.limit
|
|
7202
7347
|
});
|
|
@@ -7327,7 +7472,7 @@ async function runReleases(flags, outputFormat) {
|
|
|
7327
7472
|
}
|
|
7328
7473
|
async function runNonInteractive(flags, outputFormat) {
|
|
7329
7474
|
const handlers = {
|
|
7330
|
-
trending: async (
|
|
7475
|
+
trending: async (_ctx) => {
|
|
7331
7476
|
const since = flags.since === "weekly" ? "weekly" : flags.since === "monthly" ? "monthly" : "daily";
|
|
7332
7477
|
const trendingSearch = createTrendingSearch();
|
|
7333
7478
|
let language;
|
|
@@ -7398,7 +7543,7 @@ async function runNonInteractive(flags, outputFormat) {
|
|
|
7398
7543
|
token: flags.token
|
|
7399
7544
|
});
|
|
7400
7545
|
const repos = rankRepos(response.repos, flags.sort);
|
|
7401
|
-
await pipeExec(repos, flags.pipe);
|
|
7546
|
+
if (flags.pipe) await pipeExec(repos, flags.pipe);
|
|
7402
7547
|
},
|
|
7403
7548
|
format: async (ctx2) => {
|
|
7404
7549
|
const response = await ctx2.provider.search(ctx2.parsed, {
|