claudeup 3.15.0 → 3.17.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudeup",
3
- "version": "3.15.0",
3
+ "version": "3.17.0",
4
4
  "description": "TUI tool for managing Claude Code plugins, MCPs, and configuration",
5
5
  "type": "module",
6
6
  "main": "src/main.tsx",
@@ -0,0 +1,191 @@
1
+ export const PREDEFINED_PROFILES = [
2
+ {
3
+ id: "frontend-pro",
4
+ name: "Frontend Pro",
5
+ description: "UI implementation, design fidelity, browser-driven workflows",
6
+ icon: "🎨",
7
+ magusPlugins: [
8
+ "dev",
9
+ "code-analysis",
10
+ "terminal",
11
+ "statusline",
12
+ "designer",
13
+ "browser-use",
14
+ "multimodel",
15
+ ],
16
+ anthropicPlugins: [
17
+ "feature-dev",
18
+ "frontend-design",
19
+ "code-simplifier",
20
+ "explanatory-output-style",
21
+ "typescript-lsp",
22
+ ],
23
+ skills: [
24
+ "React Best Practices",
25
+ "Web Design Guidelines",
26
+ "shadcn/ui",
27
+ "UI/UX Pro Max",
28
+ "Find Skills",
29
+ ],
30
+ settings: {
31
+ effortLevel: "high",
32
+ alwaysThinkingEnabled: true,
33
+ model: "claude-sonnet-4-6",
34
+ outputStyle: "explanatory",
35
+ env: {
36
+ CLAUDE_CODE_ENABLE_TASKS: "true",
37
+ CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: "true",
38
+ },
39
+ includeGitInstructions: true,
40
+ respectGitignore: true,
41
+ enableAllProjectMcpServers: true,
42
+ },
43
+ },
44
+ {
45
+ id: "backend-forge",
46
+ name: "Backend Forge",
47
+ description: "API development, debugging, code quality, data workflows",
48
+ icon: "⚙️",
49
+ magusPlugins: [
50
+ "dev",
51
+ "code-analysis",
52
+ "terminal",
53
+ "statusline",
54
+ "conductor",
55
+ "multimodel",
56
+ "gtd",
57
+ ],
58
+ anthropicPlugins: [
59
+ "feature-dev",
60
+ "code-review",
61
+ "code-simplifier",
62
+ "commit-commands",
63
+ "security-guidance",
64
+ "agent-sdk-dev",
65
+ ],
66
+ skills: ["Systematic Debugging", "Neon Postgres", "Find Skills"],
67
+ settings: {
68
+ effortLevel: "high",
69
+ alwaysThinkingEnabled: true,
70
+ model: "claude-sonnet-4-6",
71
+ outputStyle: "concise",
72
+ env: {
73
+ CLAUDE_CODE_ENABLE_TASKS: "true",
74
+ CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: "true",
75
+ },
76
+ includeGitInstructions: true,
77
+ respectGitignore: true,
78
+ enableAllProjectMcpServers: true,
79
+ },
80
+ },
81
+ {
82
+ id: "infra-ops",
83
+ name: "Infra Ops",
84
+ description: "Infrastructure, operational debugging, automation, terminal-first",
85
+ icon: "🔧",
86
+ magusPlugins: [
87
+ "dev",
88
+ "code-analysis",
89
+ "terminal",
90
+ "statusline",
91
+ "multimodel",
92
+ "gtd",
93
+ "browser-use",
94
+ ],
95
+ anthropicPlugins: [
96
+ "claude-code-setup",
97
+ "hookify",
98
+ "code-review",
99
+ "commit-commands",
100
+ "security-guidance",
101
+ "plugin-dev",
102
+ ],
103
+ skills: ["Systematic Debugging", "Find Skills"],
104
+ settings: {
105
+ effortLevel: "high",
106
+ alwaysThinkingEnabled: true,
107
+ model: "claude-opus-4-6",
108
+ outputStyle: "concise",
109
+ env: {
110
+ CLAUDE_CODE_ENABLE_TASKS: "true",
111
+ CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: "true",
112
+ },
113
+ includeGitInstructions: true,
114
+ respectGitignore: true,
115
+ enableAllProjectMcpServers: true,
116
+ },
117
+ },
118
+ {
119
+ id: "growth-marketer",
120
+ name: "Growth Marketer",
121
+ description: "SEO, website audits, content production, marketing automation",
122
+ icon: "📈",
123
+ magusPlugins: [
124
+ "dev",
125
+ "code-analysis",
126
+ "terminal",
127
+ "statusline",
128
+ "seo",
129
+ "browser-use",
130
+ "nanobanana",
131
+ "video-editing",
132
+ ],
133
+ anthropicPlugins: [
134
+ "explanatory-output-style",
135
+ "frontend-design",
136
+ "playground",
137
+ ],
138
+ skills: [
139
+ "Audit Website",
140
+ "Web Design Guidelines",
141
+ "ElevenLabs TTS",
142
+ "Find Skills",
143
+ ],
144
+ settings: {
145
+ effortLevel: "medium",
146
+ alwaysThinkingEnabled: false,
147
+ model: "claude-sonnet-4-6",
148
+ outputStyle: "explanatory",
149
+ env: { CLAUDE_CODE_ENABLE_TASKS: "true" },
150
+ respectGitignore: true,
151
+ enableAllProjectMcpServers: true,
152
+ },
153
+ },
154
+ {
155
+ id: "team-lead",
156
+ name: "Team Lead",
157
+ description: "Planning, code review, coordination, and broad repo visibility",
158
+ icon: "👔",
159
+ magusPlugins: [
160
+ "dev",
161
+ "code-analysis",
162
+ "terminal",
163
+ "statusline",
164
+ "multimodel",
165
+ "gtd",
166
+ "agentdev",
167
+ ],
168
+ anthropicPlugins: [
169
+ "code-review",
170
+ "pr-review-toolkit",
171
+ "claude-md-management",
172
+ "commit-commands",
173
+ "explanatory-output-style",
174
+ "skill-creator",
175
+ ],
176
+ skills: ["Systematic Debugging", "Find Skills", "Audit Website"],
177
+ settings: {
178
+ effortLevel: "medium",
179
+ alwaysThinkingEnabled: true,
180
+ model: "claude-sonnet-4-6",
181
+ outputStyle: "explanatory",
182
+ env: {
183
+ CLAUDE_CODE_ENABLE_TASKS: "true",
184
+ CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: "true",
185
+ },
186
+ includeGitInstructions: true,
187
+ respectGitignore: true,
188
+ enableAllProjectMcpServers: true,
189
+ },
190
+ },
191
+ ];
@@ -0,0 +1,205 @@
1
+ export interface PredefinedProfile {
2
+ id: string;
3
+ name: string;
4
+ description: string;
5
+ icon: string; // emoji or symbol
6
+ magusPlugins: string[];
7
+ anthropicPlugins: string[];
8
+ skills: string[];
9
+ settings: Record<string, unknown>;
10
+ }
11
+
12
+ export const PREDEFINED_PROFILES: PredefinedProfile[] = [
13
+ {
14
+ id: "frontend-pro",
15
+ name: "Frontend Pro",
16
+ description: "UI implementation, design fidelity, browser-driven workflows",
17
+ icon: "🎨",
18
+ magusPlugins: [
19
+ "dev",
20
+ "code-analysis",
21
+ "terminal",
22
+ "statusline",
23
+ "designer",
24
+ "browser-use",
25
+ "multimodel",
26
+ ],
27
+ anthropicPlugins: [
28
+ "feature-dev",
29
+ "frontend-design",
30
+ "code-simplifier",
31
+ "explanatory-output-style",
32
+ "typescript-lsp",
33
+ ],
34
+ skills: [
35
+ "React Best Practices",
36
+ "Web Design Guidelines",
37
+ "shadcn/ui",
38
+ "UI/UX Pro Max",
39
+ "Find Skills",
40
+ ],
41
+ settings: {
42
+ effortLevel: "high",
43
+ alwaysThinkingEnabled: true,
44
+ model: "claude-sonnet-4-6",
45
+ outputStyle: "explanatory",
46
+ env: {
47
+ CLAUDE_CODE_ENABLE_TASKS: "true",
48
+ CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: "true",
49
+ },
50
+ includeGitInstructions: true,
51
+ respectGitignore: true,
52
+ enableAllProjectMcpServers: true,
53
+ },
54
+ },
55
+ {
56
+ id: "backend-forge",
57
+ name: "Backend Forge",
58
+ description: "API development, debugging, code quality, data workflows",
59
+ icon: "⚙️",
60
+ magusPlugins: [
61
+ "dev",
62
+ "code-analysis",
63
+ "terminal",
64
+ "statusline",
65
+ "conductor",
66
+ "multimodel",
67
+ "gtd",
68
+ ],
69
+ anthropicPlugins: [
70
+ "feature-dev",
71
+ "code-review",
72
+ "code-simplifier",
73
+ "commit-commands",
74
+ "security-guidance",
75
+ "agent-sdk-dev",
76
+ ],
77
+ skills: ["Systematic Debugging", "Neon Postgres", "Find Skills"],
78
+ settings: {
79
+ effortLevel: "high",
80
+ alwaysThinkingEnabled: true,
81
+ model: "claude-sonnet-4-6",
82
+ outputStyle: "concise",
83
+ env: {
84
+ CLAUDE_CODE_ENABLE_TASKS: "true",
85
+ CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: "true",
86
+ },
87
+ includeGitInstructions: true,
88
+ respectGitignore: true,
89
+ enableAllProjectMcpServers: true,
90
+ },
91
+ },
92
+ {
93
+ id: "infra-ops",
94
+ name: "Infra Ops",
95
+ description:
96
+ "Infrastructure, operational debugging, automation, terminal-first",
97
+ icon: "🔧",
98
+ magusPlugins: [
99
+ "dev",
100
+ "code-analysis",
101
+ "terminal",
102
+ "statusline",
103
+ "multimodel",
104
+ "gtd",
105
+ "browser-use",
106
+ ],
107
+ anthropicPlugins: [
108
+ "claude-code-setup",
109
+ "hookify",
110
+ "code-review",
111
+ "commit-commands",
112
+ "security-guidance",
113
+ "plugin-dev",
114
+ ],
115
+ skills: ["Systematic Debugging", "Find Skills"],
116
+ settings: {
117
+ effortLevel: "high",
118
+ alwaysThinkingEnabled: true,
119
+ model: "claude-opus-4-6",
120
+ outputStyle: "concise",
121
+ env: {
122
+ CLAUDE_CODE_ENABLE_TASKS: "true",
123
+ CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: "true",
124
+ },
125
+ includeGitInstructions: true,
126
+ respectGitignore: true,
127
+ enableAllProjectMcpServers: true,
128
+ },
129
+ },
130
+ {
131
+ id: "growth-marketer",
132
+ name: "Growth Marketer",
133
+ description:
134
+ "SEO, website audits, content production, marketing automation",
135
+ icon: "📈",
136
+ magusPlugins: [
137
+ "dev",
138
+ "code-analysis",
139
+ "terminal",
140
+ "statusline",
141
+ "seo",
142
+ "browser-use",
143
+ "nanobanana",
144
+ "video-editing",
145
+ ],
146
+ anthropicPlugins: [
147
+ "explanatory-output-style",
148
+ "frontend-design",
149
+ "playground",
150
+ ],
151
+ skills: [
152
+ "Audit Website",
153
+ "Web Design Guidelines",
154
+ "ElevenLabs TTS",
155
+ "Find Skills",
156
+ ],
157
+ settings: {
158
+ effortLevel: "medium",
159
+ alwaysThinkingEnabled: false,
160
+ model: "claude-sonnet-4-6",
161
+ outputStyle: "explanatory",
162
+ env: { CLAUDE_CODE_ENABLE_TASKS: "true" },
163
+ respectGitignore: true,
164
+ enableAllProjectMcpServers: true,
165
+ },
166
+ },
167
+ {
168
+ id: "team-lead",
169
+ name: "Team Lead",
170
+ description:
171
+ "Planning, code review, coordination, and broad repo visibility",
172
+ icon: "👔",
173
+ magusPlugins: [
174
+ "dev",
175
+ "code-analysis",
176
+ "terminal",
177
+ "statusline",
178
+ "multimodel",
179
+ "gtd",
180
+ "agentdev",
181
+ ],
182
+ anthropicPlugins: [
183
+ "code-review",
184
+ "pr-review-toolkit",
185
+ "claude-md-management",
186
+ "commit-commands",
187
+ "explanatory-output-style",
188
+ "skill-creator",
189
+ ],
190
+ skills: ["Systematic Debugging", "Find Skills", "Audit Website"],
191
+ settings: {
192
+ effortLevel: "medium",
193
+ alwaysThinkingEnabled: true,
194
+ model: "claude-sonnet-4-6",
195
+ outputStyle: "explanatory",
196
+ env: {
197
+ CLAUDE_CODE_ENABLE_TASKS: "true",
198
+ CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: "true",
199
+ },
200
+ includeGitInstructions: true,
201
+ respectGitignore: true,
202
+ enableAllProjectMcpServers: true,
203
+ },
204
+ },
205
+ ];
@@ -5,6 +5,7 @@ export const RECOMMENDED_SKILLS = [
5
5
  skillPath: "skills/find-skills",
6
6
  description: "Discover and install new skills from the ecosystem",
7
7
  category: "search",
8
+ stars: 12000,
8
9
  },
9
10
  {
10
11
  name: "React Best Practices",
@@ -12,6 +13,7 @@ export const RECOMMENDED_SKILLS = [
12
13
  skillPath: "skills/react-best-practices",
13
14
  description: "Modern React patterns and Vercel deployment guidelines",
14
15
  category: "frontend",
16
+ stars: 24000,
15
17
  },
16
18
  {
17
19
  name: "Web Design Guidelines",
@@ -19,6 +21,7 @@ export const RECOMMENDED_SKILLS = [
19
21
  skillPath: "skills/web-design-guidelines",
20
22
  description: "UI/UX design principles and web standards",
21
23
  category: "design",
24
+ stars: 24000,
22
25
  },
23
26
  {
24
27
  name: "Remotion Best Practices",
@@ -26,6 +29,7 @@ export const RECOMMENDED_SKILLS = [
26
29
  skillPath: "skills/remotion-best-practices",
27
30
  description: "Programmatic video creation with Remotion",
28
31
  category: "media",
32
+ stars: 2400,
29
33
  },
30
34
  {
31
35
  name: "UI/UX Pro Max",
@@ -33,6 +37,7 @@ export const RECOMMENDED_SKILLS = [
33
37
  skillPath: "skills_en/ui-ux-pro-max",
34
38
  description: "50 styles, 21 palettes, 50 font pairings, 9 stacks. Covers React, Next.js, Vue, Svelte, SwiftUI, Flutter, Tailwind, shadcn/ui",
35
39
  category: "design",
40
+ stars: 109,
36
41
  },
37
42
  {
38
43
  name: "ElevenLabs TTS",
@@ -40,6 +45,7 @@ export const RECOMMENDED_SKILLS = [
40
45
  skillPath: "skills/elevenlabs-tts",
41
46
  description: "Text-to-speech with ElevenLabs API integration",
42
47
  category: "media",
48
+ stars: 206,
43
49
  },
44
50
  {
45
51
  name: "Audit Website",
@@ -47,6 +53,7 @@ export const RECOMMENDED_SKILLS = [
47
53
  skillPath: "skills/audit-website",
48
54
  description: "Security and quality auditing for web applications",
49
55
  category: "security",
56
+ stars: 67,
50
57
  },
51
58
  {
52
59
  name: "Systematic Debugging",
@@ -54,6 +61,7 @@ export const RECOMMENDED_SKILLS = [
54
61
  skillPath: "skills/systematic-debugging",
55
62
  description: "Structured debugging methodology with root cause analysis",
56
63
  category: "debugging",
64
+ stars: 113000,
57
65
  },
58
66
  {
59
67
  name: "shadcn/ui",
@@ -61,6 +69,7 @@ export const RECOMMENDED_SKILLS = [
61
69
  skillPath: "packages/shadcn",
62
70
  description: "shadcn/ui component library patterns and usage",
63
71
  category: "frontend",
72
+ stars: 111000,
64
73
  },
65
74
  {
66
75
  name: "Neon Postgres",
@@ -68,6 +77,7 @@ export const RECOMMENDED_SKILLS = [
68
77
  skillPath: "skills/neon-postgres",
69
78
  description: "Neon serverless Postgres setup and best practices",
70
79
  category: "database",
80
+ stars: 42,
71
81
  },
72
82
  {
73
83
  name: "Neon Serverless",
@@ -75,6 +85,7 @@ export const RECOMMENDED_SKILLS = [
75
85
  skillPath: "skills/neon-serverless",
76
86
  description: "Serverless database patterns with Neon",
77
87
  category: "database",
88
+ stars: 81,
78
89
  },
79
90
  ];
80
91
  export const DEFAULT_SKILL_REPOS = [
@@ -6,6 +6,7 @@ export interface RecommendedSkill {
6
6
  skillPath: string;
7
7
  description: string;
8
8
  category: string;
9
+ stars?: number; // fallback when GitHub API is rate-limited
9
10
  }
10
11
 
11
12
  export const RECOMMENDED_SKILLS: RecommendedSkill[] = [
@@ -15,6 +16,7 @@ export const RECOMMENDED_SKILLS: RecommendedSkill[] = [
15
16
  skillPath: "skills/find-skills",
16
17
  description: "Discover and install new skills from the ecosystem",
17
18
  category: "search",
19
+ stars: 12000,
18
20
  },
19
21
  {
20
22
  name: "React Best Practices",
@@ -22,6 +24,7 @@ export const RECOMMENDED_SKILLS: RecommendedSkill[] = [
22
24
  skillPath: "skills/react-best-practices",
23
25
  description: "Modern React patterns and Vercel deployment guidelines",
24
26
  category: "frontend",
27
+ stars: 24000,
25
28
  },
26
29
  {
27
30
  name: "Web Design Guidelines",
@@ -29,6 +32,7 @@ export const RECOMMENDED_SKILLS: RecommendedSkill[] = [
29
32
  skillPath: "skills/web-design-guidelines",
30
33
  description: "UI/UX design principles and web standards",
31
34
  category: "design",
35
+ stars: 24000,
32
36
  },
33
37
  {
34
38
  name: "Remotion Best Practices",
@@ -36,6 +40,7 @@ export const RECOMMENDED_SKILLS: RecommendedSkill[] = [
36
40
  skillPath: "skills/remotion-best-practices",
37
41
  description: "Programmatic video creation with Remotion",
38
42
  category: "media",
43
+ stars: 2400,
39
44
  },
40
45
  {
41
46
  name: "UI/UX Pro Max",
@@ -43,6 +48,7 @@ export const RECOMMENDED_SKILLS: RecommendedSkill[] = [
43
48
  skillPath: "skills_en/ui-ux-pro-max",
44
49
  description: "50 styles, 21 palettes, 50 font pairings, 9 stacks. Covers React, Next.js, Vue, Svelte, SwiftUI, Flutter, Tailwind, shadcn/ui",
45
50
  category: "design",
51
+ stars: 109,
46
52
  },
47
53
  {
48
54
  name: "ElevenLabs TTS",
@@ -50,6 +56,7 @@ export const RECOMMENDED_SKILLS: RecommendedSkill[] = [
50
56
  skillPath: "skills/elevenlabs-tts",
51
57
  description: "Text-to-speech with ElevenLabs API integration",
52
58
  category: "media",
59
+ stars: 206,
53
60
  },
54
61
  {
55
62
  name: "Audit Website",
@@ -57,6 +64,7 @@ export const RECOMMENDED_SKILLS: RecommendedSkill[] = [
57
64
  skillPath: "skills/audit-website",
58
65
  description: "Security and quality auditing for web applications",
59
66
  category: "security",
67
+ stars: 67,
60
68
  },
61
69
  {
62
70
  name: "Systematic Debugging",
@@ -64,6 +72,7 @@ export const RECOMMENDED_SKILLS: RecommendedSkill[] = [
64
72
  skillPath: "skills/systematic-debugging",
65
73
  description: "Structured debugging methodology with root cause analysis",
66
74
  category: "debugging",
75
+ stars: 113000,
67
76
  },
68
77
  {
69
78
  name: "shadcn/ui",
@@ -71,6 +80,7 @@ export const RECOMMENDED_SKILLS: RecommendedSkill[] = [
71
80
  skillPath: "packages/shadcn",
72
81
  description: "shadcn/ui component library patterns and usage",
73
82
  category: "frontend",
83
+ stars: 111000,
74
84
  },
75
85
  {
76
86
  name: "Neon Postgres",
@@ -78,6 +88,7 @@ export const RECOMMENDED_SKILLS: RecommendedSkill[] = [
78
88
  skillPath: "skills/neon-postgres",
79
89
  description: "Neon serverless Postgres setup and best practices",
80
90
  category: "database",
91
+ stars: 42,
81
92
  },
82
93
  {
83
94
  name: "Neon Serverless",
@@ -85,6 +96,7 @@ export const RECOMMENDED_SKILLS: RecommendedSkill[] = [
85
96
  skillPath: "skills/neon-serverless",
86
97
  description: "Serverless database patterns with Neon",
87
98
  category: "database",
99
+ stars: 81,
88
100
  },
89
101
  ];
90
102
 
@@ -202,28 +202,55 @@ export async function fetchAvailableSkills(_repos, projectPath) {
202
202
  // 2. Fetch popular skills from Firebase API
203
203
  const popular = await fetchPopularSkills(30);
204
204
  const popularSkills = popular.map((s) => markInstalled({ ...s, isRecommended: false }));
205
- // 3. Enrich recommended skills with GitHub repo stars
206
- // Fetch stars for each unique repo (typically ~7 repos, parallel)
205
+ // 3. Enrich recommended skills with GitHub repo stars (cached to disk)
206
+ const starsCachePath = path.join(os.homedir(), ".claude", "skill-stars-cache.json");
207
+ let starsCache = {};
208
+ try {
209
+ starsCache = await fs.readJson(starsCachePath);
210
+ }
211
+ catch { /* no cache yet */ }
207
212
  const uniqueRepos = [...new Set(recommendedSkills.map((s) => s.source.repo))];
208
213
  const repoStars = new Map();
209
- try {
210
- const starResults = await Promise.allSettled(uniqueRepos.map(async (repo) => {
214
+ const cacheMaxAge = 24 * 60 * 60 * 1000; // 24 hours
215
+ let cacheUpdated = false;
216
+ for (const repo of uniqueRepos) {
217
+ const cached = starsCache[repo];
218
+ if (cached && Date.now() - new Date(cached.fetchedAt).getTime() < cacheMaxAge) {
219
+ repoStars.set(repo, cached.stars);
220
+ continue;
221
+ }
222
+ // Try fetching from GitHub (may be rate limited)
223
+ try {
211
224
  const res = await fetch(`https://api.github.com/repos/${repo}`, {
212
225
  headers: { Accept: "application/vnd.github+json" },
213
226
  signal: AbortSignal.timeout(5000),
214
227
  });
215
- if (!res.ok)
216
- return;
217
- const data = (await res.json());
218
- if (data.stargazers_count)
219
- repoStars.set(repo, data.stargazers_count);
220
- }));
228
+ if (res.ok) {
229
+ const data = (await res.json());
230
+ if (data.stargazers_count) {
231
+ repoStars.set(repo, data.stargazers_count);
232
+ starsCache[repo] = { stars: data.stargazers_count, fetchedAt: new Date().toISOString() };
233
+ cacheUpdated = true;
234
+ }
235
+ }
236
+ else if (cached) {
237
+ // Rate limited but have stale cache — use it
238
+ repoStars.set(repo, cached.stars);
239
+ }
240
+ }
241
+ catch {
242
+ if (cached)
243
+ repoStars.set(repo, cached.stars);
244
+ }
221
245
  }
222
- catch {
223
- // Non-fatal — stars are cosmetic
246
+ if (cacheUpdated) {
247
+ try {
248
+ await fs.writeJson(starsCachePath, starsCache);
249
+ }
250
+ catch { /* ignore */ }
224
251
  }
225
252
  for (const rec of recommendedSkills) {
226
- rec.stars = repoStars.get(rec.source.repo) || undefined;
253
+ rec.stars = repoStars.get(rec.source.repo) || rec.stars || undefined;
227
254
  }
228
255
  // 4. Combine: recommended first, then popular (dedup by name)
229
256
  const seen = new Set(recommendedSkills.map((s) => s.name));