@series-inc/rundot-game-sdk 5.1.3 → 5.2.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.
@@ -1,377 +1,377 @@
1
- #!/usr/bin/env node
2
-
3
- import { existsSync, rmSync, readFileSync, writeFileSync, createWriteStream, renameSync, readdirSync, statSync } from 'fs';
4
- import { resolve as resolvePath, dirname, join } from 'path';
5
- import { fileURLToPath } from 'url';
6
- import https from 'https';
7
- import AdmZip from 'adm-zip';
8
-
9
- const DOCS_ZIP_URL = 'https://github.com/series-ai/venus-sdk-docs/archive/refs/heads/main.zip';
10
- const DOCS_FOLDER = '.rundot-docs';
11
- const VERSION_FILE = '.sdk-version';
12
- const TEMP_ZIP_FILE = '.docs-temp.zip';
13
-
14
- /**
15
- * Get the current package version
16
- */
17
- function getCurrentVersion() {
18
- try {
19
- const __filename = fileURLToPath(import.meta.url);
20
- const __dirname = dirname(__filename);
21
- const packageJsonPath = resolvePath(__dirname, '..', 'package.json');
22
- const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
23
- return packageJson.version;
24
- } catch (error) {
25
- console.warn(' Could not read package version:', error.message);
26
- return null;
27
- }
28
- }
29
-
30
- /**
31
- * Get the previously installed version
32
- */
33
- function getInstalledVersion(projectRoot) {
34
- try {
35
- const targetPath = resolvePath(projectRoot, DOCS_FOLDER);
36
- const versionFilePath = resolvePath(targetPath, VERSION_FILE);
37
-
38
- if (!existsSync(versionFilePath)) {
39
- return null;
40
- }
41
-
42
- return readFileSync(versionFilePath, 'utf-8').trim();
43
- } catch (error) {
44
- return null;
45
- }
46
- }
47
-
48
- /**
49
- * Save the current version to the version file
50
- */
51
- function saveInstalledVersion(version, projectRoot) {
52
- try {
53
- const targetPath = resolvePath(projectRoot, DOCS_FOLDER);
54
- const versionFilePath = resolvePath(targetPath, VERSION_FILE);
55
- writeFileSync(versionFilePath, version, 'utf-8');
56
- } catch (error) {
57
- console.warn(' Could not save version file:', error.message);
58
- }
59
- }
60
-
61
- /**
62
- * Check if docs need to be downloaded
63
- */
64
- function shouldDownloadDocs(currentVersion, installedVersion, projectRoot) {
65
- // First install - no version file exists
66
- if (!installedVersion) {
67
- return true;
68
- }
69
-
70
- // Version has changed
71
- if (currentVersion && installedVersion !== currentVersion) {
72
- return true;
73
- }
74
-
75
- // Docs folder doesn't exist (somehow deleted)
76
- const targetPath = resolvePath(projectRoot, DOCS_FOLDER);
77
- if (!existsSync(targetPath)) {
78
- return true;
79
- }
80
-
81
- return false;
82
- }
83
-
84
- /**
85
- * Download a file from a URL
86
- */
87
- async function downloadFile(url, dest) {
88
- return new Promise((resolve, reject) => {
89
- const file = createWriteStream(dest);
90
-
91
- https.get(url, (response) => {
92
- // Follow redirects
93
- if (response.statusCode === 302 || response.statusCode === 301) {
94
- file.close();
95
- rmSync(dest, { force: true });
96
- return downloadFile(response.headers.location, dest).then(resolve).catch(reject);
97
- }
98
-
99
- if (response.statusCode !== 200) {
100
- file.close();
101
- rmSync(dest, { force: true });
102
- return reject(new Error(`Failed to download: HTTP ${response.statusCode}`));
103
- }
104
-
105
- response.pipe(file);
106
-
107
- file.on('finish', () => {
108
- file.close();
109
- resolve();
110
- });
111
-
112
- file.on('error', (err) => {
113
- file.close();
114
- rmSync(dest, { force: true });
115
- reject(err);
116
- });
117
- }).on('error', (err) => {
118
- file.close();
119
- rmSync(dest, { force: true });
120
- reject(err);
121
- });
122
- });
123
- }
124
-
125
- /**
126
- * Extract zip file and handle GitHub's nested folder structure
127
- */
128
- function extractZip(zipPath, targetPath) {
129
- const zip = new AdmZip(zipPath);
130
- const tempExtractPath = resolvePath(process.cwd(), '.docs-temp-extract');
131
-
132
- // Clean up temp folder if it exists from a previous failed run
133
- if (existsSync(tempExtractPath)) {
134
- rmSync(tempExtractPath, { recursive: true, force: true });
135
- }
136
-
137
- // Extract to temporary location
138
- zip.extractAllTo(tempExtractPath, true);
139
-
140
- // GitHub creates a folder like "venus-sdk-docs-main" inside the zip
141
- // We need to find it and move its contents to the target path
142
- const extractedContents = readdirSync(tempExtractPath);
143
-
144
- if (extractedContents.length === 1) {
145
- // Move the nested folder contents to target
146
- const nestedFolder = resolvePath(tempExtractPath, extractedContents[0]);
147
- renameSync(nestedFolder, targetPath);
148
- } else {
149
- // Unexpected structure, just move everything
150
- renameSync(tempExtractPath, targetPath);
151
- }
152
-
153
- // Clean up temp folder if it still exists
154
- if (existsSync(tempExtractPath)) {
155
- rmSync(tempExtractPath, { recursive: true, force: true });
156
- }
157
- }
158
-
159
- /**
160
- * Find all AGENTS.md and CLAUDE.md files (case insensitive) in a directory
161
- */
162
- function findAgentFiles(dir, results = []) {
163
- if (!existsSync(dir)) {
164
- return results;
165
- }
166
-
167
- const entries = readdirSync(dir, { withFileTypes: true });
168
-
169
- for (const entry of entries) {
170
- const fullPath = join(dir, entry.name);
171
-
172
- // Skip .git directories
173
- if (entry.name === '.git') {
174
- continue;
175
- }
176
-
177
- if (entry.isDirectory()) {
178
- findAgentFiles(fullPath, results);
179
- } else if (entry.isFile()) {
180
- const nameLower = entry.name.toLowerCase();
181
- if (nameLower === 'agents.md' || nameLower === 'claude.md') {
182
- results.push(fullPath);
183
- }
184
- }
185
- }
186
-
187
- return results;
188
- }
189
-
190
- /**
191
- * Inject agents-index.txt content into a file between <agents-index> tags
192
- */
193
- function injectAgentsIndex(filePath, agentsIndexContent) {
194
- const content = readFileSync(filePath, 'utf-8');
195
- const openTag = '<agents-index>';
196
- const closeTag = '</agents-index>';
197
-
198
- const openIndex = content.indexOf(openTag);
199
- const closeIndex = content.indexOf(closeTag);
200
-
201
- let newContent;
202
-
203
- if (openIndex !== -1 && closeIndex !== -1 && closeIndex > openIndex) {
204
- // Tags exist, replace content between them
205
- const before = content.substring(0, openIndex + openTag.length);
206
- const after = content.substring(closeIndex);
207
- newContent = `${before}\n${agentsIndexContent}${after}`;
208
- } else {
209
- // Tags don't exist, prepend them with the content
210
- newContent = `${openTag}\n${agentsIndexContent}${closeTag}\n\n${content}`;
211
- }
212
-
213
- writeFileSync(filePath, newContent, 'utf-8');
214
- }
215
-
216
- /**
217
- * Process all AGENTS.md and CLAUDE.md files in the project directory
218
- */
219
- function processAgentFiles(docsPath, projectRoot) {
220
- const agentsIndexPath = join(docsPath, 'agents-index.txt');
221
-
222
- // Check if agents-index.txt exists
223
- if (!existsSync(agentsIndexPath)) {
224
- console.log(' No agents-index.txt found, skipping agent files injection');
225
- return;
226
- }
227
-
228
- // Read the agents-index.txt content
229
- const agentsIndexContent = readFileSync(agentsIndexPath, 'utf-8').trim();
230
-
231
- // Find all AGENTS.md and CLAUDE.md files in the project root
232
- const agentFiles = findAgentFiles(projectRoot);
233
-
234
- if (agentFiles.length === 0) {
235
- console.log(' No AGENTS.md or CLAUDE.md files found in project, creating them...');
236
-
237
- const files = ['AGENTS.md', 'CLAUDE.md', 'GEMINI.md'];
238
-
239
- try {
240
- for (const file of files) {
241
- writeFileSync(join(projectRoot, file), '', 'utf-8');
242
- console.log(` Created ${file}`);
243
- agentFiles.push(join(projectRoot, file));
244
- }
245
- } catch (error) {
246
- console.warn(' Failed to create agent files:', error.message);
247
- return;
248
- }
249
- }
250
-
251
- console.log(` Found ${agentFiles.length} agent file(s), injecting agents-index...`);
252
-
253
- for (const filePath of agentFiles) {
254
- try {
255
- injectAgentsIndex(filePath, agentsIndexContent);
256
- const relativePath = filePath.replace(projectRoot + '/', '');
257
- console.log(` Injected into ${relativePath}`);
258
- } catch (error) {
259
- console.warn(` Failed to inject into ${filePath}:`, error.message);
260
- }
261
- }
262
- }
263
-
264
- /**
265
- * Add .rundot-docs to .gitignore if it exists and isn't already there
266
- */
267
- function updateGitignore(projectRoot) {
268
- const gitignorePath = join(projectRoot, '.gitignore');
269
-
270
- if (!existsSync(gitignorePath)) {
271
- return;
272
- }
273
-
274
- try {
275
- const content = readFileSync(gitignorePath, 'utf-8');
276
-
277
- // Check if .rundot-docs is already in .gitignore
278
- if (content.includes('.rundot-docs')) {
279
- return;
280
- }
281
-
282
- // Add .rundot-docs to .gitignore
283
- const newContent = content.endsWith('\n')
284
- ? `${content}.rundot-docs\n`
285
- : `${content}\n.rundot-docs\n`;
286
-
287
- writeFileSync(gitignorePath, newContent, 'utf-8');
288
- console.log(' Added .rundot-docs to .gitignore');
289
- } catch (error) {
290
- console.warn(' Failed to update .gitignore:', error.message);
291
- }
292
- }
293
-
294
- /**
295
- * Find the project root directory (where package.json with this package as a dependency exists)
296
- */
297
- function findProjectRoot() {
298
- let currentDir = process.cwd();
299
-
300
- // If we're already in node_modules, go up to find the project root
301
- if (currentDir.includes('node_modules')) {
302
- const parts = currentDir.split('node_modules');
303
- return parts[0];
304
- }
305
-
306
- return currentDir;
307
- }
308
-
309
- /**
310
- * Post-install script to download venus-sdk-docs repository
311
- * into a .docs folder in the current working directory
312
- */
313
- async function postInstall() {
314
- const projectRoot = findProjectRoot();
315
- const zipPath = resolvePath(projectRoot, TEMP_ZIP_FILE);
316
-
317
- try {
318
- const currentVersion = getCurrentVersion();
319
- const installedVersion = getInstalledVersion(projectRoot);
320
-
321
- if (!shouldDownloadDocs(currentVersion, installedVersion, projectRoot)) {
322
- console.log('venus-sdk-docs is already up to date (version:', installedVersion || 'unknown', ')');
323
- return;
324
- }
325
-
326
- // Use project root to store the docs
327
- const targetPath = resolvePath(projectRoot, DOCS_FOLDER);
328
-
329
- console.log('Downloading venus-sdk-docs...');
330
-
331
- // Check if the .docs folder already exists
332
- if (existsSync(targetPath)) {
333
- console.log(' Removing old version...');
334
- rmSync(targetPath, { recursive: true, force: true });
335
- }
336
-
337
- // Download the zip file
338
- await downloadFile(DOCS_ZIP_URL, zipPath);
339
- console.log(' Download complete, extracting...');
340
-
341
- // Extract the zip file
342
- extractZip(zipPath, targetPath);
343
-
344
- // Clean up zip file
345
- if (existsSync(zipPath)) {
346
- rmSync(zipPath, { force: true });
347
- }
348
-
349
- // Save the current version
350
- if (currentVersion) {
351
- saveInstalledVersion(currentVersion, projectRoot);
352
- }
353
-
354
- // Process AGENTS.md and CLAUDE.md files in the project root
355
- processAgentFiles(targetPath, projectRoot);
356
-
357
- // Add .rundot-docs to .gitignore if it exists
358
- updateGitignore(projectRoot);
359
-
360
- console.log('venus-sdk-docs downloaded successfully!');
361
- console.log(` Documentation available at: ${targetPath}`);
362
- } catch (error) {
363
- console.warn('Warning: Failed to download venus-sdk-docs');
364
- console.warn(' Error:', error.message);
365
- console.warn(' You can manually download the docs from:', DOCS_ZIP_URL);
366
-
367
- // Clean up any partial downloads
368
- if (existsSync(zipPath)) {
369
- rmSync(zipPath, { force: true });
370
- }
371
-
372
- // Don't fail the installation if docs download fails
373
- process.exit(0);
374
- }
375
- }
376
-
377
- postInstall();
1
+ #!/usr/bin/env node
2
+
3
+ import { existsSync, rmSync, readFileSync, writeFileSync, createWriteStream, renameSync, readdirSync, statSync } from 'fs';
4
+ import { resolve as resolvePath, dirname, join } from 'path';
5
+ import { fileURLToPath } from 'url';
6
+ import https from 'https';
7
+ import AdmZip from 'adm-zip';
8
+
9
+ const DOCS_ZIP_URL = 'https://github.com/series-ai/venus-sdk-docs/archive/refs/heads/main.zip';
10
+ const DOCS_FOLDER = '.rundot-docs';
11
+ const VERSION_FILE = '.sdk-version';
12
+ const TEMP_ZIP_FILE = '.docs-temp.zip';
13
+
14
+ /**
15
+ * Get the current package version
16
+ */
17
+ function getCurrentVersion() {
18
+ try {
19
+ const __filename = fileURLToPath(import.meta.url);
20
+ const __dirname = dirname(__filename);
21
+ const packageJsonPath = resolvePath(__dirname, '..', 'package.json');
22
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
23
+ return packageJson.version;
24
+ } catch (error) {
25
+ console.warn(' Could not read package version:', error.message);
26
+ return null;
27
+ }
28
+ }
29
+
30
+ /**
31
+ * Get the previously installed version
32
+ */
33
+ function getInstalledVersion(projectRoot) {
34
+ try {
35
+ const targetPath = resolvePath(projectRoot, DOCS_FOLDER);
36
+ const versionFilePath = resolvePath(targetPath, VERSION_FILE);
37
+
38
+ if (!existsSync(versionFilePath)) {
39
+ return null;
40
+ }
41
+
42
+ return readFileSync(versionFilePath, 'utf-8').trim();
43
+ } catch (error) {
44
+ return null;
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Save the current version to the version file
50
+ */
51
+ function saveInstalledVersion(version, projectRoot) {
52
+ try {
53
+ const targetPath = resolvePath(projectRoot, DOCS_FOLDER);
54
+ const versionFilePath = resolvePath(targetPath, VERSION_FILE);
55
+ writeFileSync(versionFilePath, version, 'utf-8');
56
+ } catch (error) {
57
+ console.warn(' Could not save version file:', error.message);
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Check if docs need to be downloaded
63
+ */
64
+ function shouldDownloadDocs(currentVersion, installedVersion, projectRoot) {
65
+ // First install - no version file exists
66
+ if (!installedVersion) {
67
+ return true;
68
+ }
69
+
70
+ // Version has changed
71
+ if (currentVersion && installedVersion !== currentVersion) {
72
+ return true;
73
+ }
74
+
75
+ // Docs folder doesn't exist (somehow deleted)
76
+ const targetPath = resolvePath(projectRoot, DOCS_FOLDER);
77
+ if (!existsSync(targetPath)) {
78
+ return true;
79
+ }
80
+
81
+ return false;
82
+ }
83
+
84
+ /**
85
+ * Download a file from a URL
86
+ */
87
+ async function downloadFile(url, dest) {
88
+ return new Promise((resolve, reject) => {
89
+ const file = createWriteStream(dest);
90
+
91
+ https.get(url, (response) => {
92
+ // Follow redirects
93
+ if (response.statusCode === 302 || response.statusCode === 301) {
94
+ file.close();
95
+ rmSync(dest, { force: true });
96
+ return downloadFile(response.headers.location, dest).then(resolve).catch(reject);
97
+ }
98
+
99
+ if (response.statusCode !== 200) {
100
+ file.close();
101
+ rmSync(dest, { force: true });
102
+ return reject(new Error(`Failed to download: HTTP ${response.statusCode}`));
103
+ }
104
+
105
+ response.pipe(file);
106
+
107
+ file.on('finish', () => {
108
+ file.close();
109
+ resolve();
110
+ });
111
+
112
+ file.on('error', (err) => {
113
+ file.close();
114
+ rmSync(dest, { force: true });
115
+ reject(err);
116
+ });
117
+ }).on('error', (err) => {
118
+ file.close();
119
+ rmSync(dest, { force: true });
120
+ reject(err);
121
+ });
122
+ });
123
+ }
124
+
125
+ /**
126
+ * Extract zip file and handle GitHub's nested folder structure
127
+ */
128
+ function extractZip(zipPath, targetPath) {
129
+ const zip = new AdmZip(zipPath);
130
+ const tempExtractPath = resolvePath(process.cwd(), '.docs-temp-extract');
131
+
132
+ // Clean up temp folder if it exists from a previous failed run
133
+ if (existsSync(tempExtractPath)) {
134
+ rmSync(tempExtractPath, { recursive: true, force: true });
135
+ }
136
+
137
+ // Extract to temporary location
138
+ zip.extractAllTo(tempExtractPath, true);
139
+
140
+ // GitHub creates a folder like "venus-sdk-docs-main" inside the zip
141
+ // We need to find it and move its contents to the target path
142
+ const extractedContents = readdirSync(tempExtractPath);
143
+
144
+ if (extractedContents.length === 1) {
145
+ // Move the nested folder contents to target
146
+ const nestedFolder = resolvePath(tempExtractPath, extractedContents[0]);
147
+ renameSync(nestedFolder, targetPath);
148
+ } else {
149
+ // Unexpected structure, just move everything
150
+ renameSync(tempExtractPath, targetPath);
151
+ }
152
+
153
+ // Clean up temp folder if it still exists
154
+ if (existsSync(tempExtractPath)) {
155
+ rmSync(tempExtractPath, { recursive: true, force: true });
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Find all AGENTS.md and CLAUDE.md files (case insensitive) in a directory
161
+ */
162
+ function findAgentFiles(dir, results = []) {
163
+ if (!existsSync(dir)) {
164
+ return results;
165
+ }
166
+
167
+ const entries = readdirSync(dir, { withFileTypes: true });
168
+
169
+ for (const entry of entries) {
170
+ const fullPath = join(dir, entry.name);
171
+
172
+ // Skip .git directories
173
+ if (entry.name === '.git') {
174
+ continue;
175
+ }
176
+
177
+ if (entry.isDirectory()) {
178
+ findAgentFiles(fullPath, results);
179
+ } else if (entry.isFile()) {
180
+ const nameLower = entry.name.toLowerCase();
181
+ if (nameLower === 'agents.md' || nameLower === 'claude.md') {
182
+ results.push(fullPath);
183
+ }
184
+ }
185
+ }
186
+
187
+ return results;
188
+ }
189
+
190
+ /**
191
+ * Inject agents-index.txt content into a file between <agents-index> tags
192
+ */
193
+ function injectAgentsIndex(filePath, agentsIndexContent) {
194
+ const content = readFileSync(filePath, 'utf-8');
195
+ const openTag = '<agents-index>';
196
+ const closeTag = '</agents-index>';
197
+
198
+ const openIndex = content.indexOf(openTag);
199
+ const closeIndex = content.indexOf(closeTag);
200
+
201
+ let newContent;
202
+
203
+ if (openIndex !== -1 && closeIndex !== -1 && closeIndex > openIndex) {
204
+ // Tags exist, replace content between them
205
+ const before = content.substring(0, openIndex + openTag.length);
206
+ const after = content.substring(closeIndex);
207
+ newContent = `${before}\n${agentsIndexContent}${after}`;
208
+ } else {
209
+ // Tags don't exist, prepend them with the content
210
+ newContent = `${openTag}\n${agentsIndexContent}${closeTag}\n\n${content}`;
211
+ }
212
+
213
+ writeFileSync(filePath, newContent, 'utf-8');
214
+ }
215
+
216
+ /**
217
+ * Process all AGENTS.md and CLAUDE.md files in the project directory
218
+ */
219
+ function processAgentFiles(docsPath, projectRoot) {
220
+ const agentsIndexPath = join(docsPath, 'agents-index.txt');
221
+
222
+ // Check if agents-index.txt exists
223
+ if (!existsSync(agentsIndexPath)) {
224
+ console.log(' No agents-index.txt found, skipping agent files injection');
225
+ return;
226
+ }
227
+
228
+ // Read the agents-index.txt content
229
+ const agentsIndexContent = readFileSync(agentsIndexPath, 'utf-8').trim();
230
+
231
+ // Find all AGENTS.md and CLAUDE.md files in the project root
232
+ const agentFiles = findAgentFiles(projectRoot);
233
+
234
+ if (agentFiles.length === 0) {
235
+ console.log(' No AGENTS.md or CLAUDE.md files found in project, creating them...');
236
+
237
+ const files = ['AGENTS.md', 'CLAUDE.md', 'GEMINI.md'];
238
+
239
+ try {
240
+ for (const file of files) {
241
+ writeFileSync(join(projectRoot, file), '', 'utf-8');
242
+ console.log(` Created ${file}`);
243
+ agentFiles.push(join(projectRoot, file));
244
+ }
245
+ } catch (error) {
246
+ console.warn(' Failed to create agent files:', error.message);
247
+ return;
248
+ }
249
+ }
250
+
251
+ console.log(` Found ${agentFiles.length} agent file(s), injecting agents-index...`);
252
+
253
+ for (const filePath of agentFiles) {
254
+ try {
255
+ injectAgentsIndex(filePath, agentsIndexContent);
256
+ const relativePath = filePath.replace(projectRoot + '/', '');
257
+ console.log(` Injected into ${relativePath}`);
258
+ } catch (error) {
259
+ console.warn(` Failed to inject into ${filePath}:`, error.message);
260
+ }
261
+ }
262
+ }
263
+
264
+ /**
265
+ * Add .rundot-docs to .gitignore if it exists and isn't already there
266
+ */
267
+ function updateGitignore(projectRoot) {
268
+ const gitignorePath = join(projectRoot, '.gitignore');
269
+
270
+ if (!existsSync(gitignorePath)) {
271
+ return;
272
+ }
273
+
274
+ try {
275
+ const content = readFileSync(gitignorePath, 'utf-8');
276
+
277
+ // Check if .rundot-docs is already in .gitignore
278
+ if (content.includes('.rundot-docs')) {
279
+ return;
280
+ }
281
+
282
+ // Add .rundot-docs to .gitignore
283
+ const newContent = content.endsWith('\n')
284
+ ? `${content}.rundot-docs\n`
285
+ : `${content}\n.rundot-docs\n`;
286
+
287
+ writeFileSync(gitignorePath, newContent, 'utf-8');
288
+ console.log(' Added .rundot-docs to .gitignore');
289
+ } catch (error) {
290
+ console.warn(' Failed to update .gitignore:', error.message);
291
+ }
292
+ }
293
+
294
+ /**
295
+ * Find the project root directory (where package.json with this package as a dependency exists)
296
+ */
297
+ function findProjectRoot() {
298
+ let currentDir = process.cwd();
299
+
300
+ // If we're already in node_modules, go up to find the project root
301
+ if (currentDir.includes('node_modules')) {
302
+ const parts = currentDir.split('node_modules');
303
+ return parts[0];
304
+ }
305
+
306
+ return currentDir;
307
+ }
308
+
309
+ /**
310
+ * Post-install script to download venus-sdk-docs repository
311
+ * into a .docs folder in the current working directory
312
+ */
313
+ async function postInstall() {
314
+ const projectRoot = findProjectRoot();
315
+ const zipPath = resolvePath(projectRoot, TEMP_ZIP_FILE);
316
+
317
+ try {
318
+ const currentVersion = getCurrentVersion();
319
+ const installedVersion = getInstalledVersion(projectRoot);
320
+
321
+ if (!shouldDownloadDocs(currentVersion, installedVersion, projectRoot)) {
322
+ console.log('venus-sdk-docs is already up to date (version:', installedVersion || 'unknown', ')');
323
+ return;
324
+ }
325
+
326
+ // Use project root to store the docs
327
+ const targetPath = resolvePath(projectRoot, DOCS_FOLDER);
328
+
329
+ console.log('Downloading venus-sdk-docs...');
330
+
331
+ // Check if the .docs folder already exists
332
+ if (existsSync(targetPath)) {
333
+ console.log(' Removing old version...');
334
+ rmSync(targetPath, { recursive: true, force: true });
335
+ }
336
+
337
+ // Download the zip file
338
+ await downloadFile(DOCS_ZIP_URL, zipPath);
339
+ console.log(' Download complete, extracting...');
340
+
341
+ // Extract the zip file
342
+ extractZip(zipPath, targetPath);
343
+
344
+ // Clean up zip file
345
+ if (existsSync(zipPath)) {
346
+ rmSync(zipPath, { force: true });
347
+ }
348
+
349
+ // Save the current version
350
+ if (currentVersion) {
351
+ saveInstalledVersion(currentVersion, projectRoot);
352
+ }
353
+
354
+ // Process AGENTS.md and CLAUDE.md files in the project root
355
+ processAgentFiles(targetPath, projectRoot);
356
+
357
+ // Add .rundot-docs to .gitignore if it exists
358
+ updateGitignore(projectRoot);
359
+
360
+ console.log('venus-sdk-docs downloaded successfully!');
361
+ console.log(` Documentation available at: ${targetPath}`);
362
+ } catch (error) {
363
+ console.warn('Warning: Failed to download venus-sdk-docs');
364
+ console.warn(' Error:', error.message);
365
+ console.warn(' You can manually download the docs from:', DOCS_ZIP_URL);
366
+
367
+ // Clean up any partial downloads
368
+ if (existsSync(zipPath)) {
369
+ rmSync(zipPath, { force: true });
370
+ }
371
+
372
+ // Don't fail the installation if docs download fails
373
+ process.exit(0);
374
+ }
375
+ }
376
+
377
+ postInstall();