github-search-cli 9.5.0 → 9.6.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 +85 -3
- package/README.md +65 -31
- package/completions/ghfind.bash +1 -1
- package/completions/ghfind.fish +1 -1
- package/completions/ghfind.zsh +2 -0
- package/dist/cli.js +813 -10
- package/package.json +1 -1
- package/release-notes/9.5.1.md +36 -0
- package/release-notes/9.6.0.md +67 -0
- package/scripts/brew.rb +31 -10
- package/scripts/install.sh +118 -0
- package/src/agent-skill.ts +140 -0
- package/src/cli.ts +60 -4
- package/src/doctor.ts +4 -0
- package/src/help.ts +4 -0
- package/src/mcp-server.ts +894 -0
- package/src/search.ts +69 -5
- package/src/types.ts +2 -0
package/src/search.ts
CHANGED
|
@@ -519,6 +519,72 @@ function appendPage(url: string, page: number, perPage: number): string {
|
|
|
519
519
|
|
|
520
520
|
const TRENDING_URL = "https://github.com/trending";
|
|
521
521
|
|
|
522
|
+
/**
|
|
523
|
+
* Languages github.com/trending accepts as a `?language=` filter (path-slug
|
|
524
|
+
* form, lowercase). The MCP `ghfind_trending` tool validates against this
|
|
525
|
+
* list instead of round-tripping an invalid language through a scrape.
|
|
526
|
+
*/
|
|
527
|
+
export const TRENDING_LANGUAGES: ReadonlySet<string> = new Set([
|
|
528
|
+
"c",
|
|
529
|
+
"c#",
|
|
530
|
+
"c++",
|
|
531
|
+
"clojure",
|
|
532
|
+
"crystal",
|
|
533
|
+
"css",
|
|
534
|
+
"dart",
|
|
535
|
+
"dockerfile",
|
|
536
|
+
"elixir",
|
|
537
|
+
"go",
|
|
538
|
+
"haskell",
|
|
539
|
+
"html",
|
|
540
|
+
"java",
|
|
541
|
+
"javascript",
|
|
542
|
+
"jupyter-notebook",
|
|
543
|
+
"kotlin",
|
|
544
|
+
"lua",
|
|
545
|
+
"objective-c",
|
|
546
|
+
"ocaml",
|
|
547
|
+
"perl",
|
|
548
|
+
"php",
|
|
549
|
+
"powershell",
|
|
550
|
+
"python",
|
|
551
|
+
"r",
|
|
552
|
+
"ruby",
|
|
553
|
+
"rust",
|
|
554
|
+
"scala",
|
|
555
|
+
"shell",
|
|
556
|
+
"solidity",
|
|
557
|
+
"svelte",
|
|
558
|
+
"swift",
|
|
559
|
+
"typescript",
|
|
560
|
+
"vue",
|
|
561
|
+
"zig",
|
|
562
|
+
]);
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Normalize a user-supplied language to the slug form github.com/trending
|
|
566
|
+
* uses: lowercase, whitespace runs collapsed to dashes ("Jupyter Notebook"
|
|
567
|
+
* → "jupyter-notebook").
|
|
568
|
+
*/
|
|
569
|
+
export function trendingLanguageSlug(language: string): string {
|
|
570
|
+
return language.trim().toLowerCase().replace(/\s+/g, "-");
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
/** Build the github.com/trending URL for a period + optional language filter. */
|
|
574
|
+
export function buildTrendingUrl(
|
|
575
|
+
since: "daily" | "weekly" | "monthly",
|
|
576
|
+
language?: string,
|
|
577
|
+
): string {
|
|
578
|
+
const params = new URLSearchParams();
|
|
579
|
+
if (since !== "daily") params.set("since", since);
|
|
580
|
+
if (language) {
|
|
581
|
+
const slug = trendingLanguageSlug(language);
|
|
582
|
+
if (TRENDING_LANGUAGES.has(slug)) params.set("language", slug);
|
|
583
|
+
}
|
|
584
|
+
const qs = params.toString();
|
|
585
|
+
return qs ? `${TRENDING_URL}?${qs}` : TRENDING_URL;
|
|
586
|
+
}
|
|
587
|
+
|
|
522
588
|
function trendingRepoToRepo(r: RawTrendingRepo): Repo {
|
|
523
589
|
return {
|
|
524
590
|
id: 0,
|
|
@@ -540,9 +606,7 @@ function trendingRepoToRepo(r: RawTrendingRepo): Repo {
|
|
|
540
606
|
pushedAt: "",
|
|
541
607
|
score: r.starsToday,
|
|
542
608
|
};
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
/**
|
|
609
|
+
} /**
|
|
546
610
|
* Trending adapter — scrapes github.com/trending HTML and returns SearchResponse.
|
|
547
611
|
*/
|
|
548
612
|
export class TrendingAdapter implements SearchAdapter {
|
|
@@ -558,8 +622,7 @@ export class TrendingAdapter implements SearchAdapter {
|
|
|
558
622
|
options: SearchOptions,
|
|
559
623
|
): Promise<SearchResponse> {
|
|
560
624
|
const since = options.trendingSince ?? "daily";
|
|
561
|
-
const url =
|
|
562
|
-
since === "daily" ? TRENDING_URL : `${TRENDING_URL}?since=${since}`;
|
|
625
|
+
const url = buildTrendingUrl(since, options.trendingLanguage);
|
|
563
626
|
let res: Response;
|
|
564
627
|
try {
|
|
565
628
|
res = await fetch(url, { headers: { "User-Agent": "ghfind" } });
|
|
@@ -639,6 +702,7 @@ export class SearchModule implements SearchProvider {
|
|
|
639
702
|
String(options.limit),
|
|
640
703
|
String(options.page ?? 1),
|
|
641
704
|
options.trendingSince ?? "none",
|
|
705
|
+
options.trendingLanguage ?? "none",
|
|
642
706
|
);
|
|
643
707
|
const cached = SearchModule.cache.get(cacheKey);
|
|
644
708
|
if (cached) {
|
package/src/types.ts
CHANGED
|
@@ -73,6 +73,8 @@ export interface SearchOptions {
|
|
|
73
73
|
page?: number;
|
|
74
74
|
/** Trending period: daily|weekly|monthly. Used by TrendingAdapter. */
|
|
75
75
|
trendingSince?: "daily" | "weekly" | "monthly";
|
|
76
|
+
/** Trending language filter (e.g. "rust", "python"). Used by TrendingAdapter. */
|
|
77
|
+
trendingLanguage?: string;
|
|
76
78
|
/** Verbose logging (outgoing query, errors, rate limits). */
|
|
77
79
|
verbose: boolean;
|
|
78
80
|
}
|