GitHubTrends


name: GitHubTrends
description: 显示GitHub热门项目趋势,生成可视化仪表板。USE WHEN github trends, trending projects, hot repositories, popular github projects, generate dashboard, create webpage.
version: 2.0.0

## Customization

**Before executing, check for user customizations at:**
`~/.claude/skills/CORE/USER/SKILLCUSTOMIZATIONS/GitHubTrends/`

If this directory exists, load and apply any PREFERENCES.md, configurations, or resources found there. These override default behavior. If the directory does not exist, proceed with skill defaults.

# GitHubTrends – GitHub热门项目趋势

**快速发现GitHub上最受欢迎的开源项目。**

## Philosophy

GitHub trending是发现优质开源项目的最佳途径。这个skill让老王我能快速获取当前最热门的项目列表,按时间周期(每日/每周)和编程语言筛选,帮助发现值得学习和贡献的项目。

## Quick Start

“`bash
# 查看本周最热门的项目(默认)
bun ~/.claude/skills/GitHubTrends/Tools/GetTrending.ts weekly

# 查看今日最热门的项目
bun ~/.claude/skills/GitHubTrends/Tools/GetTrending.ts daily

# 按语言筛选
bun ~/.claude/skills/GitHubTrends/Tools/GetTrending.ts weekly –language=TypeScript
bun ~/.claude/skills/GitHubTrends/Tools/GetTrending.ts weekly –language=Python

# 指定显示数量
bun ~/.claude/skills/GitHubTrends/Tools/GetTrending.ts weekly –limit=20
“`

## When to Use This Skill

**Core Triggers – Use this skill when user says:**

### Direct Requests
– “show github trends” 或 “github trending”
– “显示热门项目” 或 “看看有什么热门项目”
– “what’s trending on github” 或 “github hot projects”
– “本周热门项目” 或 “weekly trending”
– “今日热门项目” 或 “daily trending”

### Discovery Requests
– “discover popular projects” 或 “发现热门项目”
– “show repositories trending” 或 “显示trending仓库”
– “github上什么最火” 或 “what’s hot on github”
– “找点好项目看看” 或 “find good projects”

### Language-Specific
– “TypeScript trending projects” 或 “TypeScript热门项目”
– “Python trending” 或 “Python热门项目”
– “show trending Rust projects” 或 “显示Rust热门项目”
– “Go语言热门项目” 或 “trending Go projects”

### Dashboard & Visualization
– “生成 GitHub trending 仪表板” 或 “generate trending dashboard”
– “创建趋势网页” 或 “create trending webpage”
– “生成交互式报告” 或 “generate interactive report”
– “export trending dashboard” 或 “导出仪表板”
– “可视化 GitHub 趋势” 或 “visualize github trends”

## Core Capabilities

### 获取趋势列表
– **每日趋势** – 过去24小时最热门项目
– **每周趋势** – 过去7天最热门项目(默认)
– **语言筛选** – 按编程语言过滤(TypeScript, Python, Go, Rust等)
– **自定义数量** – 指定返回项目数量(默认10个)

### 生成可视化仪表板
– **交互式HTML** – 生成交互式网页仪表板
– **数据可视化** – 语言分布饼图、Stars增长柱状图
– **技术新闻** – 集成 Hacker News 技术资讯
– **实时筛选** – 按语言筛选、排序、搜索功能
– **响应式设计** – 支持桌面、平板、手机

### 项目信息
– 项目名称和描述
– Star数量和变化
– 编程语言
– 项目URL

## Tool Usage

### GetTrending.ts

**Location:** `Tools/GetTrending.ts`

**功能:** 从GitHub获取trending项目列表

**参数:**
– `period` – 时间周期:`daily` 或 `weekly`(默认:weekly)
– `–language` – 编程语言筛选(可选)
– `–limit` – 返回项目数量(默认:10)

**使用示例:**
“`bash
# 基本用法
bun ~/.claude/skills/GitHubTrends/Tools/GetTrending.ts weekly

# 带参数
bun ~/.claude/skills/GitHubTrends/Tools/GetTrending.ts weekly –language=TypeScript –limit=15

# 简写
bun ~/.claude/skills/GitHubTrends/Tools/GetTrending.ts daily -l=Python
“`

**实现方式:**
使用 GitHub官方trending页面:https://github.com/trending
通过 fetch API 读取页面内容并解析

### GenerateDashboard.ts

**Location:** `Tools/GenerateDashboard.ts`

**功能:** 生成交互式数据可视化仪表板HTML文件

**参数:**
– `–period` – 时间周期:`daily` 或 `weekly`(默认:weekly)
– `–language` – 编程语言筛选(可选)
– `–limit` – 返回项目数量(默认:10)
– `–include-news` – 包含技术新闻
– `–news-count` – 新闻数量(默认:10)
– `–output` – 输出文件路径(默认:./github-trends.html)

**使用示例:**
“`bash
# 基本用法 – 生成本周仪表板
bun ~/.claude/skills/GitHubTrends/Tools/GenerateDashboard.ts

# 包含技术新闻
bun ~/.claude/skills/GitHubTrends/Tools/GenerateDashboard.ts –include-news

# TypeScript 项目每日仪表板
bun ~/.claude/skills/GitHubTrends/Tools/GenerateDashboard.ts
–period daily
–language TypeScript
–limit 20
–include-news
–output ~/ts-daily.html
“`

**实现方式:**
– 获取 GitHub trending 项目数据
– 获取 Hacker News 技术新闻
– 使用 Handlebars 模板引擎渲染 HTML
– 集成 Tailwind CSS 和 Chart.js
– 生成完全独立的 HTML 文件(通过 CDN 加载依赖)

## Output Format

“`markdown
# GitHub Trending Projects – Weekly (2025-01-19)

## 1. vercel/next.js – ⭐ 125,342 (+1,234 this week)
**Language:** TypeScript
**Description:** The React Framework for the Web
**URL:** https://github.com/vercel/next.js

## 2. microsoft/vscode – ⭐ 160,890 (+987 this week)
**Language:** TypeScript
**Description:** Visual Studio Code
**URL:** https://github.com/microsoft/vscode


Total: 10 projects | Language: All | Period: Weekly
“`

## Supported Languages

常用编程语言筛选:
– **TypeScript** – TypeScript项目
– **JavaScript** – JavaScript项目
– **Python** – Python项目
– **Go** – Go语言项目
– **Rust** – Rust项目
– **Java** – Java项目
– **C++** – C++项目
– **Ruby** – Ruby项目
– **Swift** – Swift项目
– **Kotlin** – Kotlin项目

## Workflow Integration

这个skill可以被其他skill调用:
– **OSINT** – 在调查技术栈时发现热门工具
– **Research** – 研究特定语言生态系统的趋势
– **System** – 发现有用的PAI相关项目

## Technical Notes

**数据来源:** GitHub官方trending页面
**更新频率:** 每小时更新一次
**无需认证:** 使用公开页面,无需GitHub API token
**解析方式:** 通过HTML解析提取项目信息

**错误处理:**
– 网络错误会显示友好提示
– 解析失败会返回原始HTML供调试
– 支持的语言参数不区分大小写

## Future Enhancements

可能的未来功能:
– 支持月度趋势(如果GitHub提供)
– 按stars范围筛选(1k+, 10k+, 100k+)
– 保存历史数据用于趋势分析
– 集成到其他skill的自动化工作流

## Voice Notification

**When executing a workflow, do BOTH:**

1. **Send voice notification:**
“`bash
curl -s -X POST http://localhost:8888/notify
-H “Content-Type: application/json”
-d ‘{“message”: “Running the GitHubTrends workflow”}’
> /dev/null 2>&1 &
“`

2. **Output text notification:**
“`
Running the **GitHubTrends** workflow…
“`

**Full documentation:** `~/.claude/skills/CORE/SkillNotifications.md`
FILE:README.md
# GitHubTrends Skill

**快速发现GitHub上最受欢迎的开源项目,生成可视化仪表板!**

## 功能特性

### 基础功能
– ✅ 获取每日/每周热门项目列表
– ✅ 按编程语言筛选(TypeScript, Python, Go, Rust等)
– ✅ 自定义返回项目数量
– ✅ 显示Star总数和周期增长
– ✅ 无需GitHub API token

### 可视化仪表板
– ✨ **交互式HTML** – 生成交互式网页仪表板
– **数据可视化** – 语言分布饼图、Stars增长柱状图
– **技术新闻** – 集成 Hacker News 最新资讯
– **实时筛选** – 按语言筛选、排序、搜索
– **响应式设计** – 支持桌面、平板、手机
– **美观界面** – Tailwind CSS + GitHub 风格

## 快速开始

### 查看本周热门项目(默认)

“`bash
bun ~/.claude/skills/GitHubTrends/Tools/GetTrending.ts weekly
“`

### 查看今日热门项目

“`bash
bun ~/.claude/skills/GitHubTrends/Tools/GetTrending.ts daily
“`

### 按语言筛选

“`bash
# TypeScript热门项目
bun ~/.claude/skills/GitHubTrends/Tools/GetTrending.ts weekly –language=TypeScript

# Python热门项目
bun ~/.claude/skills/GitHubTrends/Tools/GetTrending.ts weekly –language=Python

# Go热门项目
bun ~/.claude/skills/GitHubTrends/Tools/GetTrending.ts weekly -l=Go
“`

### 指定返回数量

“`bash
# 返回20个项目
bun ~/.claude/skills/GitHubTrends/Tools/GetTrending.ts weekly –limit=20

# 组合使用:返回15个TypeScript项目
bun ~/.claude/skills/GitHubTrends/Tools/GetTrending.ts weekly –language=TypeScript –limit=15
“`

## 生成可视化仪表板

### 基本用法

“`bash
# 生成本周趋势仪表板(默认)
bun ~/.claude/skills/GitHubTrends/Tools/GenerateDashboard.ts
“`

### 包含技术新闻

“`bash
# 生成包含 Hacker News 的仪表板
bun ~/.claude/skills/GitHubTrends/Tools/GenerateDashboard.ts –include-news
“`

### 高级选项

“`bash
# 生成 TypeScript 项目每日仪表板,包含 15 条新闻
bun ~/.claude/skills/GitHubTrends/Tools/GenerateDashboard.ts
–period daily
–language TypeScript
–limit 20
–include-news
–news-count 15
–output ~/Downloads/ts-daily-trends.html
“`

### 仪表板功能

生成的 HTML 文件包含:
– **统计概览** – 总项目数、总 stars、top 项目
– **语言分布图** – 饼图展示各语言占比
– **Stars 增长图** – 柱状图展示增长趋势
– **项目卡片** – 美观的卡片式项目展示
– **技术新闻** – Hacker News 最新资讯
– **交互功能** – 筛选、排序、搜索
– **响应式** – 自适应各种屏幕尺寸

## 输出示例

“`markdown
# GitHub Trending Projects – Weekly (2026-01-19)

**Total:** 10 projects | **Language:** All | **Period:** Weekly

## 1. vercel/next.js – ⭐ 125,342 (+1,234 this week)
**Language:** TypeScript
**Description:** The React Framework for the Web
**URL:** https://github.com/vercel/next.js

## 2. microsoft/vscode – ⭐ 160,890 (+987 this week)
**Language:** TypeScript
**Description:** Visual Studio Code
**URL:** https://github.com/microsoft/vscode


“`

## 参数说明

| 参数 | 说明 | 默认值 | 可选值 |
|——|——|——–|——–|
| `period` | 时间周期 | `weekly` | `daily`, `weekly` |
| `–language` | 编程语言筛选 | 全部 | TypeScript, Python, Go, Rust, Java等 |
| `–limit` | 返回项目数量 | 10 | 任意正整数 |

## 支持的语言

常用的编程语言都可以作为筛选条件:
– **TypeScript** – TypeScript项目
– **JavaScript** – JavaScript项目
– **Python** – Python项目
– **Go** – Go语言项目
– **Rust** – Rust项目
– **Java** – Java项目
– **C++** – C++项目
– **Ruby** – Ruby项目
– **Swift** – Swift项目
– **Kotlin** – Kotlin项目

## Skill 触发词

当你说以下任何内容时,这个skill会被触发:

– “show github trends” / “github trending”
– “显示热门项目” / “看看有什么热门项目”
– “weekly trending” / “本周热门项目”
– “daily trending” / “今日热门项目”
– “TypeScript trending” / “Python trending”
– “what’s hot on github” / “github上什么最火”

## 技术实现

– **数据源**: GitHub官方trending页面 (https://github.com/trending)
– **解析方式**: HTML解析提取项目信息
– **认证**: 无需GitHub API token
– **更新频率**: 每小时更新一次

## 目录结构

“`
~/.claude/skills/GitHubTrends/
├── SKILL.md # Skill主文件
├── README.md # 使用文档(本文件)
├── Tools/
│ └── GetTrending.ts # 获取trending数据的工具
└── Workflows/
└── GetTrending.md # 工作流文档
“`

## 注意事项

1. **网络要求**: 需要能访问GitHub官网
2. **更新频率**: 数据每小时更新,不是实时
3. **解析准确性**: GitHub页面结构变化可能影响解析,如遇问题请检查 `/tmp/github-trending-debug-*.html`
4. **语言参数**: 不区分大小写,`–language=typescript` 和 `–language=TypeScript` 效果相同

## 已知问题

– GitHub trending页面的HTML结构复杂,某些项目的URL和名称可能解析不完整
– 如果GitHub页面结构变化,工具可能需要更新解析逻辑

## 未来改进

– [ ] 支持保存历史数据用于趋势分析
– [ ] 按stars范围筛选(1k+, 10k+, 100k+)
– [ ] 更智能的HTML解析(使用HTML解析库而非正则)
– [ ] 集成到其他skill的自动化工作流

## 贡献

如果发现问题或有改进建议,欢迎提出!

**Made with ❤️ by 老王**
FILE:Tools/GetTrending.ts
#!/usr/bin/env bun
/**
* GitHub Trending Projects Fetcher
*
* 从GitHub获取trending项目列表
* 支持每日/每周趋势,按语言筛选
*/

import { $ } from “bun”;

interface TrendingProject {
rank: number;
name: string;
description: string;
language: string;
stars: string;
starsThisPeriod: string;
url: string;
}

interface TrendingOptions {
period: “daily” | “weekly”;
language?: string;
limit: number;
}

function buildTrendingUrl(options: TrendingOptions): string {
const baseUrl = “https://github.com/trending”;
const since = options.period === “daily” ? “daily” : “weekly”;
let url = `${baseUrl}?since=${since}`;
if (options.language) {
url += `&language=${encodeURIComponent(options.language.toLowerCase())}`;
}
return url;
}

function parseTrendingProjects(html: string, limit: number): TrendingProject[] {
const projects: TrendingProject[] = [];
try {
const articleRegex = /]*>([sS]*?)

/g;
const articles = html.match(articleRegex) || [];
const articlesToProcess = articles.slice(0, limit);
articlesToProcess.forEach((article, index) => {
try {
const headingMatch = article.match(/]*>([sS]*?)/);
let repoName: string | null = null;
if (headingMatch) {
const headingContent = headingMatch[1];
const validLinkMatch = headingContent.match(
/]*href=”/([^/”/]+/[^/”/]+)”[^>]*>(?![^<]*login)/ ); if (validLinkMatch) { repoName = validLinkMatch[1]; } } if (!repoName) { const repoMatch = article.match( /]*href=”/([a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+)”[^>]*>(?!.*(?:login|stargazers|forks|issues))/
);
repoName = repoMatch ? repoMatch[1] : null;
}
const descMatch = article.match(/]*class=”[^”]*col-9[^”]*”[^>]*>([sS]*?)

/);
const description = descMatch
? descMatch[1]
.replace(/<[^>]+>/g, “”)
.replace(/&/g, “&”)
.replace(/</g, “<") .replace(/>/g, ">“)
.replace(/"/g, ‘”‘)
.trim()
.substring(0, 200)
: “No description”;
const langMatch = article.match(/]*itemprop=”programmingLanguage”[^>]*>([^<]+)/);
const language = langMatch ? langMatch[1].trim() : “Unknown”;
const starsMatch = article.match(/]*href=”/[^”]+/stargazers”[^>]*>(d[d,]*)s*stars?/);
const totalStars = starsMatch ? starsMatch[1] : “0”;
const starsAddedMatch = article.match(/(d[d,]*)s*stars?s*(?:today|this week)/i);
const starsAdded = starsAddedMatch ? `+${starsAddedMatch[1]}` : “”;
if (repoName && !repoName.includes(“login”) && !repoName.includes(“return_to”)) {
projects.push({
rank: index + 1,
name: repoName,
description,
language,
stars: totalStars,
starsThisPeriod: starsAdded,
url: `https://github.com/${repoName}`,
});
}
} catch (error) {
console.error(`解析第${index + 1}个项目失败:`, error);
}
});
} catch (error) {
console.error(“解析trending项目失败:”, error);
}
return projects;
}

function formatProjects(projects: TrendingProject[], options: TrendingOptions): string {
if (projects.length === 0) {
return “# GitHub Trending – No Projects Foundnn没有找到trending项目,可能是网络问题或页面结构变化。”;
}
const periodLabel = options.period === “daily” ? “Daily” : “Weekly”;
const languageLabel = options.language ? `Language: ${options.language}` : “Language: All”;
const today = new Date().toISOString().split(“T”)[0];
let output = `# GitHub Trending Projects – ${periodLabel} (${today})nn`;
output += ` **Total:** ${projects.length} projects | **${languageLabel}** | **Period:** ${periodLabel}nn`;
output += `—nn`;
projects.forEach((project) => {
output += `## ${project.rank}. ${project.name} – ⭐ ${project.stars}`;
if (project.starsThisPeriod) {
output += ` (${project.starsThisPeriod} this ${options.period})`;
}
output += `n`;
output += `**Language:** ${project.language}n`;
output += `**Description:** ${project.description}n`;
output += `**URL:** ${project.url}nn`;
});
output += `—n`;
output += ` Data from: https://github.com/trendingn`;
return output;
}

async function main() {
const args = process.argv.slice(2);
let period: “daily” | “weekly” = “weekly”;
let language: string | undefined;
let limit = 10;
for (const arg of args) {
if (arg === “daily” || arg === “weekly”) {
period = arg;
} else if (arg.startsWith(“–language=”)) {
language = arg.split(“=”)[1];
} else if (arg.startsWith(“-l=”)) {
language = arg.split(“=”)[1];
} else if (arg.startsWith(“–limit=”)) {
limit = parseInt(arg.split(“=”)[1]) || 10;
}
}
const options: TrendingOptions = { period, language, limit };
try {
const url = buildTrendingUrl(options);
console.error(`正在获取 GitHub trending 数据: ${url}`);
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const html = await response.text();
const projects = parseTrendingProjects(html, limit);
const formatted = formatProjects(projects, options);
console.log(formatted);
if (projects.length === 0) {
const debugFile = `/tmp/github-trending-debug-${Date.now()}.html`;
await Bun.write(debugFile, html);
console.error(`n调试: 原始HTML已保存到 ${debugFile}`);
}
} catch (error) {
console.error(“❌ 获取trending数据失败:”);
console.error(error);
process.exit(1);
}
}

main();
FILE:Workflows/GetTrending.md
# GetTrending Workflow

获取GitHub trending项目列表的工作流程。

## Description

这个工作流使用 GetTrending.ts 工具从GitHub获取当前最热门的项目列表,支持按时间周期(每日/每周)和编程语言筛选。

## When to Use

当用户请求以下任何内容时使用此工作流:
– “show github trends” / “github trending”
– “显示热门项目” / “看看有什么热门项目”
– “weekly trending” / “本周热门项目”
– “daily trending” / “今日热门项目”
– “TypeScript trending” / “Python trending” / 按语言筛选
– “what’s hot on github” / “github上什么最火”

## Workflow Steps

### Step 1: 确定参数
向用户确认或推断以下参数:
– **时间周期**: daily (每日) 或 weekly (每周,默认)
– **编程语言**: 可选(如 TypeScript, Python, Go, Rust等)
– **项目数量**: 默认10个

### Step 2: 执行工具
运行 GetTrending.ts 工具:

“`bash
# 基本用法(本周,全部语言,10个项目)
bun ~/.claude/skills/GitHubTrends/Tools/GetTrending.ts weekly

# 指定语言
bun ~/.claude/skills/GitHubTrends/Tools/GetTrending.ts weekly –language=TypeScript

# 指定数量
bun ~/.claude/skills/GitHubTrends/Tools/GetTrending.ts weekly –limit=20

# 组合参数
bun ~/.claude/skills/GitHubTrends/Tools/GetTrending.ts daily –language=Python –limit=15
“`

### Step 3: 显示结果
工具会自动格式化输出,包括:
– 项目排名
– 项目名称
– Star总数和周期内增长
– 编程语言
– 项目描述
– GitHub URL

### Step 4: 后续操作(可选)
根据用户需求,可以:
– 打开某个项目页面
– 使用其他skill进一步分析项目
– 将结果保存到文件供后续参考

## Integration with Other Skills

– **OSINT**: 在调查技术栈时发现热门工具
– **Research**: 研究特定语言生态系统的趋势
– **Browser**: 打开项目页面进行详细分析

## Notes

– 数据每小时更新一次
– 无需GitHub API token
– 使用公开的GitHub trending页面
– 支持的语言参数不区分大小写
FILE:Tools/GenerateDashboard.ts
#!/usr/bin/env bun
/**
* GitHub Trending Dashboard Generator
*
* 生成交互式数据可视化仪表板
*
* 使用方式:
* ./GenerateDashboard.ts [options]
*
* 选项:
* –period – daily | weekly (默认: weekly)
* –language – 编程语言筛选 (可选)
* –limit – 项目数量 (默认: 10)
* –include-news – 包含技术新闻
* –news-count – 新闻数量 (默认: 10)
* –theme – light | dark | auto (默认: auto)
* –output – 输出文件路径 (默认: ./github-trends.html)
*
* 示例:
* ./GenerateDashboard.ts
* ./GenerateDashboard.ts –period daily –language TypeScript –include-news
* ./GenerateDashboard.ts –limit 20 –output ~/trends.html
*/

import Handlebars from ‘handlebars’;
import type { DashboardOptions, TrendingProject, TechNewsItem, TemplateData } from ‘./Lib/types’;
import { registerHelpers, renderTemplate } from ‘./Lib/template-helpers’;
import { analyzeData } from ‘./Lib/visualization-helpers’;

// 注册 Handlebars 辅助函数
registerHelpers();

/**
* 构建 GitHub trending URL
*/
function buildTrendingUrl(options: DashboardOptions): string {
const baseUrl = “https://github.com/trending”;
const since = options.period === “daily” ? “daily” : “weekly”;
let url = `${baseUrl}?since=${since}`;

if (options.language) {
url += `&language=${encodeURIComponent(options.language.toLowerCase())}`;
}

return url;
}

/**
* 解析 HTML 提取 trending 项目
* (从 GetTrending.ts 复制的逻辑)
*/
async function getTrendingProjects(options: DashboardOptions): Promise {
const url = buildTrendingUrl(options);

console.error(`正在获取 GitHub trending 数据: ${url}`);

const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}

const html = await response.text();
return parseTrendingProjects(html, options.limit);
}

/**
* 解析 HTML
*/
function parseTrendingProjects(html: string, limit: number): TrendingProject[] {
const projects: TrendingProject[] = [];

try {
const articleRegex = /]*>([sS]*?)

/g;
const articles = html.match(articleRegex) || [];
const articlesToProcess = articles.slice(0, limit);

articlesToProcess.forEach((article, index) => {
try {
const headingMatch = article.match(/]*>([sS]*?)/);
let repoName: string | null = null;

if (headingMatch) {
const headingContent = headingMatch[1];
const validLinkMatch = headingContent.match(
/]*href=”/([^/”/]+/[^/”/]+)”[^>]*>(?![^<]*login)/ ); if (validLinkMatch) { repoName = validLinkMatch[1]; } } if (!repoName) { const repoMatch = article.match( /]*href=”/([a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+)”[^>]*>(?!.*(?:login|stargazers|forks|issues))/
);
repoName = repoMatch ? repoMatch[1] : null;
}

const descMatch = article.match(/]*class=”[^”]*col-9[^”]*”[^>]*>([sS]*?)

/);
const description = descMatch
? descMatch[1]
.replace(/<[^>]+>/g, “”)
.replace(/&/g, “&”)
.replace(/</g, “<") .replace(/>/g, ">“)
.replace(/"/g, ‘”‘)
.trim()
.substring(0, 200)
: “No description”;

const langMatch = article.match(/]*itemprop=”programmingLanguage”[^>]*>([^<]+)/);
const language = langMatch ? langMatch[1].trim() : “Unknown”;

// 提取stars总数 – GitHub 改了 HTML 结构,数字在 SVG 后面
const starsMatch = article.match(/stargazers[^>]*>[sS]*?s*([d,]+)/);
const totalStars = starsMatch ? starsMatch[1] : “0”;

// 尝试提取新增stars – 格式:XXX stars today/this week
const starsAddedMatch = article.match(/(d[d,]*)s+stars?s+(?:today|this week)/);
const starsAdded = starsAddedMatch ? `+${starsAddedMatch[1]}` : “”;

if (repoName && !repoName.includes(“login”) && !repoName.includes(“return_to”)) {
projects.push({
rank: index + 1,
name: repoName,
description,
language,
stars: totalStars,
starsThisPeriod: starsAdded,
url: `https://github.com/${repoName}`,
});
}
} catch (error) {
console.error(`解析第${index + 1}个项目失败:`, error);
}
});
} catch (error) {
console.error(“解析trending项目失败:”, error);
}

return projects;
}

/**
* 获取技术新闻
*/
async function getTechNews(count: number): Promise {
const HN_API = ‘https://hn.algolia.com/api/v1/search_by_date’;

try {
const response = await fetch(`${HN_API}?tags=story&hitsPerPage=${count}`);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}

const data = await response.json();

return data.hits.slice(0, count).map((hit: any) => ({
id: hit.objectID,
title: hit.title,
url: hit.url || `https://news.ycombinator.com/item?id=${hit.objectID}`,
source: ‘hackernews’,
points: hit.points || 0,
comments: hit.num_comments || 0,
timestamp: new Date(hit.created_at).toISOString(),
tags: hit._tags || []
}));
} catch (error) {
console.error(‘获取 Hacker News 失败:’, error);
return [];
}
}

/**
* 生成仪表板
*/
async function generateDashboard(options: DashboardOptions): Promise {
try {
console.error(‘ 开始生成 GitHub Trending Dashboard…n’);

// 1. 获取 GitHub Trending 数据
const projects = await getTrendingProjects(options);
console.error(`✅ 获取到 ${projects.length} 个项目`);

// 2. 获取技术新闻(如果启用)
let news: TechNewsItem[] = [];
if (options.includeNews) {
news = await getTechNews(options.newsCount);
console.error(`✅ 获取到 ${news.length} 条新闻`);
}

// 3. 分析数据
const analytics = analyzeData(projects);
console.error(`✅ 数据分析完成`);

// 4. 准备模板数据
const templateData: TemplateData = {
title: ‘GitHub Trending Dashboard’,
generatedAt: new Date().toLocaleString(‘zh-CN’),
period: options.period === ‘daily’ ? ‘Daily’ : ‘Weekly’,
projects,
news,
analytics,
options
};

// 5. 渲染模板
const templatePath = `${import.meta.dir}/../Templates/dashboard.hbs`;
const templateContent = await Bun.file(templatePath).text();
const template = Handlebars.compile(templateContent);
const html = template(templateData);
console.error(`✅ 模板渲染完成`);

// 6. 保存文件
await Bun.write(options.output, html);
console.error(`n 仪表板生成成功!`);
console.error(` 文件路径: ${options.output}`);
console.error(`n 在浏览器中打开查看效果!`);

} catch (error) {
console.error(‘n❌ 生成仪表板失败:’);
console.error(error);
process.exit(1);
}
}

/**
* 解析命令行参数
*/
function parseArgs(): DashboardOptions {
const args = process.argv.slice(2);

const options: DashboardOptions = {
period: ‘weekly’,
limit: 10,
output: ‘./github-trends.html’,
includeNews: false,
newsCount: 10,
theme: ‘auto’
};

for (let i = 0; i < args.length; i++) { const arg = args[i]; switch (arg) { case '--period': options.period = args[++i] === 'daily' ? 'daily' : 'weekly'; break; case '--language': options.language = args[++i]; break; case '--limit': options.limit = parseInt(args[++i]) || 10; break; case '--include-news': options.includeNews = true; break; case '--news-count': options.newsCount = parseInt(args[++i]) || 10; break; case '--theme': options.theme = args[++i] === 'light' || args[++i] === 'dark' ? args[i] : 'auto'; break; case '--output': options.output = args[++i]; break; default: if (arg.startsWith('--output=')) { options.output = arg.split('=')[1]; } else if (arg.startsWith('--language=')) { options.language = arg.split('=')[1]; } else if (arg.startsWith('--limit=')) { options.limit = parseInt(arg.split('=')[1]) || 10; } } } return options; } /** * 主函数 */ async function main() { const options = parseArgs(); await generateDashboard(options); } // 如果直接运行此脚本 if (import.meta.main) { main(); } // 导出供其他模块使用 export { generateDashboard }; export type { DashboardOptions }; FILE:Tools/GetTechNews.ts #!/usr/bin/env bun /** * Tech News Fetcher * * 从 Hacker News 和其他来源获取技术新闻 * * 使用方式: * ./GetTechNews.ts [count] * * 参数: * count - 获取新闻数量 (默认: 10) * * 示例: * ./GetTechNews.ts * ./GetTechNews.ts 20 */ import Parser from 'rss-parser'; import type { TechNewsItem } from './Lib/types'; const HN_API = 'https://hn.algolia.com/api/v1/search'; const parser = new Parser(); /** * 从 Hacker News Algolia API 获取新闻 */ async function getHackerNews(count: number): Promise {
try {
const response = await fetch(`${HN_API}?tags=front_page&hits=${count}`);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}

const data = await response.json();

return data.hits.map((hit: any) => ({
id: hit.objectID,
title: hit.title,
url: hit.url || `https://news.ycombinator.com/item?id=${hit.objectID}`,
source: ‘hackernews’,
points: hit.points || 0,
comments: hit.num_comments || 0,
timestamp: new Date(hit.created_at).toISOString(),
tags: hit._tags || []
}));
} catch (error) {
console.error(‘获取 Hacker News 失败:’, error);
return [];
}
}

/**
* 从 Hacker News RSS 获取新闻(备用方案)
*/
async function getHackerNewsRSS(count: number): Promise {
try {
const feed = await parser.parseURL(‘https://news.ycombinator.com/rss’);

return feed.items.slice(0, count).map((item: any) => ({
id: item.guid || item.link,
title: item.title || ‘No title’,
url: item.link,
source: ‘hackernews’,
timestamp: item.pubDate || new Date().toISOString(),
tags: [‘hackernews’, ‘rss’]
}));
} catch (error) {
console.error(‘获取 Hacker News RSS 失败:’, error);
return [];
}
}

/**
* 获取技术新闻(主函数)
*/
async function getTechNews(count: number = 10): Promise {
console.error(`正在获取技术新闻(${count}条)…`);

// 优先使用 Hacker News API
let news = await getHackerNews(count);

// 如果失败,尝试 RSS 备用
if (news.length === 0) {
console.error(‘Hacker News API 失败,尝试 RSS…’);
news = await getHackerNewsRSS(count);
}

console.error(`✅ 获取到 ${news.length} 条新闻`);
return news;
}

/**
* CLI 入口
*/
async function main() {
const args = process.argv.slice(2);
const count = parseInt(args[0]) || 10;

try {
const news = await getTechNews(count);

// 输出 JSON 格式(便于程序调用)
console.log(JSON.stringify(news, null, 2));
} catch (error) {
console.error(‘❌ 获取新闻失败:’);
console.error(error);
process.exit(1);
}
}

// 如果直接运行此脚本
if (import.meta.main) {
main();
}

// 导出供其他模块使用
export { getTechNews };
export type { TechNewsItem };
FILE:Tools/Lib/types.ts
/**
* GitHubTrends – 类型定义
*
* 定义所有 TypeScript 接口和类型
*/

/**
* GitHub Trending 项目
*/
export interface TrendingProject {
rank: number;
name: string;
description: string;
language: string;
stars: string;
starsThisPeriod: string;
url: string;
}

/**
* 技术新闻条目
*/
export interface TechNewsItem {
id: string;
title: string;
url: string;
source: string; // ‘hackernews’, ‘reddit’, etc.
points?: number;
comments?: number;
timestamp: string;
tags: string[];
}

/**
* 仪表板生成选项
*/
export interface DashboardOptions {
period: ‘daily’ | ‘weekly’;
language?: string;
limit: number;
output: string;
includeNews: boolean;
newsCount: number;
theme: ‘light’ | ‘dark’ | ‘auto’;
}

/**
* 数据分析结果
*/
export interface Analytics {
languageDistribution: Record;
totalStars: number;
topProject: TrendingProject;
growthStats: {
highest: TrendingProject;
average: number;
};
}

/**
* Trending 查询选项(用于 GetTrending.ts)
*/
export interface TrendingOptions {
period: “daily” | “weekly”;
language?: string;
limit: number;
}

/**
* 图表数据
*/
export interface ChartData {
labels: string[];
data: number[];
colors: string[];
}

/**
* 模板渲染数据
*/
export interface TemplateData {
title: string;
generatedAt: string;
period: string;
projects: TrendingProject[];
news?: TechNewsItem[];
analytics: Analytics;
options: DashboardOptions;
}
FILE:Tools/Lib/template-helpers.ts
/**
* Template Helpers
*
* Handlebars 自定义辅助函数
*/

import Handlebars from ‘handlebars’;

/**
* 注册所有自定义辅助函数
*/
export function registerHelpers(): void {
// 格式化数字(添加千位分隔符)
Handlebars.registerHelper(‘formatNumber’, (value: number) => {
return value.toLocaleString();
});

// 截断文本
Handlebars.registerHelper(‘truncate’, (str: string, length: number = 100) => {
if (str.length <= length) return str; return str.substring(0, length) + '...'; }); // 格式化日期 Handlebars.registerHelper('formatDate', (dateStr: string) => {
const date = new Date(dateStr);
return date.toLocaleDateString(‘zh-CN’, {
year: ‘numeric’,
month: ‘long’,
day: ‘numeric’,
hour: ‘2-digit’,
minute: ‘2-digit’
});
});

// JSON 序列化(用于内嵌数据)
Handlebars.registerHelper(‘json’, (context: any) => {
return JSON.stringify(context);
});

// 条件判断
Handlebars.registerHelper(‘eq’, (a: any, b: any) => {
return a === b;
});

Handlebars.registerHelper(‘ne’, (a: any, b: any) => {
return a !== b;
});

Handlebars.registerHelper(‘gt’, (a: number, b: number) => {
return a > b;
});

Handlebars.registerHelper(‘lt’, (a: number, b: number) => {
return a < b; }); } /** * 渲染模板 */ export async function renderTemplate( templatePath: string, data: any ): Promise {
const templateContent = await Bun.file(templatePath).text();
const template = Handlebars.compile(templateContent);
return template(data);
}

export default { registerHelpers, renderTemplate };
FILE:Tools/Lib/visualization-helpers.ts
/**
* Visualization Helpers
*
* 数据分析和可视化辅助函数
*/

import type { TrendingProject, Analytics } from ‘./types’;

/**
* 分析项目数据
*/
export function analyzeData(projects: TrendingProject[]): Analytics {
// 语言分布统计
const languageDistribution: Record = {};
projects.forEach(project => {
const lang = project.language;
languageDistribution[lang] = (languageDistribution[lang] || 0) + 1;
});

// 总 stars 数
const totalStars = projects.reduce((sum, project) => {
return sum + parseInt(project.stars.replace(/,/g, ”) || 0);
}, 0);

// 找出 top project
const topProject = projects.reduce((top, project) => {
const topStars = parseInt(top.stars.replace(/,/g, ”) || 0);
const projStars = parseInt(project.stars.replace(/,/g, ”) || 0);
return projStars > topStars ? project : top;
}, projects[0]);

// 增长统计
const projectsWithGrowth = projects.filter(p => p.starsThisPeriod);
const growthValues = projectsWithGrowth.map(p =>
parseInt(p.starsThisPeriod.replace(/[+,]/g, ”) || 0)
);

const highestGrowth = projectsWithGrowth.reduce((highest, project) => {
const highestValue = parseInt(highest.starsThisPeriod.replace(/[+,]/g, ”) || 0);
const projValue = parseInt(project.starsThisPeriod.replace(/[+,]/g, ”) || 0);
return projValue > highestValue ? project : highest;
}, projectsWithGrowth[0] || projects[0]);

const averageGrowth = growthValues.length > 0
? Math.round(growthValues.reduce((a, b) => a + b, 0) / growthValues.length)
: 0;

// 提取唯一语言列表(用于筛选)
const languages = Object.keys(languageDistribution).sort();

// 生成图表数据
const growthData = projects.slice(0, 10).map(p => ({
name: p.name.split(‘/’)[1] || p.name,
growth: parseInt(p.starsThisPeriod.replace(/[+,]/g, ”) || 0)
}));

return {
languageDistribution,
totalStars,
topProject,
growthStats: {
highest: highestGrowth,
average: averageGrowth
},
languages,
growthData
};
}

/**
* 格式化 stars 数字
*/
export function formatStars(starsStr: string): number {
return parseInt(starsStr.replace(/,/g, ”) || 0);
}

/**
* 解析增长数值
*/
export function parseGrowth(growthStr: string): number {
if (!growthStr) return 0;
return parseInt(growthStr.replace(/[+,]/g, ”) || 0);
}

export default { analyzeData, formatStars, parseGrowth };
FILE:Templates/dashboard.hbs





GitHub Trending Dashboard – {{period}}





GitHub Trending Dashboard

周期: {{period}} |
生成时间: {{generatedAt}}

项目总数

{{projects.length}}

{{period}} 热门趋势

总 Stars 数

{{analytics.totalStars}}

所有项目总计

最热项目

{{analytics.topProject.name}}

{{analytics.topProject.stars}} stars




语言分布

热门项目

{{#each projects}}

#{{rank}}

{{name}}

{{language}}

{{description}}

⭐ {{stars}} stars
{{#if starsThisPeriod}}
(+{{starsThisPeriod}} this {{../period}})
{{/if}}


View →

{{/each}}


{{#if news}}

技术资讯

{{#each news}}

{{title}}

{{source}}
{{#if points}}
⬆️ {{points}} points
{{/if}}
{{#if comments}}
{{comments}} comments
{{/if}}

{{/each}}

{{/if}}

由 GitHubTrends Skill 生成 | 数据来源:GitHub 和 Hacker News





FILE:Workflows/GenerateDashboard.md
# GenerateDashboard Workflow

生成交互式数据可视化仪表板的工作流程。

## Description

这个工作流使用 GenerateDashboard.ts 工具从 GitHub 获取 trending 项目,并生成交互式 HTML 仪表板,支持:
– 项目卡片展示
– 语言分布饼图
– Stars 增长柱状图
– 技术新闻列表
– 实时筛选、排序、搜索功能

## When to Use

当用户请求以下任何内容时使用此工作流:
– “生成 GitHub trending 仪表板”
– “创建趋势网页”
– “生成可视化报告”
– “export trending dashboard”
– “生成交互式网页”

## Workflow Steps

### Step 1: 确定参数
向用户确认或推断以下参数:
– **时间周期**: daily (每日) 或 weekly (每周,默认)
– **编程语言**: 可选(如 TypeScript, Python, Go, Rust等)
– **项目数量**: 默认10个
– **包含新闻**: 是否包含技术新闻
– **新闻数量**: 默认10条
– **输出路径**: 默认 ./github-trends.html

### Step 2: 执行工具
运行 GenerateDashboard.ts 工具:

“`bash
# 基本用法(本周,10个项目)
bun ~/.claude/skills/GitHubTrends/Tools/GenerateDashboard.ts

# 指定语言和新闻
bun ~/.claude/skills/GitHubTrends/Tools/GenerateDashboard.ts
–period weekly
–language TypeScript
–limit 20
–include-news
–news-count 15
–output ~/trends.html

# 每日趋势
bun ~/.claude/skills/GitHubTrends/Tools/GenerateDashboard.ts
–period daily
–output ~/daily-trends.html
“`

### Step 3: 显示结果
工具会自动:
1. 获取 GitHub trending 数据
2. 获取技术新闻(如果启用)
3. 分析数据生成统计信息
4. 渲染 HTML 模板
5. 保存到指定路径

### Step 4: 验证和打开
生成的 HTML 文件包含:
– ✅ 响应式布局
– ✅ 项目卡片展示
– ✅ 语言分布饼图
– ✅ Stars 增长柱状图
– ✅ 实时筛选功能
– ✅ 排序功能
– ✅ 搜索功能
– ✅ 技术新闻列表

## Example Usage

### Example 1: 基本仪表板
“`
User: “生成本周 GitHub trending 仪表板”

Assistant:
运行 GenerateDashboard 工具…
[执行命令,生成 /tmp/github-trends.html]
✅ 仪表板生成成功!已在浏览器中打开。
“`

### Example 2: 包含新闻的仪表板
“`
User: “生成 TypeScript 项目的每日趋势,包含新闻”

Assistant:
生成 TypeScript 每日趋势仪表板,包含技术新闻…
[执行命令:–period daily –language TypeScript –include-news]
✅ 仪表板已生成到 ~/Downloads/ts-daily-trends.html
“`

### Example 3: 自定义输出
“`
User: “生成一个包含 20 个项目的仪表板,保存到桌面”

Assistant:
生成 20 个项目的趋势仪表板…
[执行命令:–limit 20 –output ~/Desktop/github-trends.html]
✅ 完成!文件已保存到桌面
“`

## Tool Options

| 参数 | 说明 | 默认值 | 可选值 |
|——|——|——–|——–|
| `–period` | 时间周期 | `weekly` | `daily`, `weekly` |
| `–language` | 编程语言筛选 | 全部 | TypeScript, Python, Go, Rust等 |
| `–limit` | 返回项目数量 | 10 | 任意正整数 |
| `–include-news` | 包含技术新闻 | false | – |
| `–news-count` | 新闻数量 | 10 | 任意正整数 |
| `–theme` | 主题 | `auto` | `light`, `dark`, `auto` |
| `–output` | 输出文件路径 | `./github-trends.html` | 任意路径 |

## Output Features

### 数据可视化
– **语言分布饼图**: 展示各编程语言的项目占比
– **Stars 增长柱状图**: 展示前 10 名项目的 stars 增长

### 交互功能
– **搜索**: 按项目名称或描述搜索
– **筛选**: 按编程语言筛选
– **排序**: 按排名、总 stars、周期内增长排序

### 响应式设计
– 支持桌面、平板、手机
– 使用 Tailwind CSS 构建美观界面
– GitHub 风格配色

## Error Handling

如果遇到错误:
1. **网络错误**: 检查网络连接,确保能访问 GitHub
2. **解析失败**: GitHub 页面结构可能变化,工具会显示调试信息
3. **文件写入失败**: 检查输出路径的写权限

## Voice Notification

执行此工作流时发送语音通知:

“`bash
curl -s -X POST http://localhost:8888/notify
-H “Content-Type: application/json”
-d ‘{“message”: “正在生成 GitHub Trending Dashboard…”}’
> /dev/null 2>&1 &
“`

并输出文本通知:
“`
Running the **GenerateDashboard** workflow from the **GitHubTrends** skill…
“`

## Integration with Other Skills

– **Browser**: 验证生成的 HTML 页面效果
– **System**: 保存仪表板快照到 MEMORY/
– **OSINT**: 分析技术栈趋势

## Notes

– 数据每小时更新一次(GitHub trending 更新频率)
– 生成的 HTML 是完全独立的,无需服务器
– 所有依赖通过 CDN 加载(Tailwind CSS, Chart.js)
– 支持离线查看(图表已内嵌数据)

## Advanced Usage

### 批量生成
“`bash
# 生成多个语言的仪表板
for lang in TypeScript Python Go Rust; do
bun Tools/GenerateDashboard.ts
–language $lang
–output ~/trends-$lang.html
done
“`

### 定时任务
“`bash
# 每小时生成一次快照
# 添加到 crontab:
0 * * * * cd ~/.claude/skills/GitHubTrends && bun Tools/GenerateDashboard.ts –output ~/trends-$(date +%H).html
“`

### 定制主题
通过修改 `Templates/dashboard.hbs` 可以自定义:
– 配色方案
– 布局结构
– 添加新的图表类型
– 添加新的交互功能

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *