Skip to content

Commit 934f08c

Browse files
committed
feat: use new github tags to show projects
1 parent 3cc0855 commit 934f08c

5 files changed

Lines changed: 346 additions & 127 deletions

File tree

public/feed.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<description>Insights, tutorials, and thoughts on modern web development, technology trends, and best practices.</description>
88
<language>en-us</language>
99
<copyright>Copyright © 2026 TigreGotico. All rights reserved.</copyright>
10-
<lastBuildDate>Thu, 26 Feb 2026 17:34:32 GMT</lastBuildDate>
10+
<lastBuildDate>Sun, 08 Mar 2026 19:30:21 GMT</lastBuildDate>
1111
<pubDate>Tue, 13 Jan 2026 00:00:00 GMT</pubDate>
1212

1313
<item>

public/sitemap.xml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,55 +42,55 @@
4242
</url>
4343
<url>
4444
<loc>https://tigregotico.github.io/blog/2023-10-16-no-language-left-behind</loc>
45-
<lastmod>2026-02-26</lastmod>
45+
<lastmod>2025-12-26</lastmod>
4646
<changefreq>never</changefreq>
4747
<priority>0.7</priority>
4848
</url>
4949
<url>
5050
<loc>https://tigregotico.github.io/blog/2025-06-26-making-synthetic-voices-from-scratch</loc>
51-
<lastmod>2026-02-26</lastmod>
51+
<lastmod>2025-12-26</lastmod>
5252
<changefreq>never</changefreq>
5353
<priority>0.7</priority>
5454
</url>
5555
<url>
5656
<loc>https://tigregotico.github.io/blog/2025-09-17-ovos_ha_dream_team</loc>
57-
<lastmod>2026-02-26</lastmod>
57+
<lastmod>2025-12-26</lastmod>
5858
<changefreq>never</changefreq>
5959
<priority>0.7</priority>
6060
</url>
6161
<url>
6262
<loc>https://tigregotico.github.io/blog/2025-10-06-phoonnx</loc>
63-
<lastmod>2026-02-26</lastmod>
63+
<lastmod>2025-12-26</lastmod>
6464
<changefreq>never</changefreq>
6565
<priority>0.7</priority>
6666
</url>
6767
<url>
6868
<loc>https://tigregotico.github.io/blog/2025-11-20-intro-to-ovos</loc>
69-
<lastmod>2026-02-26</lastmod>
69+
<lastmod>2025-12-26</lastmod>
7070
<changefreq>never</changefreq>
7171
<priority>0.7</priority>
7272
</url>
7373
<url>
7474
<loc>https://tigregotico.github.io/blog/2025-11-26-OVOS-hivemind-industry</loc>
75-
<lastmod>2026-02-26</lastmod>
75+
<lastmod>2025-12-26</lastmod>
7676
<changefreq>never</changefreq>
7777
<priority>0.7</priority>
7878
</url>
7979
<url>
8080
<loc>https://tigregotico.github.io/blog/2025-12-09-ast</loc>
81-
<lastmod>2026-02-26</lastmod>
81+
<lastmod>2025-12-26</lastmod>
8282
<changefreq>never</changefreq>
8383
<priority>0.7</priority>
8484
</url>
8585
<url>
8686
<loc>https://tigregotico.github.io/blog/2025-12-12-barranquenho</loc>
87-
<lastmod>2026-02-26</lastmod>
87+
<lastmod>2025-12-26</lastmod>
8888
<changefreq>never</changefreq>
8989
<priority>0.7</priority>
9090
</url>
9191
<url>
9292
<loc>https://tigregotico.github.io/blog/2026-01-13-hivemind_agpl</loc>
93-
<lastmod>2026-02-26</lastmod>
93+
<lastmod>2026-02-12</lastmod>
9494
<changefreq>never</changefreq>
9595
<priority>0.7</priority>
9696
</url>

src/lib/github-projects.ts

Lines changed: 89 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
// ─── GitHub-driven project loader ────────────────────────────────────────────
22
// Scans repos from configured GitHub orgs/users.
3-
// If a repo has any topic from TOPIC_CATEGORY_MAP → it's included.
4-
// First matching topic decides the category. That's it.
3+
// If a repo has any topic from TOPIC_TO_TAG → it's included.
4+
// All matched topics become tags on the project.
55
// ─────────────────────────────────────────────────────────────────────────────
66

77
export interface GitHubSource {
88
owner: string;
99
type: 'user' | 'org';
10-
defaultCategory: string;
1110
}
1211

1312
export interface GitHubProject {
1413
name: string;
1514
description: string;
1615
url: string;
17-
category: string;
18-
tags: string[];
16+
category: string; // kept for compat — first ecosystem tag
17+
tags: string[]; // normalised display tags
1918
stars: number;
2019
language: string | null;
2120
updatedAt: string;
@@ -24,30 +23,69 @@ export interface GitHubProject {
2423
// ── Configuration ────────────────────────────────────────────────────────────
2524

2625
export const GITHUB_SOURCES: GitHubSource[] = [
27-
{ owner: 'TigreGotico', type: 'user', defaultCategory: 'In-House' },
28-
{ owner: 'OpenVoiceOS', type: 'org', defaultCategory: 'OVOS-Utils' },
26+
{ owner: 'TigreGotico', type: 'user' },
27+
{ owner: 'OpenVoiceOS', type: 'org' },
2928
];
3029

3130
/**
32-
* topic → category. One key per line.
31+
* GitHub topic → display tag name.
3332
* A repo with at least one of these topics gets listed.
34-
* First match (iteration order) wins the category.
3533
*/
34+
export const TOPIC_TO_TAG: Record<string, string> = {
35+
// Ecosystem
36+
openvoiceos: 'OpenVoiceOS',
37+
hivemind: 'HiveMind',
38+
ilenia: 'ILENIA',
39+
tigregotico: 'TigreGotico',
40+
'in-house': 'TigreGotico',
41+
// Function
42+
'ovos-plugin': 'Plugin',
43+
library: 'Library',
44+
'ovos-skill': 'Skill',
45+
framework: 'Framework',
46+
dataset: 'Dataset',
47+
tool: 'Tool',
48+
server: 'Server',
49+
// Domain
50+
'ovos-stt': 'Speech-to-Text',
51+
'ovos-tts': 'Text-to-Speech',
52+
nlp: 'NLP',
53+
'ovos-translation': 'Translation',
54+
phonetics: 'Phonetics',
55+
'ovos-embeddings': 'Embeddings',
56+
llm: 'LLM',
57+
'ovos-intent': 'Intent',
58+
audio: 'Audio',
59+
'ovos-solver': 'Solver',
60+
reranking: 'Reranking',
61+
dialog: 'Dialog',
62+
// Technology
63+
onnx: 'ONNX',
64+
gguf: 'GGUF',
65+
whisper: 'Whisper',
66+
chromadb: 'ChromaDB',
67+
qdrant: 'Qdrant',
68+
docker: 'Docker',
69+
markov: 'Markov',
70+
// Platform
71+
'raspberry-pi': 'Raspberry Pi',
72+
linux: 'Linux',
73+
macos: 'macOS',
74+
};
3675

37-
38-
export const TOPIC_CATEGORY_MAP: Record<string, string> = {
39-
'in-house': 'In-House',
40-
'ovos-intent': 'OVOS-Intents',
41-
'ovos-solver': 'OVOS-Solvers',
42-
'ovos-embeddings': 'OVOS-Embeddings',
43-
'ovos-stt': 'OVOS-STT',
44-
'ovos-translation': 'OVOS-Translation',
45-
'ovos-tts': 'OVOS-Utils',
46-
'ilenia': 'ILENIA',
76+
/** Tag groups for UI filtering. */
77+
export const TAG_GROUPS: Record<string, string[]> = {
78+
Ecosystem: ['OpenVoiceOS', 'HiveMind', 'ILENIA', 'TigreGotico'],
79+
Function: ['Plugin', 'Library', 'Skill', 'Framework', 'Dataset', 'Tool', 'Server'],
80+
Domain: ['Speech-to-Text', 'Text-to-Speech', 'NLP', 'Translation', 'Phonetics', 'Embeddings', 'LLM', 'Intent', 'Audio', 'Solver', 'Reranking', 'Dialog'],
81+
Technology: ['ONNX', 'GGUF', 'Whisper', 'ChromaDB', 'Qdrant', 'Docker', 'Markov'],
82+
Platform: ['Raspberry Pi', 'Linux', 'macOS'],
4783
};
4884

4985

50-
const CACHE_KEY = 'gh-projects-v2';
86+
const ECOSYSTEM_TAGS = new Set(TAG_GROUPS.Ecosystem);
87+
88+
const CACHE_KEY = 'gh-projects-v3';
5189
const CACHE_TTL = 1000 * 60 * 30; // 30 minutes
5290

5391
interface CacheEntry {
@@ -110,28 +148,28 @@ async function fetchAllRepos(source: GitHubSource): Promise<any[]> {
110148
}
111149

112150
/**
113-
* Determine the category for a repo:
114-
* 1. Check topics against TOPIC_CATEGORY_MAP — first match wins.
115-
* 2. Fall back to the source's defaultCategory.
151+
* Map all known topics to their display tags.
152+
* Return unique set.
116153
*/
117-
function resolveCategory(topics: string[], defaultCategory: string): string {
118-
for (const topic of topics) {
119-
if (topic in TOPIC_CATEGORY_MAP) {
120-
return TOPIC_CATEGORY_MAP[topic];
121-
}
154+
function resolveTagsFromTopics(topics: string[]): string[] {
155+
const tags = new Set<string>();
156+
for (const t of topics) {
157+
const tag = TOPIC_TO_TAG[t];
158+
if (tag) tags.add(tag);
122159
}
123-
return defaultCategory;
160+
return Array.from(tags);
124161
}
125162

126-
/** Check if a topic is in the map. */
127-
function isValidTag(topic: string): boolean {
128-
return topic in TOPIC_CATEGORY_MAP;
163+
/** Pick a "category" from the resolved tags — first ecosystem tag, else first tag. */
164+
function pickCategory(tags: string[]): string {
165+
const eco = tags.find(t => ECOSYSTEM_TAGS.has(t));
166+
return eco ?? tags[0] ?? 'Uncategorised';
129167
}
130168

131169
// ── Public API ───────────────────────────────────────────────────────────────
132170

133171
/**
134-
* Fetch projects from GitHub, filtered by TOPIC_CATEGORY_MAP keys.
172+
* Fetch projects from GitHub, filtered by TOPIC_TO_TAG keys.
135173
* Results are cached in localStorage for CACHE_TTL.
136174
*/
137175
export async function fetchGitHubProjects(): Promise<GitHubProject[]> {
@@ -154,17 +192,17 @@ export async function fetchGitHubProjects(): Promise<GitHubProject[]> {
154192
if (repo.fork || repo.archived || repo.disabled) continue;
155193

156194
const topics: string[] = (repo.topics ?? []).map((t: string) => t.toLowerCase());
157-
const matched = topics.filter(isValidTag);
195+
const tags = resolveTagsFromTopics(topics);
158196

159-
// Must have at least one valid tag
160-
if (matched.length === 0) continue;
197+
// Must have at least one recognised tag
198+
if (tags.length === 0) continue;
161199

162200
projects.push({
163201
name: repo.name,
164202
description: repo.description ?? '',
165203
url: repo.html_url,
166-
category: resolveCategory(topics, source.defaultCategory),
167-
tags: matched,
204+
category: pickCategory(tags),
205+
tags,
168206
stars: repo.stargazers_count ?? 0,
169207
language: repo.language ?? null,
170208
updatedAt: repo.updated_at ?? '',
@@ -187,16 +225,19 @@ export async function fetchStaticProjects(): Promise<GitHubProject[]> {
187225
const res = await fetch('/projects/projects.json');
188226
if (!res.ok) return [];
189227
const data: any[] = await res.json();
190-
return data.map((p) => ({
191-
name: p.name,
192-
description: p.description ?? '',
193-
url: p.url,
194-
category: p.category ?? 'Uncategorised',
195-
tags: p.tags ?? [],
196-
stars: 0,
197-
language: null,
198-
updatedAt: '',
199-
}));
228+
return data.map((p) => {
229+
const tags: string[] = p.tags ?? [];
230+
return {
231+
name: p.name,
232+
description: p.description ?? '',
233+
url: p.url,
234+
category: pickCategory(tags) || p.category || 'Uncategorised',
235+
tags,
236+
stars: 0,
237+
language: null,
238+
updatedAt: '',
239+
};
240+
});
200241
}
201242

202243
/**

0 commit comments

Comments
 (0)