codex-skills-mcp 1.0.3 → 1.0.6
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/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +11 -1
- package/dist/config.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/remote/github.d.ts +8 -1
- package/dist/remote/github.d.ts.map +1 -1
- package/dist/remote/github.js +199 -70
- package/dist/remote/github.js.map +1 -1
- package/package.json +1 -1
package/dist/config.d.ts
CHANGED
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,MAAM;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,MAAM;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAuBD;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CA+FlD;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,aAAa,EAAE,CAGlE"}
|
package/dist/config.js
CHANGED
|
@@ -83,6 +83,15 @@ export function parseConfig(args) {
|
|
|
83
83
|
process.exit(1);
|
|
84
84
|
}
|
|
85
85
|
const useCnMirror = args.includes("--cn-mirror");
|
|
86
|
+
// Concurrent downloads for skill files (default 16). Configurable via
|
|
87
|
+
// --download-concurrency <n> or CODEX_SKILLS_DOWNLOAD_CONCURRENCY env var.
|
|
88
|
+
const concurrencyArg = getArg("--download-concurrency");
|
|
89
|
+
const concurrencyEnv = process.env.CODEX_SKILLS_DOWNLOAD_CONCURRENCY;
|
|
90
|
+
const downloadConcurrency = parseInt(concurrencyArg || concurrencyEnv || "16", 10);
|
|
91
|
+
if (!Number.isInteger(downloadConcurrency) || downloadConcurrency < 1) {
|
|
92
|
+
console.error("Error: --download-concurrency must be a positive integer");
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
86
95
|
return {
|
|
87
96
|
skillsDir,
|
|
88
97
|
manifestPath,
|
|
@@ -91,7 +100,8 @@ export function parseConfig(args) {
|
|
|
91
100
|
githubBranch,
|
|
92
101
|
githubPath,
|
|
93
102
|
githubToken,
|
|
94
|
-
useCnMirror
|
|
103
|
+
useCnMirror,
|
|
104
|
+
downloadConcurrency
|
|
95
105
|
};
|
|
96
106
|
}
|
|
97
107
|
export function loadManifest(manifestPath) {
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ import { registerPlanWorkflow } from "./tools/plan-workflow.js";
|
|
|
31
31
|
function createServer(searchEngine, loader) {
|
|
32
32
|
const server = new McpServer({
|
|
33
33
|
name: "codex-skills",
|
|
34
|
-
version: "1.0.
|
|
34
|
+
version: "1.0.6",
|
|
35
35
|
});
|
|
36
36
|
registerSearchSkills(server, searchEngine);
|
|
37
37
|
registerListCategories(server, searchEngine);
|
|
@@ -109,7 +109,7 @@ async function startHTTP(searchEngine, loader, port) {
|
|
|
109
109
|
res.json({
|
|
110
110
|
status: "ok",
|
|
111
111
|
name: "codex-skills-mcp",
|
|
112
|
-
version: "1.0.
|
|
112
|
+
version: "1.0.6",
|
|
113
113
|
skills: searchEngine.getCategories().reduce((s, c) => s + c.skill_count, 0),
|
|
114
114
|
});
|
|
115
115
|
});
|
package/dist/remote/github.d.ts
CHANGED
|
@@ -8,7 +8,14 @@ export declare function initRemote(config: Config): Promise<void>;
|
|
|
8
8
|
*/
|
|
9
9
|
export declare function fetchManifest(config: Config): Promise<void>;
|
|
10
10
|
/**
|
|
11
|
-
* Ensure a skill's directory is downloaded and cached
|
|
11
|
+
* Ensure a skill's directory is downloaded and cached.
|
|
12
|
+
*
|
|
13
|
+
* - Listing uses only 2 API calls (parent contents + recursive subtree tree),
|
|
14
|
+
* never the full repository tree, so huge repos stay within GitHub limits.
|
|
15
|
+
* - Downloads run concurrently and skip files already cached with the right size.
|
|
16
|
+
* - A `.codex-skills.tree.json` marker records the file list + completion state,
|
|
17
|
+
* so an interrupted download resumes on the next call instead of being
|
|
18
|
+
* silently treated as complete.
|
|
12
19
|
*/
|
|
13
20
|
export declare function ensureSkillFetched(config: Config, entry: ManifestEntry): Promise<void>;
|
|
14
21
|
//# sourceMappingURL=github.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/remote/github.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/remote/github.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAkR1D;;GAEG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9D;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUjE;AAED;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA6C5F"}
|
package/dist/remote/github.js
CHANGED
|
@@ -1,62 +1,207 @@
|
|
|
1
|
-
import { writeFileSync, existsSync, mkdirSync } from "node:fs";
|
|
2
|
-
import { resolve, dirname } from "node:path";
|
|
1
|
+
import { writeFileSync, existsSync, mkdirSync, readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { resolve, dirname, join, basename } from "node:path";
|
|
3
|
+
/** Metadata marker written inside each cached skill directory */
|
|
4
|
+
const TREE_CACHE_FILE = ".codex-skills.tree.json";
|
|
5
|
+
/**
|
|
6
|
+
* Fetch with timeout using AbortController
|
|
7
|
+
*/
|
|
8
|
+
async function fetchWithTimeout(url, options = {}, timeout = 3000) {
|
|
9
|
+
const controller = new AbortController();
|
|
10
|
+
const id = setTimeout(() => controller.abort(), timeout);
|
|
11
|
+
try {
|
|
12
|
+
const res = await fetch(url, { ...options, signal: controller.signal });
|
|
13
|
+
return res;
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
if (error.name === 'AbortError') {
|
|
17
|
+
throw new Error(`Request timed out after ${timeout}ms`);
|
|
18
|
+
}
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
finally {
|
|
22
|
+
clearTimeout(id);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
3
25
|
/**
|
|
4
26
|
* Fetch with optional auth token
|
|
5
27
|
*/
|
|
6
|
-
async function fetchWithAuth(url, token) {
|
|
28
|
+
async function fetchWithAuth(url, token, timeout = 3000) {
|
|
7
29
|
const headers = {};
|
|
8
30
|
if (token) {
|
|
9
31
|
headers["Authorization"] = `Bearer ${token}`;
|
|
10
32
|
}
|
|
11
|
-
const res = await
|
|
33
|
+
const res = await fetchWithTimeout(url, { headers }, timeout);
|
|
12
34
|
if (!res.ok) {
|
|
13
35
|
throw new Error(`Failed to fetch ${url}: ${res.status} ${res.statusText}`);
|
|
14
36
|
}
|
|
15
37
|
return res;
|
|
16
38
|
}
|
|
17
39
|
/**
|
|
18
|
-
* Advanced raw file downloader with
|
|
40
|
+
* Advanced raw file downloader with Automatic 3-second Timeout Fallback Chain
|
|
19
41
|
*/
|
|
20
42
|
async function fetchRawWithFallback(config, path) {
|
|
21
|
-
//
|
|
22
|
-
if (!config.useCnMirror) {
|
|
23
|
-
const rawUrl = `https://raw.githubusercontent.com/${config.githubRepo}/${config.githubBranch}/${path}`;
|
|
24
|
-
return fetchWithAuth(rawUrl, config.githubToken);
|
|
25
|
-
}
|
|
26
|
-
// Define the fallback chain
|
|
43
|
+
// Define the smart fallback chain
|
|
27
44
|
const fallbacks = [
|
|
28
|
-
//
|
|
45
|
+
// 0. Official direct (Fastest if VPN is on, but fails/timeouts in pure CN network)
|
|
46
|
+
{
|
|
47
|
+
name: "GitHub Official",
|
|
48
|
+
url: `https://raw.githubusercontent.com/${config.githubRepo}/${config.githubBranch}/${path}`,
|
|
49
|
+
useAuth: true,
|
|
50
|
+
timeout: 3000 // 3 seconds timeout for direct connection
|
|
51
|
+
},
|
|
52
|
+
// 1. jsdelivr CDN (Fastest in China without VPN)
|
|
29
53
|
{
|
|
30
54
|
name: "jsDelivr",
|
|
31
|
-
url: `https://cdn.jsdelivr.net/gh/${config.githubRepo}@${config.githubBranch}/${path}
|
|
55
|
+
url: `https://cdn.jsdelivr.net/gh/${config.githubRepo}@${config.githubBranch}/${path}`,
|
|
56
|
+
useAuth: false,
|
|
57
|
+
timeout: 10000 // longer timeout for fallbacks
|
|
32
58
|
},
|
|
33
59
|
// 2. gh-proxy.com (Reliable raw proxy)
|
|
34
60
|
{
|
|
35
61
|
name: "gh-proxy.com",
|
|
36
|
-
url: `https://gh-proxy.com/https://raw.githubusercontent.com/${config.githubRepo}/${config.githubBranch}/${path}
|
|
62
|
+
url: `https://gh-proxy.com/https://raw.githubusercontent.com/${config.githubRepo}/${config.githubBranch}/${path}`,
|
|
63
|
+
useAuth: false,
|
|
64
|
+
timeout: 10000
|
|
37
65
|
},
|
|
38
66
|
// 3. ghfast.top (Backup raw proxy)
|
|
39
67
|
{
|
|
40
68
|
name: "ghfast.top",
|
|
41
|
-
url: `https://ghfast.top/https://raw.githubusercontent.com/${config.githubRepo}/${config.githubBranch}/${path}
|
|
69
|
+
url: `https://ghfast.top/https://raw.githubusercontent.com/${config.githubRepo}/${config.githubBranch}/${path}`,
|
|
70
|
+
useAuth: false,
|
|
71
|
+
timeout: 10000
|
|
42
72
|
}
|
|
43
73
|
];
|
|
44
74
|
let lastError = null;
|
|
45
75
|
for (const proxy of fallbacks) {
|
|
46
76
|
try {
|
|
47
|
-
|
|
48
|
-
|
|
77
|
+
const res = proxy.useAuth
|
|
78
|
+
? await fetchWithAuth(proxy.url, config.githubToken, proxy.timeout)
|
|
79
|
+
: await fetchWithTimeout(proxy.url, {}, proxy.timeout);
|
|
49
80
|
if (!res.ok) {
|
|
50
81
|
throw new Error(`HTTP ${res.status}`);
|
|
51
82
|
}
|
|
52
83
|
return res; // Success!
|
|
53
84
|
}
|
|
54
85
|
catch (e) {
|
|
55
|
-
console.error(`[codex-skills-mcp] Network warning: ${proxy.name} failed
|
|
86
|
+
console.error(`[codex-skills-mcp] Network warning: [${proxy.name}] failed (${e.message}). Auto-switching to next node...`);
|
|
56
87
|
lastError = e;
|
|
57
88
|
}
|
|
58
89
|
}
|
|
59
|
-
throw new Error(`All
|
|
90
|
+
throw new Error(`All download nodes failed to fetch ${path}. Network error: ${lastError?.message}\n\n【网络兜底提示】您的网络环境极其恶劣,所有的直连与免翻墙加速节点均已失效。为了保证技能库的稳定拉取,建议您配置科学上网环境。推荐服务:https://a.xn--30rs3b33gl8gq9hj52b.com/#/register?code=4uq59ogs (该服务极具性价比,最便宜每月200G流量一年仅需13.99元)`);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Build the remote repo path of a skill directory, e.g.
|
|
94
|
+
* "codex-skills/00_全局大管家/12_学术论文与科研图表/nature-skills"
|
|
95
|
+
*/
|
|
96
|
+
function buildSkillRemotePath(config, relPath) {
|
|
97
|
+
let prefix = config.githubPath ? `${config.githubPath}/${relPath}` : relPath;
|
|
98
|
+
prefix = prefix.replace(/^\.\//, "").replace(/^\/+/, "").replace(/\/+$/, "");
|
|
99
|
+
return prefix;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* List a skill's files with exactly 2 GitHub API calls (never the full repo tree):
|
|
103
|
+
* 1. contents(parent dir) -> locate the skill dir and get its tree SHA
|
|
104
|
+
* 2. git/trees/{sha}?recursive=1 -> all blobs of that single skill subtree, with sizes
|
|
105
|
+
*/
|
|
106
|
+
async function fetchSkillTree(config, relPath) {
|
|
107
|
+
const segments = relPath.split("/").filter(Boolean);
|
|
108
|
+
const dirName = segments[segments.length - 1];
|
|
109
|
+
const parentPath = segments.slice(0, -1).join("/");
|
|
110
|
+
const parentRemotePath = buildSkillRemotePath(config, parentPath);
|
|
111
|
+
const apiBase = `https://api.github.com/repos/${config.githubRepo}/`;
|
|
112
|
+
// STEP 1: find the skill directory's tree SHA from its parent listing
|
|
113
|
+
const contentsRes = await fetchWithAuth(`${apiBase}contents/${parentRemotePath}?ref=${config.githubBranch}`, config.githubToken, 10000);
|
|
114
|
+
const contents = (await contentsRes.json());
|
|
115
|
+
if (Array.isArray(contents)) {
|
|
116
|
+
const dir = contents.find((item) => item.name === dirName && item.type === "dir");
|
|
117
|
+
if (!dir || !dir.sha) {
|
|
118
|
+
throw new Error(`Skill directory "${dirName}" not found at "${parentRemotePath}"`);
|
|
119
|
+
}
|
|
120
|
+
// STEP 2: recursive tree of ONLY this skill subtree (small, not truncated)
|
|
121
|
+
const treeRes = await fetchWithAuth(`${apiBase}git/trees/${dir.sha}?recursive=1`, config.githubToken, 30000);
|
|
122
|
+
const tree = (await treeRes.json());
|
|
123
|
+
if (tree.truncated) {
|
|
124
|
+
throw new Error(`Git tree truncated for skill "${dirName}" (too many files)`);
|
|
125
|
+
}
|
|
126
|
+
const files = (tree.tree || [])
|
|
127
|
+
.filter((t) => t.type === "blob" && typeof t.path === "string")
|
|
128
|
+
.map((t) => ({
|
|
129
|
+
path: t.path,
|
|
130
|
+
size: typeof t.size === "number" ? t.size : 0,
|
|
131
|
+
}));
|
|
132
|
+
return { version: 1, files };
|
|
133
|
+
}
|
|
134
|
+
if (contents && contents.type === "file") {
|
|
135
|
+
// Single-file skill: the manifest "directory" is actually one file
|
|
136
|
+
return {
|
|
137
|
+
version: 1,
|
|
138
|
+
files: [{ path: basename(contents.path), size: contents.size ?? 0 }],
|
|
139
|
+
singleFileRemotePath: `${parentRemotePath}/${dirName}`,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
throw new Error(`Unexpected GitHub Contents API response for "${parentRemotePath}": ${contentsRes.status}`);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Run `worker` over `items` with at most `limit` concurrent executions.
|
|
146
|
+
* Collects per-item errors instead of failing fast, so one bad file never
|
|
147
|
+
* aborts an entire skill download.
|
|
148
|
+
*/
|
|
149
|
+
async function runPool(items, limit, worker) {
|
|
150
|
+
const errors = [];
|
|
151
|
+
let next = 0;
|
|
152
|
+
const run = async () => {
|
|
153
|
+
while (next < items.length) {
|
|
154
|
+
const index = next++;
|
|
155
|
+
try {
|
|
156
|
+
await worker(items[index]);
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
errors.push(error);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
await Promise.all(Array.from({ length: Math.max(1, Math.min(limit, items.length)) }, run));
|
|
164
|
+
if (errors.length > 0) {
|
|
165
|
+
throw new Error(`${errors.length} of ${items.length} downloads failed. First error: ${errors[0].message}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/** True when the local file already exists with the expected size (resume support) */
|
|
169
|
+
function isFileUpToDate(localPath, expectedSize) {
|
|
170
|
+
try {
|
|
171
|
+
return statSync(localPath).size === expectedSize;
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/** Verify every recorded file exists with the expected size */
|
|
178
|
+
function areFilesUpToDate(tree, skillLocalPath) {
|
|
179
|
+
return tree.files.every((file) => isFileUpToDate(resolve(skillLocalPath, file.path), file.size));
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Download every missing file of a skill, skipping files already cached.
|
|
183
|
+
* Failures throw AFTER the pool finishes so the caller can resume next time.
|
|
184
|
+
*/
|
|
185
|
+
async function downloadMissing(config, relPath, tree, skillLocalPath) {
|
|
186
|
+
if (!tree.files || tree.files.length === 0)
|
|
187
|
+
return;
|
|
188
|
+
const skillRemotePath = buildSkillRemotePath(config, relPath);
|
|
189
|
+
const missing = tree.files.filter((file) => !isFileUpToDate(resolve(skillLocalPath, file.path), file.size));
|
|
190
|
+
if (missing.length === 0)
|
|
191
|
+
return;
|
|
192
|
+
const skillName = basename(skillLocalPath);
|
|
193
|
+
console.error(`[codex-skills-mcp] Fetching ${missing.length}/${tree.files.length} files for skill: ${skillName}...`);
|
|
194
|
+
const startedAt = Date.now();
|
|
195
|
+
const limit = Math.max(1, config.downloadConcurrency);
|
|
196
|
+
await runPool(missing, limit, async (file) => {
|
|
197
|
+
const remotePath = tree.singleFileRemotePath ?? `${skillRemotePath}/${file.path}`;
|
|
198
|
+
const res = await fetchRawWithFallback(config, remotePath);
|
|
199
|
+
const buffer = Buffer.from(await res.arrayBuffer());
|
|
200
|
+
const localFile = resolve(skillLocalPath, file.path);
|
|
201
|
+
mkdirSync(dirname(localFile), { recursive: true });
|
|
202
|
+
writeFileSync(localFile, buffer);
|
|
203
|
+
});
|
|
204
|
+
console.error(`[codex-skills-mcp] Skill ${skillName}: downloaded ${missing.length} files in ${((Date.now() - startedAt) / 1000).toFixed(1)}s`);
|
|
60
205
|
}
|
|
61
206
|
/**
|
|
62
207
|
* Initialize remote caching (just creates the cache dir now)
|
|
@@ -79,63 +224,47 @@ export async function fetchManifest(config) {
|
|
|
79
224
|
writeFileSync(config.manifestPath, text, "utf-8");
|
|
80
225
|
}
|
|
81
226
|
/**
|
|
82
|
-
*
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
for (const item of data) {
|
|
91
|
-
if (item.type === "file" && item.download_url) {
|
|
92
|
-
files.push({ path: item.path, downloadUrl: item.download_url });
|
|
93
|
-
}
|
|
94
|
-
else if (item.type === "dir") {
|
|
95
|
-
const subFiles = await fetchDirectoryRecursive(config, item.path);
|
|
96
|
-
files.push(...subFiles);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
return files;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Ensure a skill's directory is downloaded and cached
|
|
227
|
+
* Ensure a skill's directory is downloaded and cached.
|
|
228
|
+
*
|
|
229
|
+
* - Listing uses only 2 API calls (parent contents + recursive subtree tree),
|
|
230
|
+
* never the full repository tree, so huge repos stay within GitHub limits.
|
|
231
|
+
* - Downloads run concurrently and skip files already cached with the right size.
|
|
232
|
+
* - A `.codex-skills.tree.json` marker records the file list + completion state,
|
|
233
|
+
* so an interrupted download resumes on the next call instead of being
|
|
234
|
+
* silently treated as complete.
|
|
103
235
|
*/
|
|
104
236
|
export async function ensureSkillFetched(config, entry) {
|
|
105
237
|
const relPath = entry.relative_path.replace(/^\.\//, "");
|
|
106
238
|
const skillLocalPath = resolve(config.skillsDir, relPath);
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
if (config.githubPath && relativeFilePath.startsWith(config.githubPath + "/")) {
|
|
126
|
-
relativeFilePath = relativeFilePath.substring(config.githubPath.length + 1);
|
|
239
|
+
const cacheFile = join(skillLocalPath, TREE_CACHE_FILE);
|
|
240
|
+
// Fast path: fully downloaded in a previous run
|
|
241
|
+
if (existsSync(cacheFile)) {
|
|
242
|
+
try {
|
|
243
|
+
const cached = JSON.parse(readFileSync(cacheFile, "utf-8"));
|
|
244
|
+
if (cached.completedAt && Array.isArray(cached.files)) {
|
|
245
|
+
if (areFilesUpToDate(cached, skillLocalPath)) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
// Some files disappeared after completion — fetch only the gaps.
|
|
249
|
+
await downloadMissing(config, relPath, cached, skillLocalPath);
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
if (Array.isArray(cached.files)) {
|
|
253
|
+
// Resume: reuse the cached file list, download only what is missing
|
|
254
|
+
await downloadMissing(config, relPath, cached, skillLocalPath);
|
|
255
|
+
writeFileSync(cacheFile, JSON.stringify({ ...cached, completedAt: new Date().toISOString() }, null, 2), "utf-8");
|
|
256
|
+
return;
|
|
127
257
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
//
|
|
131
|
-
const res = await fetchRawWithFallback(config, file.path);
|
|
132
|
-
const buffer = await res.arrayBuffer();
|
|
133
|
-
writeFileSync(localFilePath, Buffer.from(buffer));
|
|
258
|
+
}
|
|
259
|
+
catch {
|
|
260
|
+
// Corrupted marker — fall through and rebuild the file list
|
|
134
261
|
}
|
|
135
262
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
263
|
+
mkdirSync(skillLocalPath, { recursive: true });
|
|
264
|
+
console.error(`[codex-skills-mcp] Listing files for skill: ${entry.name}...`);
|
|
265
|
+
const tree = await fetchSkillTree(config, relPath);
|
|
266
|
+
writeFileSync(cacheFile, JSON.stringify(tree, null, 2), "utf-8");
|
|
267
|
+
await downloadMissing(config, relPath, tree, skillLocalPath);
|
|
268
|
+
writeFileSync(cacheFile, JSON.stringify({ ...tree, completedAt: new Date().toISOString() }, null, 2), "utf-8");
|
|
140
269
|
}
|
|
141
270
|
//# sourceMappingURL=github.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/remote/github.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/remote/github.ts"],"names":[],"mappings":"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"}
|