rushangle-cli 0.2.0 → 0.2.2
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 +1 -1
- package/src/commands/install.js +66 -3
package/package.json
CHANGED
package/src/commands/install.js
CHANGED
|
@@ -11,7 +11,7 @@ const INSTALL_DIR = path.join(os.homedir(), '.workbuddy', 'skills');
|
|
|
11
11
|
module.exports = new Command('install')
|
|
12
12
|
.description('安装技能/MCP/代码段')
|
|
13
13
|
.argument('[skill]', '技能名称或 ID')
|
|
14
|
-
.option('-t, --type <type>', '类型: skill | mcp | code', 'skill')
|
|
14
|
+
.option('-t, --type <type>', '类型: skill | mcp | code | doc', 'skill')
|
|
15
15
|
.option('-g, --global', '全局安装(默认)', true)
|
|
16
16
|
.option('--register-only', '仅注册到服务器,不写入本地文件(适用于受限环境)')
|
|
17
17
|
.action(async (nameOrId, opts) => {
|
|
@@ -129,7 +129,10 @@ module.exports = new Command('install')
|
|
|
129
129
|
const match = listData.items.find(
|
|
130
130
|
s => s.name === nameOrId || s.id === nameOrId
|
|
131
131
|
);
|
|
132
|
-
if (match)
|
|
132
|
+
if (match) {
|
|
133
|
+
// Re-fetch full data (list data is sanitized)
|
|
134
|
+
item = await api.getMcp(match.id);
|
|
135
|
+
}
|
|
133
136
|
}
|
|
134
137
|
}
|
|
135
138
|
|
|
@@ -183,7 +186,10 @@ module.exports = new Command('install')
|
|
|
183
186
|
const match = listData.items.find(
|
|
184
187
|
s => s.name === nameOrId || s.id === nameOrId
|
|
185
188
|
);
|
|
186
|
-
if (match)
|
|
189
|
+
if (match) {
|
|
190
|
+
// Re-fetch full data (list data is sanitized)
|
|
191
|
+
item = await api.getCode(match.id);
|
|
192
|
+
}
|
|
187
193
|
}
|
|
188
194
|
}
|
|
189
195
|
|
|
@@ -221,6 +227,63 @@ module.exports = new Command('install')
|
|
|
221
227
|
console.log(chalk.gray(` 语言: ${item.language}`));
|
|
222
228
|
if (showLocalPath) console.log(chalk.gray(` 本地目录: ${installDir}`));
|
|
223
229
|
|
|
230
|
+
} else if (type === 'doc') {
|
|
231
|
+
// Docs: Try by ID first, then search by name
|
|
232
|
+
try {
|
|
233
|
+
item = await api.getDoc(nameOrId);
|
|
234
|
+
} catch {
|
|
235
|
+
const listData = await api.listDocs({ search: nameOrId });
|
|
236
|
+
if (listData.items && listData.items.length > 0) {
|
|
237
|
+
const match = listData.items.find(
|
|
238
|
+
s => s.name === nameOrId || s.id === nameOrId
|
|
239
|
+
);
|
|
240
|
+
if (match) {
|
|
241
|
+
// Re-fetch full data (list data is sanitized)
|
|
242
|
+
item = await api.getDoc(match.id);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (!item) {
|
|
248
|
+
console.log(chalk.red(`未找到文档: ${nameOrId}`));
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Local file install (best-effort)
|
|
253
|
+
let showLocalPath = false;
|
|
254
|
+
let installDir = '';
|
|
255
|
+
if (!opts.registerOnly) {
|
|
256
|
+
try {
|
|
257
|
+
installDir = path.join(INSTALL_DIR, 'docs', item.id);
|
|
258
|
+
fs.mkdirSync(installDir, { recursive: true });
|
|
259
|
+
// Write document content as markdown
|
|
260
|
+
if (item.content) {
|
|
261
|
+
fs.writeFileSync(path.join(installDir, 'document.md'), item.content);
|
|
262
|
+
}
|
|
263
|
+
// Write attached file list if any
|
|
264
|
+
if (item.files && item.files.length > 0) {
|
|
265
|
+
fs.writeFileSync(
|
|
266
|
+
path.join(installDir, 'files.json'),
|
|
267
|
+
JSON.stringify(item.files, null, 2)
|
|
268
|
+
);
|
|
269
|
+
console.log(chalk.gray(` 附带文件: ${item.files.map(f => f.name || f).join(', ')}`));
|
|
270
|
+
}
|
|
271
|
+
fs.writeFileSync(
|
|
272
|
+
path.join(installDir, 'rushangle.json'),
|
|
273
|
+
JSON.stringify({ type: 'doc', ...item, installedAt: new Date().toISOString() }, null, 2)
|
|
274
|
+
);
|
|
275
|
+
showLocalPath = true;
|
|
276
|
+
} catch (fileErr) {
|
|
277
|
+
console.log(chalk.yellow(` 本地文件写入跳过(${fileErr.code || fileErr.message})`));
|
|
278
|
+
if (fileErr.code === 'EPERM' || fileErr.code === 'EACCES') {
|
|
279
|
+
console.log(chalk.gray(` 提示: 使用 --register-only 跳过本地文件操作`));
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
console.log(chalk.green(`✓ 安装成功: ${item.name}`));
|
|
285
|
+
if (showLocalPath) console.log(chalk.gray(` 本地目录: ${installDir}`));
|
|
286
|
+
|
|
224
287
|
} else {
|
|
225
288
|
console.log(chalk.red(`不支持的类型: ${type}`));
|
|
226
289
|
}
|