agent-resource-management 1.4.0 → 1.5.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.
Files changed (18) hide show
  1. package/dist/main.js +735 -5
  2. package/package.json +1 -1
  3. package/src/cmd/agent.ts +331 -2
  4. package/src/cmd/knowledge.ts +95 -2
  5. package/src/cmd/skill.ts +115 -2
  6. package/src/lib/client.ts +87 -0
  7. package/src/lib/output.ts +35 -0
  8. package/src/lib/storage.ts +1 -0
  9. package/src/main.ts +176 -1
  10. package/test-regression.sh +1 -1
  11. package/dist//344/273/277/347/234/237/350/260/203/350/257/225/345/212/251/346/211/213/AGENT.md +0 -18
  12. package/dist//344/273/277/347/234/237/350/260/203/350/257/225/345/212/251/346/211/213/knowledges//344/273/277/347/234/237/345/271/263/345/217/260Loki/346/227/245/345/277/227/346/216/222/346/237/245/346/226/271/346/263/225.md +0 -27
  13. package/dist//344/273/277/347/234/237/350/260/203/350/257/225/345/212/251/346/211/213/knowledges//344/273/277/347/234/237/345/271/263/345/217/260/344/273/273/345/212/241/350/247/246/345/217/221/345/220/270/346/224/266/345/231/250/344/270/216/345/215/240/344/275/215/350/247/246/345/217/221/345/220/270/346/224/266/345/231/250/344/275/277/347/224/250/345/234/272/346/231/257.md +0 -18
  14. package/dist//344/273/277/347/234/237/350/260/203/350/257/225/345/212/251/346/211/213/knowledges//344/273/277/347/234/237/345/271/263/345/217/260/345/220/216/347/253/257Swagger/346/216/245/345/217/243/346/226/207/346/241/243.md +0 -22
  15. package/dist//344/273/277/347/234/237/350/260/203/350/257/225/345/212/251/346/211/213/knowledges//344/273/277/347/234/237/345/271/263/345/217/260/345/275/223/345/211/215/350/277/220/350/241/214/345/256/236/344/276/213/345/217/212/345/256/236/344/276/213/350/277/220/350/241/214/346/227/245/345/277/227/346/216/222/346/237/245.md +0 -39
  16. package/dist//344/273/277/347/234/237/350/260/203/350/257/225/345/212/251/346/211/213/knowledges//344/273/277/347/234/237/345/271/263/345/217/260/346/216/245/345/217/243/346/216/222/346/237/245/350/203/214/346/231/257/347/237/245/350/257/206.md +0 -49
  17. package/dist//344/273/277/347/234/237/350/260/203/350/257/225/345/212/251/346/211/213/knowledges//344/273/277/347/234/237/350/264/247/350/275/275/347/224/237/345/221/275/345/221/250/346/234/237/346/237/245/350/257/242/346/265/201/347/250/213.md +0 -165
  18. package/dist//344/273/277/347/234/237/350/260/203/350/257/225/345/212/251/346/211/213/knowledges//345/244/251/350/275/246/350/260/203/345/272/246/347/263/273/347/273/237/351/207/215/347/273/204/346/216/245/345/217/243/350/260/203/347/224/250/344/270/216/346/227/245/345/277/227/345/210/206/346/236/220/346/226/271/346/263/225.md +0 -137
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-resource-management",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "arm": "./dist/main.js"
package/src/cmd/agent.ts CHANGED
@@ -1,14 +1,289 @@
1
1
  import { ApiClient } from '../lib/client';
2
2
  import { loadConfig } from '../lib/storage';
3
3
  import { formatAgent, formatAgentDetail, success, error, info } from '../lib/formatter';
4
+ import { shouldOutputJson, outputJson } from '../lib/output';
4
5
  import { writeFileSync, existsSync } from 'fs';
5
6
  import { join } from 'path';
6
7
  import { execSync } from 'child_process';
7
8
  import { mkdtempSync, rmSync } from 'fs';
8
9
 
10
+ function getAgentIdentifier(identifier: string): { id: string; name: string } {
11
+ if (identifier.includes('-')) {
12
+ return { id: identifier, name: identifier };
13
+ }
14
+ return { id: identifier, name: identifier };
15
+ }
16
+
17
+ export async function createAgent(
18
+ name: string,
19
+ options: {
20
+ description?: string;
21
+ prompt?: string;
22
+ avatar?: string;
23
+ skills?: string[];
24
+ knowledges?: string[];
25
+ skillConfigs?: string[];
26
+ knowledgeConfigs?: string[];
27
+ } = {}
28
+ ): Promise<void> {
29
+ const config = loadConfig();
30
+ if (!config?.token) {
31
+ if (shouldOutputJson()) {
32
+ outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
33
+ process.exit(1);
34
+ }
35
+ error('未登录,请先运行 arm login');
36
+ process.exit(1);
37
+ }
38
+
39
+ const client = new ApiClient(config.serverUrl, config.token);
40
+ try {
41
+ const skills = options.skills?.map((skillId, index) => ({
42
+ skillId,
43
+ config: options.skillConfigs?.[index] ? JSON.parse(options.skillConfigs[index]) : undefined,
44
+ }));
45
+
46
+ const knowledges = options.knowledges?.map((knowledgeId, index) => ({
47
+ knowledgeId,
48
+ retrievalConfig: options.knowledgeConfigs?.[index] ? JSON.parse(options.knowledgeConfigs[index]) : undefined,
49
+ }));
50
+
51
+ const result = await client.createAgent({
52
+ name,
53
+ description: options.description,
54
+ prompt: options.prompt,
55
+ avatar: options.avatar,
56
+ skills,
57
+ knowledges,
58
+ });
59
+
60
+ if (shouldOutputJson()) {
61
+ outputJson({ success: true, data: result });
62
+ return;
63
+ }
64
+ success(`Agent "${name}" 创建成功 (ID: ${result.id})`);
65
+ } catch (err) {
66
+ if (shouldOutputJson()) {
67
+ outputJson({ success: false, error: { code: 'CREATE_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
68
+ process.exit(1);
69
+ }
70
+ error(`创建失败: ${err instanceof Error ? err.message : '未知错误'}`);
71
+ process.exit(1);
72
+ }
73
+ }
74
+
75
+ export async function updateAgent(
76
+ id: string,
77
+ options: {
78
+ name?: string;
79
+ description?: string;
80
+ prompt?: string;
81
+ avatar?: string;
82
+ status?: 'active' | 'draft';
83
+ } = {}
84
+ ): Promise<void> {
85
+ const config = loadConfig();
86
+ if (!config?.token) {
87
+ if (shouldOutputJson()) {
88
+ outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
89
+ process.exit(1);
90
+ }
91
+ error('未登录,请先运行 arm login');
92
+ process.exit(1);
93
+ }
94
+
95
+ const client = new ApiClient(config.serverUrl, config.token);
96
+ try {
97
+ const updateData: Partial<{
98
+ name: string;
99
+ description: string;
100
+ prompt: string;
101
+ avatar: string;
102
+ status: 'active' | 'draft';
103
+ }> = {};
104
+
105
+ if (options.name !== undefined) updateData.name = options.name;
106
+ if (options.description !== undefined) updateData.description = options.description;
107
+ if (options.prompt !== undefined) updateData.prompt = options.prompt;
108
+ if (options.avatar !== undefined) updateData.avatar = options.avatar;
109
+ if (options.status !== undefined) updateData.status = options.status;
110
+
111
+ const result = await client.updateAgent(id, updateData);
112
+
113
+ if (shouldOutputJson()) {
114
+ outputJson({ success: true, data: result });
115
+ return;
116
+ }
117
+ success(`Agent "${id}" 更新成功`);
118
+ } catch (err) {
119
+ if (shouldOutputJson()) {
120
+ outputJson({ success: false, error: { code: 'UPDATE_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
121
+ process.exit(1);
122
+ }
123
+ error(`更新失败: ${err instanceof Error ? err.message : '未知错误'}`);
124
+ process.exit(1);
125
+ }
126
+ }
127
+
128
+ export async function deleteAgent(id: string): Promise<void> {
129
+ const config = loadConfig();
130
+ if (!config?.token) {
131
+ if (shouldOutputJson()) {
132
+ outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
133
+ process.exit(1);
134
+ }
135
+ error('未登录,请先运行 arm login');
136
+ process.exit(1);
137
+ }
138
+
139
+ const client = new ApiClient(config.serverUrl, config.token);
140
+ try {
141
+ await client.deleteAgent(id);
142
+
143
+ if (shouldOutputJson()) {
144
+ outputJson({ success: true, data: { id } });
145
+ return;
146
+ }
147
+ success(`Agent "${id}" 删除成功`);
148
+ } catch (err) {
149
+ if (shouldOutputJson()) {
150
+ outputJson({ success: false, error: { code: 'DELETE_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
151
+ process.exit(1);
152
+ }
153
+ error(`删除失败: ${err instanceof Error ? err.message : '未知错误'}`);
154
+ process.exit(1);
155
+ }
156
+ }
157
+
158
+ export async function bindSkill(id: string, skillId: string, config?: string): Promise<void> {
159
+ const configStore = loadConfig();
160
+ if (!configStore?.token) {
161
+ if (shouldOutputJson()) {
162
+ outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
163
+ process.exit(1);
164
+ }
165
+ error('未登录,请先运行 arm login');
166
+ process.exit(1);
167
+ }
168
+
169
+ const client = new ApiClient(configStore.serverUrl, configStore.token);
170
+ try {
171
+ const parsedConfig = config ? JSON.parse(config) : undefined;
172
+ await client.bindSkillToAgent(id, skillId, parsedConfig);
173
+
174
+ if (shouldOutputJson()) {
175
+ outputJson({ success: true, data: { agentId: id, skillId, config: parsedConfig } });
176
+ return;
177
+ }
178
+ success(`Skill "${skillId}" 已绑定到 Agent "${id}"`);
179
+ } catch (err) {
180
+ if (shouldOutputJson()) {
181
+ outputJson({ success: false, error: { code: 'BIND_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
182
+ process.exit(1);
183
+ }
184
+ error(`绑定失败: ${err instanceof Error ? err.message : '未知错误'}`);
185
+ process.exit(1);
186
+ }
187
+ }
188
+
189
+ export async function unbindSkill(id: string, skillId: string): Promise<void> {
190
+ const config = loadConfig();
191
+ if (!config?.token) {
192
+ if (shouldOutputJson()) {
193
+ outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
194
+ process.exit(1);
195
+ }
196
+ error('未登录,请先运行 arm login');
197
+ process.exit(1);
198
+ }
199
+
200
+ const client = new ApiClient(config.serverUrl, config.token);
201
+ try {
202
+ await client.unbindSkillFromAgent(id, skillId);
203
+
204
+ if (shouldOutputJson()) {
205
+ outputJson({ success: true, data: { agentId: id, skillId } });
206
+ return;
207
+ }
208
+ success(`Skill "${skillId}" 已从 Agent "${id}" 解绑`);
209
+ } catch (err) {
210
+ if (shouldOutputJson()) {
211
+ outputJson({ success: false, error: { code: 'UNBIND_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
212
+ process.exit(1);
213
+ }
214
+ error(`解绑失败: ${err instanceof Error ? err.message : '未知错误'}`);
215
+ process.exit(1);
216
+ }
217
+ }
218
+
219
+ export async function bindKnowledge(id: string, knowledgeId: string, retrievalConfig?: string): Promise<void> {
220
+ const configStore = loadConfig();
221
+ if (!configStore?.token) {
222
+ if (shouldOutputJson()) {
223
+ outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
224
+ process.exit(1);
225
+ }
226
+ error('未登录,请先运行 arm login');
227
+ process.exit(1);
228
+ }
229
+
230
+ const client = new ApiClient(configStore.serverUrl, configStore.token);
231
+ try {
232
+ const parsedConfig = retrievalConfig ? JSON.parse(retrievalConfig) : undefined;
233
+ await client.bindKnowledgeToAgent(id, knowledgeId, parsedConfig);
234
+
235
+ if (shouldOutputJson()) {
236
+ outputJson({ success: true, data: { agentId: id, knowledgeId, retrievalConfig: parsedConfig } });
237
+ return;
238
+ }
239
+ success(`Knowledge "${knowledgeId}" 已绑定到 Agent "${id}"`);
240
+ } catch (err) {
241
+ if (shouldOutputJson()) {
242
+ outputJson({ success: false, error: { code: 'BIND_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
243
+ process.exit(1);
244
+ }
245
+ error(`绑定失败: ${err instanceof Error ? err.message : '未知错误'}`);
246
+ process.exit(1);
247
+ }
248
+ }
249
+
250
+ export async function unbindKnowledge(id: string, knowledgeId: string): Promise<void> {
251
+ const config = loadConfig();
252
+ if (!config?.token) {
253
+ if (shouldOutputJson()) {
254
+ outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
255
+ process.exit(1);
256
+ }
257
+ error('未登录,请先运行 arm login');
258
+ process.exit(1);
259
+ }
260
+
261
+ const client = new ApiClient(config.serverUrl, config.token);
262
+ try {
263
+ await client.unbindKnowledgeFromAgent(id, knowledgeId);
264
+
265
+ if (shouldOutputJson()) {
266
+ outputJson({ success: true, data: { agentId: id, knowledgeId } });
267
+ return;
268
+ }
269
+ success(`Knowledge "${knowledgeId}" 已从 Agent "${id}" 解绑`);
270
+ } catch (err) {
271
+ if (shouldOutputJson()) {
272
+ outputJson({ success: false, error: { code: 'UNBIND_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
273
+ process.exit(1);
274
+ }
275
+ error(`解绑失败: ${err instanceof Error ? err.message : '未知错误'}`);
276
+ process.exit(1);
277
+ }
278
+ }
279
+
9
280
  export async function listAgents(): Promise<void> {
10
281
  const config = loadConfig();
11
282
  if (!config?.token) {
283
+ if (shouldOutputJson()) {
284
+ outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
285
+ process.exit(1);
286
+ }
12
287
  error('未登录,请先运行 arm login');
13
288
  process.exit(1);
14
289
  }
@@ -16,6 +291,10 @@ export async function listAgents(): Promise<void> {
16
291
  const client = new ApiClient(config.serverUrl, config.token);
17
292
  try {
18
293
  const result = await client.listAgents();
294
+ if (shouldOutputJson()) {
295
+ outputJson({ success: true, data: result });
296
+ return;
297
+ }
19
298
  if (result.agents.length === 0) {
20
299
  info('暂无 Agent');
21
300
  return;
@@ -26,6 +305,10 @@ export async function listAgents(): Promise<void> {
26
305
  console.log('');
27
306
  }
28
307
  } catch (err) {
308
+ if (shouldOutputJson()) {
309
+ outputJson({ success: false, error: { code: 'LIST_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
310
+ process.exit(1);
311
+ }
29
312
  error(`获取列表失败: ${err instanceof Error ? err.message : '未知错误'}`);
30
313
  process.exit(1);
31
314
  }
@@ -34,6 +317,10 @@ export async function listAgents(): Promise<void> {
34
317
  export async function searchAgents(keyword: string): Promise<void> {
35
318
  const config = loadConfig();
36
319
  if (!config?.token) {
320
+ if (shouldOutputJson()) {
321
+ outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
322
+ process.exit(1);
323
+ }
37
324
  error('未登录,请先运行 arm login');
38
325
  process.exit(1);
39
326
  }
@@ -41,6 +328,10 @@ export async function searchAgents(keyword: string): Promise<void> {
41
328
  const client = new ApiClient(config.serverUrl, config.token);
42
329
  try {
43
330
  const result = await client.listAgents(keyword);
331
+ if (shouldOutputJson()) {
332
+ outputJson({ success: true, data: result });
333
+ return;
334
+ }
44
335
  if (result.agents.length === 0) {
45
336
  info(`没有找到包含 "${keyword}" 的 Agent`);
46
337
  return;
@@ -51,6 +342,10 @@ export async function searchAgents(keyword: string): Promise<void> {
51
342
  console.log('');
52
343
  }
53
344
  } catch (err) {
345
+ if (shouldOutputJson()) {
346
+ outputJson({ success: false, error: { code: 'SEARCH_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
347
+ process.exit(1);
348
+ }
54
349
  error(`搜索失败: ${err instanceof Error ? err.message : '未知错误'}`);
55
350
  process.exit(1);
56
351
  }
@@ -59,6 +354,10 @@ export async function searchAgents(keyword: string): Promise<void> {
59
354
  export async function infoAgent(name: string): Promise<void> {
60
355
  const config = loadConfig();
61
356
  if (!config?.token) {
357
+ if (shouldOutputJson()) {
358
+ outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
359
+ process.exit(1);
360
+ }
62
361
  error('未登录,请先运行 arm login');
63
362
  process.exit(1);
64
363
  }
@@ -68,6 +367,10 @@ export async function infoAgent(name: string): Promise<void> {
68
367
  const result = await client.listAgents(name);
69
368
  const agent = result.agents.find((a) => a.name === name);
70
369
  if (!agent) {
370
+ if (shouldOutputJson()) {
371
+ outputJson({ success: false, error: { code: 'NOT_FOUND', message: `Agent "${name}" 不存在` } });
372
+ process.exit(1);
373
+ }
71
374
  error(`Agent "${name}" 不存在`);
72
375
  process.exit(1);
73
376
  }
@@ -86,8 +389,16 @@ export async function infoAgent(name: string): Promise<void> {
86
389
  fullAgent.knowledges = await Promise.all(knowledgeNamePromises);
87
390
  }
88
391
 
392
+ if (shouldOutputJson()) {
393
+ outputJson({ success: true, data: fullAgent });
394
+ return;
395
+ }
89
396
  console.log(formatAgentDetail(fullAgent));
90
397
  } catch (err) {
398
+ if (shouldOutputJson()) {
399
+ outputJson({ success: false, error: { code: 'INFO_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
400
+ process.exit(1);
401
+ }
91
402
  error(`获取详情失败: ${err instanceof Error ? err.message : '未知错误'}`);
92
403
  process.exit(1);
93
404
  }
@@ -96,6 +407,10 @@ export async function infoAgent(name: string): Promise<void> {
96
407
  export async function downloadAgent(name: string, outputDir?: string): Promise<void> {
97
408
  const config = loadConfig();
98
409
  if (!config?.token) {
410
+ if (shouldOutputJson()) {
411
+ outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
412
+ process.exit(1);
413
+ }
99
414
  error('未登录,请先运行 arm login');
100
415
  process.exit(1);
101
416
  }
@@ -105,11 +420,17 @@ export async function downloadAgent(name: string, outputDir?: string): Promise<v
105
420
  const result = await client.listAgents(name);
106
421
  const agent = result.agents.find((a) => a.name === name);
107
422
  if (!agent) {
423
+ if (shouldOutputJson()) {
424
+ outputJson({ success: false, error: { code: 'NOT_FOUND', message: `Agent "${name}" 不存在` } });
425
+ process.exit(1);
426
+ }
108
427
  error(`Agent "${name}" 不存在`);
109
428
  process.exit(1);
110
429
  }
111
430
 
112
- info(`正在下载 ${name}...`);
431
+ if (shouldOutputJson()) {
432
+ info(`正在下载 ${name}...`);
433
+ }
113
434
  const { buffer, version } = await client.downloadAgent(agent.id);
114
435
 
115
436
  const tempDir = mkdtempSync('/tmp/agent-download-');
@@ -119,7 +440,7 @@ export async function downloadAgent(name: string, outputDir?: string): Promise<v
119
440
  const targetDir = join(outputDir || '.', name);
120
441
  execSync(`mkdir -p "${targetDir}"`, { stdio: 'pipe' });
121
442
  execSync(`unzip -q "${zipPath}" -d "${tempDir}"`, { stdio: 'pipe' });
122
-
443
+
123
444
  const contentDir = join(tempDir, 'agent-content');
124
445
  if (existsSync(contentDir)) {
125
446
  execSync(`cp -r "${contentDir}"/* "${targetDir}/"`, { stdio: 'pipe' });
@@ -129,8 +450,16 @@ export async function downloadAgent(name: string, outputDir?: string): Promise<v
129
450
 
130
451
  rmSync(tempDir, { recursive: true, force: true });
131
452
 
453
+ if (shouldOutputJson()) {
454
+ outputJson({ success: true, data: { path: targetDir, version } });
455
+ return;
456
+ }
132
457
  success(`已下载到 ${targetDir} (版本: ${version})`);
133
458
  } catch (err) {
459
+ if (shouldOutputJson()) {
460
+ outputJson({ success: false, error: { code: 'DOWNLOAD_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
461
+ process.exit(1);
462
+ }
134
463
  error(`下载失败: ${err instanceof Error ? err.message : '未知错误'}`);
135
464
  process.exit(1);
136
465
  }
@@ -1,6 +1,7 @@
1
1
  import { ApiClient } from '../lib/client';
2
2
  import { loadConfig } from '../lib/storage';
3
3
  import { formatKnowledge, formatKnowledgeDetail, success, error, info } from '../lib/formatter';
4
+ import { shouldOutputJson, outputJson } from '../lib/output';
4
5
  import { writeFileSync, existsSync, statSync } from 'fs';
5
6
  import { join, basename, dirname } from 'path';
6
7
  import { execSync } from 'child_process';
@@ -9,6 +10,10 @@ import { mkdtempSync, rmSync } from 'fs';
9
10
  export async function listKnowledge(): Promise<void> {
10
11
  const config = loadConfig();
11
12
  if (!config?.token) {
13
+ if (shouldOutputJson()) {
14
+ outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
15
+ process.exit(1);
16
+ }
12
17
  error('未登录,请先运行 arm login');
13
18
  process.exit(1);
14
19
  }
@@ -16,6 +21,10 @@ export async function listKnowledge(): Promise<void> {
16
21
  const client = new ApiClient(config.serverUrl, config.token);
17
22
  try {
18
23
  const result = await client.listKnowledge();
24
+ if (shouldOutputJson()) {
25
+ outputJson({ success: true, data: result });
26
+ return;
27
+ }
19
28
  if (result.knowledges.length === 0) {
20
29
  info('暂无 Knowledge');
21
30
  return;
@@ -26,6 +35,10 @@ export async function listKnowledge(): Promise<void> {
26
35
  console.log('');
27
36
  }
28
37
  } catch (err) {
38
+ if (shouldOutputJson()) {
39
+ outputJson({ success: false, error: { code: 'LIST_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
40
+ process.exit(1);
41
+ }
29
42
  error(`获取列表失败: ${err instanceof Error ? err.message : '未知错误'}`);
30
43
  process.exit(1);
31
44
  }
@@ -34,6 +47,10 @@ export async function listKnowledge(): Promise<void> {
34
47
  export async function searchKnowledge(keyword: string): Promise<void> {
35
48
  const config = loadConfig();
36
49
  if (!config?.token) {
50
+ if (shouldOutputJson()) {
51
+ outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
52
+ process.exit(1);
53
+ }
37
54
  error('未登录,请先运行 arm login');
38
55
  process.exit(1);
39
56
  }
@@ -41,6 +58,10 @@ export async function searchKnowledge(keyword: string): Promise<void> {
41
58
  const client = new ApiClient(config.serverUrl, config.token);
42
59
  try {
43
60
  const result = await client.listKnowledge(keyword);
61
+ if (shouldOutputJson()) {
62
+ outputJson({ success: true, data: result });
63
+ return;
64
+ }
44
65
  if (result.knowledges.length === 0) {
45
66
  info(`没有找到包含 "${keyword}" 的 Knowledge`);
46
67
  return;
@@ -51,6 +72,10 @@ export async function searchKnowledge(keyword: string): Promise<void> {
51
72
  console.log('');
52
73
  }
53
74
  } catch (err) {
75
+ if (shouldOutputJson()) {
76
+ outputJson({ success: false, error: { code: 'SEARCH_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
77
+ process.exit(1);
78
+ }
54
79
  error(`搜索失败: ${err instanceof Error ? err.message : '未知错误'}`);
55
80
  process.exit(1);
56
81
  }
@@ -59,6 +84,10 @@ export async function searchKnowledge(keyword: string): Promise<void> {
59
84
  export async function infoKnowledge(name: string): Promise<void> {
60
85
  const config = loadConfig();
61
86
  if (!config?.token) {
87
+ if (shouldOutputJson()) {
88
+ outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
89
+ process.exit(1);
90
+ }
62
91
  error('未登录,请先运行 arm login');
63
92
  process.exit(1);
64
93
  }
@@ -66,8 +95,16 @@ export async function infoKnowledge(name: string): Promise<void> {
66
95
  const client = new ApiClient(config.serverUrl, config.token);
67
96
  try {
68
97
  const knowledge = await client.getKnowledge(name);
98
+ if (shouldOutputJson()) {
99
+ outputJson({ success: true, data: knowledge });
100
+ return;
101
+ }
69
102
  console.log(formatKnowledgeDetail(knowledge));
70
103
  } catch (err) {
104
+ if (shouldOutputJson()) {
105
+ outputJson({ success: false, error: { code: 'INFO_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
106
+ process.exit(1);
107
+ }
71
108
  error(`获取详情失败: ${err instanceof Error ? err.message : '未知错误'}`);
72
109
  process.exit(1);
73
110
  }
@@ -76,18 +113,32 @@ export async function infoKnowledge(name: string): Promise<void> {
76
113
  export async function downloadKnowledge(name: string, outputDir?: string): Promise<void> {
77
114
  const config = loadConfig();
78
115
  if (!config?.token) {
116
+ if (shouldOutputJson()) {
117
+ outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
118
+ process.exit(1);
119
+ }
79
120
  error('未登录,请先运行 arm login');
80
121
  process.exit(1);
81
122
  }
82
123
 
83
124
  const client = new ApiClient(config.serverUrl, config.token);
84
125
  try {
85
- info(`正在下载 ${name}...`);
126
+ if (shouldOutputJson()) {
127
+ info(`正在下载 ${name}...`);
128
+ }
86
129
  const buffer = await client.downloadKnowledge(name);
87
130
  const outputPath = join(outputDir || '.', `${name}.zip`);
88
131
  writeFileSync(outputPath, Buffer.from(buffer));
132
+ if (shouldOutputJson()) {
133
+ outputJson({ success: true, data: { path: outputPath } });
134
+ return;
135
+ }
89
136
  success(`已下载到 ${outputPath}`);
90
137
  } catch (err) {
138
+ if (shouldOutputJson()) {
139
+ outputJson({ success: false, error: { code: 'DOWNLOAD_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
140
+ process.exit(1);
141
+ }
91
142
  error(`下载失败: ${err instanceof Error ? err.message : '未知错误'}`);
92
143
  process.exit(1);
93
144
  }
@@ -96,11 +147,19 @@ export async function downloadKnowledge(name: string, outputDir?: string): Promi
96
147
  export async function uploadKnowledge(filePath: string): Promise<void> {
97
148
  const config = loadConfig();
98
149
  if (!config?.token) {
150
+ if (shouldOutputJson()) {
151
+ outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
152
+ process.exit(1);
153
+ }
99
154
  error('未登录,请先运行 arm login');
100
155
  process.exit(1);
101
156
  }
102
157
 
103
158
  if (!existsSync(filePath)) {
159
+ if (shouldOutputJson()) {
160
+ outputJson({ success: false, error: { code: 'FILE_NOT_FOUND', message: `上传失败: 目录不存在: ${filePath}` } });
161
+ process.exit(1);
162
+ }
104
163
  error(`上传失败: 目录不存在: ${filePath}`);
105
164
  process.exit(1);
106
165
  }
@@ -117,10 +176,20 @@ export async function uploadKnowledge(filePath: string): Promise<void> {
117
176
  }
118
177
 
119
178
  const client = new ApiClient(config.serverUrl, config.token);
120
- info(`正在上传 ${filePath}...`);
179
+ if (shouldOutputJson()) {
180
+ info(`正在上传 ${filePath}...`);
181
+ }
121
182
  const knowledge = await client.uploadKnowledge(zipPath);
183
+ if (shouldOutputJson()) {
184
+ outputJson({ success: true, data: knowledge });
185
+ return;
186
+ }
122
187
  success(`上传成功! Knowledge: ${knowledge.name}`);
123
188
  } catch (err) {
189
+ if (shouldOutputJson()) {
190
+ outputJson({ success: false, error: { code: 'UPLOAD_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
191
+ process.exit(1);
192
+ }
124
193
  error(`上传失败: ${err instanceof Error ? err.message : '未知错误'}`);
125
194
  process.exit(1);
126
195
  } finally {
@@ -131,6 +200,10 @@ export async function uploadKnowledge(filePath: string): Promise<void> {
131
200
  export async function myKnowledge(): Promise<void> {
132
201
  const config = loadConfig();
133
202
  if (!config?.token) {
203
+ if (shouldOutputJson()) {
204
+ outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
205
+ process.exit(1);
206
+ }
134
207
  error('未登录,请先运行 arm login');
135
208
  process.exit(1);
136
209
  }
@@ -138,6 +211,10 @@ export async function myKnowledge(): Promise<void> {
138
211
  const client = new ApiClient(config.serverUrl, config.token);
139
212
  try {
140
213
  const knowledges = await client.getMyKnowledge();
214
+ if (shouldOutputJson()) {
215
+ outputJson({ success: true, data: knowledges });
216
+ return;
217
+ }
141
218
  if (knowledges.length === 0) {
142
219
  info('您还没有发布任何 Knowledge');
143
220
  return;
@@ -148,6 +225,10 @@ export async function myKnowledge(): Promise<void> {
148
225
  console.log('');
149
226
  }
150
227
  } catch (err) {
228
+ if (shouldOutputJson()) {
229
+ outputJson({ success: false, error: { code: 'LIST_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
230
+ process.exit(1);
231
+ }
151
232
  error(`获取列表失败: ${err instanceof Error ? err.message : '未知错误'}`);
152
233
  process.exit(1);
153
234
  }
@@ -156,6 +237,10 @@ export async function myKnowledge(): Promise<void> {
156
237
  export async function deleteKnowledge(name: string): Promise<void> {
157
238
  const config = loadConfig();
158
239
  if (!config?.token) {
240
+ if (shouldOutputJson()) {
241
+ outputJson({ success: false, error: { code: 'NOT_LOGGED_IN', message: '未登录,请先运行 arm login' } });
242
+ process.exit(1);
243
+ }
159
244
  error('未登录,请先运行 arm login');
160
245
  process.exit(1);
161
246
  }
@@ -163,8 +248,16 @@ export async function deleteKnowledge(name: string): Promise<void> {
163
248
  const client = new ApiClient(config.serverUrl, config.token);
164
249
  try {
165
250
  await client.deleteKnowledge(name);
251
+ if (shouldOutputJson()) {
252
+ outputJson({ success: true, data: { name } });
253
+ return;
254
+ }
166
255
  success(`已删除 ${name}`);
167
256
  } catch (err) {
257
+ if (shouldOutputJson()) {
258
+ outputJson({ success: false, error: { code: 'DELETE_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
259
+ process.exit(1);
260
+ }
168
261
  error(`删除失败: ${err instanceof Error ? err.message : '未知错误'}`);
169
262
  process.exit(1);
170
263
  }