mcp-server-trending 0.1.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/README.md +94 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +236 -0
- package/package.json +25 -0
package/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# mcp-server-trending ๐ฅ
|
|
2
|
+
|
|
3
|
+
> ่ฎฉ AI Agent ๅฎๆถ่ทๅ GitHubใHacker News ็ญๅนณๅฐ็็ญ้จ่ถๅฟๆฐๆฎ
|
|
4
|
+
|
|
5
|
+
ไธไธช่ฝป้็บง็ MCP๏ผModel Context Protocol๏ผๆๅกๅจ๏ผไธบ AI ๅฉๆๆไพๅฎๆถ็ๆๆฏ่ถๅฟ่ต่ฎฏใ**่ฎฉ AI ไธๅไธไบ่็ฝ่ฑ่ใ**
|
|
6
|
+
|
|
7
|
+
## ๐ ๅฟซ้ๅผๅง
|
|
8
|
+
|
|
9
|
+
### ๅฎ่ฃ
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx mcp-server-trending
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### ้
็ฝฎ๏ผๅจ MCP ๅฎขๆท็ซฏไธญ๏ผ
|
|
16
|
+
|
|
17
|
+
**Claude Code / OpenCode / Cursor:**
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"mcpServers": {
|
|
21
|
+
"trending": {
|
|
22
|
+
"command": "npx",
|
|
23
|
+
"args": ["mcp-server-trending"]
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Hermes Agent:**
|
|
30
|
+
```yaml
|
|
31
|
+
# config.yaml
|
|
32
|
+
mcpServers:
|
|
33
|
+
trending:
|
|
34
|
+
command: npx
|
|
35
|
+
args: [mcp-server-trending]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## ๐ ๅทฅๅ
ทๅ่กจ
|
|
39
|
+
|
|
40
|
+
### 1. `get_github_trending`
|
|
41
|
+
|
|
42
|
+
่ทๅ GitHub ็ญ้จไปๅบ
|
|
43
|
+
|
|
44
|
+
| ๅๆฐ | ็ฑปๅ | ้ป่ฎคๅผ | ่ฏดๆ |
|
|
45
|
+
|------|------|--------|------|
|
|
46
|
+
| `language` | string | - | ็ญ้่ฏญ่จ (ๅฆ `typescript`, `python`, `rust`) |
|
|
47
|
+
| `since` | enum | `daily` | ๆถ้ด่ๅด: `daily` / `weekly` / `monthly` |
|
|
48
|
+
| `limit` | number | `10` | ่ฟๅๆฐ้ (1-25) |
|
|
49
|
+
|
|
50
|
+
### 2. `get_hacker_news`
|
|
51
|
+
|
|
52
|
+
่ทๅ Hacker News ็ญ้จๆ
ไบ
|
|
53
|
+
|
|
54
|
+
| ๅๆฐ | ็ฑปๅ | ้ป่ฎคๅผ | ่ฏดๆ |
|
|
55
|
+
|------|------|--------|------|
|
|
56
|
+
| `type` | enum | `top` | ็ฑปๅ: `top` / `new` / `show` / `ask` / `best` |
|
|
57
|
+
| `limit` | number | `10` | ่ฟๅๆฐ้ (1-30) |
|
|
58
|
+
|
|
59
|
+
### 3. `get_trending_summary`
|
|
60
|
+
|
|
61
|
+
ไธ้ฎ่ทๅๅคๆบ็ญ้จๆ่ฆ๏ผGitHub + HN ๅๆถๆๅ๏ผ
|
|
62
|
+
|
|
63
|
+
| ๅๆฐ | ็ฑปๅ | ้ป่ฎคๅผ | ่ฏดๆ |
|
|
64
|
+
|------|------|--------|------|
|
|
65
|
+
| `sources` | array | `all` | ๆฐๆฎๆบ: `["github", "hackernews"]` |
|
|
66
|
+
|
|
67
|
+
## ๐ ่พๅบ็คบไพ
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
## ๐ฅ GitHub ไปๆฅ็ญ้จไปๅบ
|
|
71
|
+
|
|
72
|
+
1. โญ 58288 | code-yeongyu/oh-my-openagent (TypeScript)
|
|
73
|
+
omo; the best agent harness - previously oh-my-opencode
|
|
74
|
+
https://github.com/code-yeongyu/oh-my-openagent
|
|
75
|
+
|
|
76
|
+
## ๐ฐ Hacker News ็ญ้จๆ
ไบ
|
|
77
|
+
|
|
78
|
+
1. ๐ I turned a $80 RK3562 Android tablet into a Debian Linux workstation
|
|
79
|
+
โญ 306 ๅ | ๐ค tech4bot | ๐ฌ 141 ่ฏ่ฎบ
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## ๐ฆ ๅๅธ
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npm publish --access public
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## ๐ ่ฎธๅฏ
|
|
89
|
+
|
|
90
|
+
MIT - ๅ
่ดนไฝฟ็จ๏ผๆฌข่ฟ่ดก็ฎ
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
**ไธบไปไน้่ฆ่ฟไธช๏ผ** AI ไปฃ็้่ฆๅฎๆถๆฐๆฎๆฅๅๅบๆดๅฅฝ็ๅณ็ญใ่ถๅฟๆฐๆฎๅธฎๅฉ AI ไบ่งฃๅฝๅๆๆฏ็ๆ็ๆๆฐๅจๅใ
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* mcp-server-trending โ MCP server providing real-time trending data
|
|
4
|
+
* for AI agents. Fetches from GitHub Trending, Hacker News, and more.
|
|
5
|
+
*
|
|
6
|
+
* Tools:
|
|
7
|
+
* get_github_trending โ trending repos by language/date range
|
|
8
|
+
* get_hacker_news โ top/new/show HN stories
|
|
9
|
+
* get_trending_summary โ quick multi-source digest
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* mcp-server-trending โ MCP server providing real-time trending data
|
|
4
|
+
* for AI agents. Fetches from GitHub Trending, Hacker News, and more.
|
|
5
|
+
*
|
|
6
|
+
* Tools:
|
|
7
|
+
* get_github_trending โ trending repos by language/date range
|
|
8
|
+
* get_hacker_news โ top/new/show HN stories
|
|
9
|
+
* get_trending_summary โ quick multi-source digest
|
|
10
|
+
*/
|
|
11
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
12
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
13
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
// โโโ Schemas โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
16
|
+
const GitHubTrendingSchema = z.object({
|
|
17
|
+
language: z.string().optional().describe("Filter by programming language (e.g. 'typescript', 'python', 'rust')"),
|
|
18
|
+
since: z.enum(["daily", "weekly", "monthly"]).optional().default("daily").describe("Time range"),
|
|
19
|
+
limit: z.number().min(1).max(25).optional().default(10).describe("Max repos to return"),
|
|
20
|
+
});
|
|
21
|
+
const HackerNewsSchema = z.object({
|
|
22
|
+
type: z.enum(["top", "new", "show", "ask", "best"]).optional().default("top").describe("Story type"),
|
|
23
|
+
limit: z.number().min(1).max(30).optional().default(10).describe("Max stories to return"),
|
|
24
|
+
});
|
|
25
|
+
const TrendingSummarySchema = z.object({
|
|
26
|
+
sources: z.array(z.enum(["github", "hackernews"])).optional().describe("Sources to include (default: all)"),
|
|
27
|
+
});
|
|
28
|
+
// โโโ Fetch Functions โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
29
|
+
async function fetchGitHubTrending(language, since = "daily", limit = 10) {
|
|
30
|
+
const url = language
|
|
31
|
+
? `https://github.com/trending/${encodeURIComponent(language.toLowerCase())}?since=${since}`
|
|
32
|
+
: `https://github.com/trending?since=${since}`;
|
|
33
|
+
const res = await fetch(url, {
|
|
34
|
+
headers: {
|
|
35
|
+
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36",
|
|
36
|
+
"Accept": "text/html",
|
|
37
|
+
},
|
|
38
|
+
signal: AbortSignal.timeout(15_000),
|
|
39
|
+
});
|
|
40
|
+
const html = await res.text();
|
|
41
|
+
// Extract repo hrefs from the server-rendered HTML shell
|
|
42
|
+
const repoRegex = /href="\/([a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+)"/g;
|
|
43
|
+
const matches = new Set();
|
|
44
|
+
let match;
|
|
45
|
+
while ((match = repoRegex.exec(html)) !== null) {
|
|
46
|
+
const name = match[1];
|
|
47
|
+
// Filter out non-repo links
|
|
48
|
+
if (!name.includes("login") && !name.includes("trending") && !name.includes("developers") && !name.includes("sponsors")) {
|
|
49
|
+
matches.add(name);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const repos = Array.from(matches).slice(0, limit);
|
|
53
|
+
// Fetch star counts for each repo
|
|
54
|
+
const results = [];
|
|
55
|
+
for (const fullName of repos) {
|
|
56
|
+
try {
|
|
57
|
+
const apiRes = await fetch(`https://api.github.com/repos/${fullName}`, {
|
|
58
|
+
headers: {
|
|
59
|
+
"User-Agent": "mcp-server-trending/1.0",
|
|
60
|
+
"Accept": "application/vnd.github.v3+json",
|
|
61
|
+
},
|
|
62
|
+
signal: AbortSignal.timeout(10_000),
|
|
63
|
+
});
|
|
64
|
+
if (apiRes.ok) {
|
|
65
|
+
const data = await apiRes.json();
|
|
66
|
+
results.push({
|
|
67
|
+
name: data.full_name,
|
|
68
|
+
url: data.html_url,
|
|
69
|
+
stars: data.stargazers_count,
|
|
70
|
+
forks: data.forks_count,
|
|
71
|
+
language: data.language,
|
|
72
|
+
description: data.description || "ๆ ๆ่ฟฐ",
|
|
73
|
+
topics: data.topics || [],
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
results.push({ name: fullName, url: `https://github.com/${fullName}`, stars: "?", description: "่ทๅๅคฑ่ดฅ" });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
results.push({ name: fullName, url: `https://github.com/${fullName}`, stars: "?", description: "่ทๅๅคฑ่ดฅ" });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
results.sort((a, b) => (typeof b.stars === 'number' ? b.stars : 0) - (typeof a.stars === 'number' ? a.stars : 0));
|
|
85
|
+
return results;
|
|
86
|
+
}
|
|
87
|
+
async function fetchHackerNews(type = "top", limit = 10) {
|
|
88
|
+
const endpoint = type === "top" ? "topstories" :
|
|
89
|
+
type === "new" ? "newstories" :
|
|
90
|
+
type === "best" ? "beststories" :
|
|
91
|
+
type === "show" ? "showstories" :
|
|
92
|
+
"askstories";
|
|
93
|
+
const res = await fetch(`https://hacker-news.firebaseio.com/v0/${endpoint}.json`, {
|
|
94
|
+
signal: AbortSignal.timeout(10_000),
|
|
95
|
+
});
|
|
96
|
+
const ids = (await res.json());
|
|
97
|
+
const topIds = ids.slice(0, limit);
|
|
98
|
+
const stories = await Promise.all(topIds.map(async (id) => {
|
|
99
|
+
try {
|
|
100
|
+
const sRes = await fetch(`https://hacker-news.firebaseio.com/v0/item/${id}.json`, {
|
|
101
|
+
signal: AbortSignal.timeout(10_000),
|
|
102
|
+
});
|
|
103
|
+
const data = (await sRes.json());
|
|
104
|
+
return {
|
|
105
|
+
id: data.id,
|
|
106
|
+
title: data.title || "(ๆ ๆ ้ข)",
|
|
107
|
+
url: data.url || `https://news.ycombinator.com/item?id=${data.id}`,
|
|
108
|
+
points: data.score || 0,
|
|
109
|
+
author: data.by || "anonymous",
|
|
110
|
+
comments: data.descendants || 0,
|
|
111
|
+
type: data.type || "story",
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}));
|
|
118
|
+
return stories.filter((s) => s !== null)
|
|
119
|
+
.sort((a, b) => (b.points || 0) - (a.points || 0));
|
|
120
|
+
}
|
|
121
|
+
// โโโ Server Setup โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
122
|
+
const server = new Server({ name: "mcp-server-trending", version: "0.1.0" }, { capabilities: { tools: {} } });
|
|
123
|
+
// List Tools
|
|
124
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
125
|
+
tools: [
|
|
126
|
+
{
|
|
127
|
+
name: "get_github_trending",
|
|
128
|
+
description: "่ทๅ GitHub ไปๆฅ/ๆฌๅจ/ๆฌๆ็ญ้จไปๅบใๅฏๆ็ผ็จ่ฏญ่จ็ญ้ใ่ฟๅไปๅบๅใStarๆฐใๆ่ฟฐ็ญใ",
|
|
129
|
+
inputSchema: {
|
|
130
|
+
type: "object",
|
|
131
|
+
properties: {
|
|
132
|
+
language: { type: "string", description: "็ผ็จ่ฏญ่จ็ญ้ (ๅฆ 'typescript', 'python', 'rust')" },
|
|
133
|
+
since: { type: "string", enum: ["daily", "weekly", "monthly"], default: "daily", description: "ๆถ้ด่ๅด" },
|
|
134
|
+
limit: { type: "number", default: 10, description: "่ฟๅๆฐ้ (1-25)" },
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: "get_hacker_news",
|
|
140
|
+
description: "่ทๅ Hacker News ็ญ้จ/ๆๆฐๆ
ไบใ่ฟๅๆ ้ขใ้พๆฅใๅๆฐใ่ฏ่ฎบๆฐ็ญใ",
|
|
141
|
+
inputSchema: {
|
|
142
|
+
type: "object",
|
|
143
|
+
properties: {
|
|
144
|
+
type: { type: "string", enum: ["top", "new", "show", "ask", "best"], default: "top", description: "ๆ
ไบ็ฑปๅ" },
|
|
145
|
+
limit: { type: "number", default: 10, description: "่ฟๅๆฐ้ (1-30)" },
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
name: "get_trending_summary",
|
|
151
|
+
description: "ๅฟซ้่ทๅๅคๆบ็ญ้จๆ่ฆใๅๆถไป GitHub ๅ Hacker News ๆๅไปๆฅ็ญ้จ๏ผไธๆฌก่ฟๅใ",
|
|
152
|
+
inputSchema: {
|
|
153
|
+
type: "object",
|
|
154
|
+
properties: {
|
|
155
|
+
sources: { type: "array", items: { type: "string", enum: ["github", "hackernews"] }, description: "ๆฐๆฎๆบ (้ป่ฎคๅ
จ้)" },
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
}));
|
|
161
|
+
// Call Tool
|
|
162
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
163
|
+
const { name, arguments: args } = request.params;
|
|
164
|
+
try {
|
|
165
|
+
switch (name) {
|
|
166
|
+
case "get_github_trending": {
|
|
167
|
+
const { language, since, limit } = GitHubTrendingSchema.parse(args || {});
|
|
168
|
+
const repos = await fetchGitHubTrending(language, since, limit);
|
|
169
|
+
const lines = repos.map((r, i) => `${i + 1}. โญ ${r.stars} | ${r.name}${r.language ? ` (${r.language})` : ""}\n ${r.description}\n ${r.url}`);
|
|
170
|
+
return {
|
|
171
|
+
content: [{
|
|
172
|
+
type: "text",
|
|
173
|
+
text: `## ๐ฅ GitHub ${since === "daily" ? "ไปๆฅ" : since === "weekly" ? "ๆฌๅจ" : "ๆฌๆ"}็ญ้จไปๅบ\n${language ? `๏ผ่ฏญ่จ: ${language}๏ผ` : ""}\n\n${lines.join("\n\n") || "ๆๆช่ทๅๅฐๆฐๆฎ"}`,
|
|
174
|
+
}],
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
case "get_hacker_news": {
|
|
178
|
+
const { type, limit } = HackerNewsSchema.parse(args || {});
|
|
179
|
+
const stories = await fetchHackerNews(type, limit);
|
|
180
|
+
const typeNames = {
|
|
181
|
+
top: "็ญ้จ", new: "ๆๆฐ", show: "Show HN", ask: "Ask HN", best: "ๆไฝณ",
|
|
182
|
+
};
|
|
183
|
+
const lines = stories.map((s, i) => `${i + 1}. ๐ ${s.title}\n โญ ${s.points} ๅ | ๐ค ${s.author} | ๐ฌ ${s.comments} ่ฏ่ฎบ\n ${s.url}`);
|
|
184
|
+
return {
|
|
185
|
+
content: [{
|
|
186
|
+
type: "text",
|
|
187
|
+
text: `## ๐ฐ Hacker News ${typeNames[type] || type}ๆ
ไบ\n\n${lines.join("\n\n") || "ๆๆช่ทๅๅฐๆฐๆฎ"}`,
|
|
188
|
+
}],
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
case "get_trending_summary": {
|
|
192
|
+
const { sources } = TrendingSummarySchema.parse(args || {});
|
|
193
|
+
const srcList = sources || ["github", "hackernews"];
|
|
194
|
+
const [ghRepos, hnStories] = await Promise.all([
|
|
195
|
+
srcList.includes("github") ? fetchGitHubTrending(undefined, "daily", 5) : Promise.resolve([]),
|
|
196
|
+
srcList.includes("hackernews") ? fetchHackerNews("top", 5) : Promise.resolve([]),
|
|
197
|
+
]);
|
|
198
|
+
const parts = ["# ๐ ไปๆฅ็ญ้จๆ่ฆ\n"];
|
|
199
|
+
if (ghRepos.length > 0) {
|
|
200
|
+
parts.push("## ๐ฅ GitHub ็ญ้จ\n");
|
|
201
|
+
ghRepos.slice(0, 5).forEach((r, i) => {
|
|
202
|
+
parts.push(`${i + 1}. โญ ${r.stars} โ **${r.name}** โ ${String(r.description).slice(0, 80)}`);
|
|
203
|
+
});
|
|
204
|
+
parts.push("");
|
|
205
|
+
}
|
|
206
|
+
if (hnStories.length > 0) {
|
|
207
|
+
parts.push("## ๐ฐ Hacker News ็ญ้จ\n");
|
|
208
|
+
hnStories.slice(0, 5).forEach((s, i) => {
|
|
209
|
+
parts.push(`${i + 1}. โญ ${s.points} โ **${s.title}**`);
|
|
210
|
+
});
|
|
211
|
+
parts.push("");
|
|
212
|
+
}
|
|
213
|
+
return { content: [{ type: "text", text: parts.join("\n") }] };
|
|
214
|
+
}
|
|
215
|
+
default:
|
|
216
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
catch (error) {
|
|
220
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
221
|
+
return {
|
|
222
|
+
content: [{ type: "text", text: `้่ฏฏ: ${msg}` }],
|
|
223
|
+
isError: true,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
// โโโ Start โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
228
|
+
async function main() {
|
|
229
|
+
const transport = new StdioServerTransport();
|
|
230
|
+
await server.connect(transport);
|
|
231
|
+
console.error("[mcp-server-trending] ๆๅกๅจๅทฒๅฏๅจ๏ผ็ญๅพ
MCP ๅฎขๆท็ซฏ่ฟๆฅ...");
|
|
232
|
+
}
|
|
233
|
+
main().catch((err) => {
|
|
234
|
+
console.error("[mcp-server-trending] ๅฏๅจๅคฑ่ดฅ:", err);
|
|
235
|
+
process.exit(1);
|
|
236
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mcp-server-trending",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server providing real-time trending data from GitHub, Hacker News, and more โ for AI agents",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"mcp-server-trending": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": ["dist"],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"start": "node dist/index.js",
|
|
13
|
+
"prepublishOnly": "npm run build"
|
|
14
|
+
},
|
|
15
|
+
"keywords": ["mcp", "model-context-protocol", "trending", "github", "hackernews", "ai-agent"],
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@modelcontextprotocol/sdk": "^1.19.0",
|
|
19
|
+
"zod": "^3.24.0"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/node": "^22.0.0",
|
|
23
|
+
"typescript": "^5.7.0"
|
|
24
|
+
}
|
|
25
|
+
}
|