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/dist/main.js CHANGED
@@ -230,6 +230,72 @@ class ApiClient {
230
230
  }
231
231
  return res.arrayBuffer();
232
232
  }
233
+ async createAgent(data) {
234
+ const res = await this.request("/agents", {
235
+ method: "POST",
236
+ body: JSON.stringify(data)
237
+ });
238
+ if (!res.ok) {
239
+ throw new Error(res.msg);
240
+ }
241
+ return res.data;
242
+ }
243
+ async updateAgent(id, data) {
244
+ const res = await this.request(`/agents/${id}`, {
245
+ method: "PUT",
246
+ body: JSON.stringify(data)
247
+ });
248
+ if (!res.ok) {
249
+ throw new Error(res.msg);
250
+ }
251
+ return res.data;
252
+ }
253
+ async deleteAgent(id) {
254
+ const res = await this.request(`/agents/${id}`, {
255
+ method: "DELETE"
256
+ });
257
+ if (!res.ok) {
258
+ throw new Error(res.msg);
259
+ }
260
+ }
261
+ async bindSkillToAgent(agentId, skillId, config) {
262
+ const res = await this.request(`/agents/${agentId}/skills`, {
263
+ method: "POST",
264
+ body: JSON.stringify({ skillId, config })
265
+ });
266
+ if (!res.ok) {
267
+ throw new Error(res.msg);
268
+ }
269
+ }
270
+ async unbindSkillFromAgent(agentId, skillId) {
271
+ const res = await this.request(`/agents/${agentId}/skills?skillId=${skillId}`, {
272
+ method: "DELETE"
273
+ });
274
+ if (!res.ok) {
275
+ throw new Error(res.msg);
276
+ }
277
+ }
278
+ async bindKnowledgeToAgent(agentId, knowledgeId, retrievalConfig) {
279
+ const res = await this.request(`/agents/${agentId}/knowledges`, {
280
+ method: "POST",
281
+ body: JSON.stringify({ knowledgeId, retrievalConfig })
282
+ });
283
+ if (!res.ok) {
284
+ throw new Error(res.msg);
285
+ }
286
+ }
287
+ async unbindKnowledgeFromAgent(agentId, knowledgeId) {
288
+ const res = await this.request(`/agents/${agentId}/knowledges?knowledgeId=${knowledgeId}`, {
289
+ method: "DELETE"
290
+ });
291
+ if (!res.ok) {
292
+ throw new Error(res.msg);
293
+ }
294
+ }
295
+ async getAgentByName(name) {
296
+ const result = await this.listAgents(name, 1, 1);
297
+ return result.agents.find((a) => a.name === name) || null;
298
+ }
233
299
  }
234
300
 
235
301
  // src/lib/storage.ts
@@ -438,6 +504,27 @@ async function getCurrentUser() {
438
504
  }
439
505
  }
440
506
 
507
+ // src/lib/output.ts
508
+ function outputJson(result) {
509
+ console.log(JSON.stringify(result, null, 2));
510
+ }
511
+ function shouldOutputJson() {
512
+ if (process.argv.includes("--json") || process.argv.includes("-j")) {
513
+ return true;
514
+ }
515
+ const config = loadConfig();
516
+ return config.outputMode !== "text";
517
+ }
518
+ function getOutputMode() {
519
+ const config = loadConfig();
520
+ return config.outputMode || "json";
521
+ }
522
+ function setOutputMode(mode) {
523
+ const config = loadConfig() || {};
524
+ config.outputMode = mode;
525
+ saveConfig(config);
526
+ }
527
+
441
528
  // src/lib/validate.ts
442
529
  import { readFileSync as readFileSync2, existsSync as existsSync2, statSync } from "fs";
443
530
  import { execSync } from "child_process";
@@ -618,12 +705,20 @@ import { mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "fs";
618
705
  async function listSkills() {
619
706
  const config = loadConfig();
620
707
  if (!config?.token) {
708
+ if (shouldOutputJson()) {
709
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
710
+ process.exit(1);
711
+ }
621
712
  error("未登录,请先运行 arm login");
622
713
  process.exit(1);
623
714
  }
624
715
  const client = new ApiClient(config.serverUrl, config.token);
625
716
  try {
626
717
  const result = await client.listSkills();
718
+ if (shouldOutputJson()) {
719
+ outputJson({ success: true, data: result });
720
+ return;
721
+ }
627
722
  if (result.skills.length === 0) {
628
723
  info("暂无 Skill");
629
724
  return;
@@ -636,6 +731,10 @@ async function listSkills() {
636
731
  console.log("");
637
732
  }
638
733
  } catch (err) {
734
+ if (shouldOutputJson()) {
735
+ outputJson({ success: false, error: { code: "LIST_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
736
+ process.exit(1);
737
+ }
639
738
  error(`获取列表失败: ${err instanceof Error ? err.message : "未知错误"}`);
640
739
  process.exit(1);
641
740
  }
@@ -643,12 +742,20 @@ async function listSkills() {
643
742
  async function searchSkills(keyword) {
644
743
  const config = loadConfig();
645
744
  if (!config?.token) {
745
+ if (shouldOutputJson()) {
746
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
747
+ process.exit(1);
748
+ }
646
749
  error("未登录,请先运行 arm login");
647
750
  process.exit(1);
648
751
  }
649
752
  const client = new ApiClient(config.serverUrl, config.token);
650
753
  try {
651
754
  const result = await client.listSkills(keyword);
755
+ if (shouldOutputJson()) {
756
+ outputJson({ success: true, data: result });
757
+ return;
758
+ }
652
759
  if (result.skills.length === 0) {
653
760
  info(`没有找到包含 "${keyword}" 的 Skill`);
654
761
  return;
@@ -661,6 +768,10 @@ async function searchSkills(keyword) {
661
768
  console.log("");
662
769
  }
663
770
  } catch (err) {
771
+ if (shouldOutputJson()) {
772
+ outputJson({ success: false, error: { code: "SEARCH_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
773
+ process.exit(1);
774
+ }
664
775
  error(`搜索失败: ${err instanceof Error ? err.message : "未知错误"}`);
665
776
  process.exit(1);
666
777
  }
@@ -668,14 +779,26 @@ async function searchSkills(keyword) {
668
779
  async function infoSkill(name) {
669
780
  const config = loadConfig();
670
781
  if (!config?.token) {
782
+ if (shouldOutputJson()) {
783
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
784
+ process.exit(1);
785
+ }
671
786
  error("未登录,请先运行 arm login");
672
787
  process.exit(1);
673
788
  }
674
789
  const client = new ApiClient(config.serverUrl, config.token);
675
790
  try {
676
791
  const skill = await client.getSkill(name);
792
+ if (shouldOutputJson()) {
793
+ outputJson({ success: true, data: skill });
794
+ return;
795
+ }
677
796
  console.log(formatSkillDetail(skill));
678
797
  } catch (err) {
798
+ if (shouldOutputJson()) {
799
+ outputJson({ success: false, error: { code: "INFO_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
800
+ process.exit(1);
801
+ }
679
802
  error(`获取详情失败: ${err instanceof Error ? err.message : "未知错误"}`);
680
803
  process.exit(1);
681
804
  }
@@ -683,17 +806,31 @@ async function infoSkill(name) {
683
806
  async function downloadSkill(name, outputDir) {
684
807
  const config = loadConfig();
685
808
  if (!config?.token) {
809
+ if (shouldOutputJson()) {
810
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
811
+ process.exit(1);
812
+ }
686
813
  error("未登录,请先运行 arm login");
687
814
  process.exit(1);
688
815
  }
689
816
  const client = new ApiClient(config.serverUrl, config.token);
690
817
  try {
691
- info(`正在下载 ${name}...`);
818
+ if (shouldOutputJson()) {
819
+ info(`正在下载 ${name}...`);
820
+ }
692
821
  const buffer = await client.downloadSkill(name);
693
822
  const outputPath = join3(outputDir || ".", `${name}.zip`);
694
823
  writeFileSync2(outputPath, Buffer.from(buffer));
824
+ if (shouldOutputJson()) {
825
+ outputJson({ success: true, data: { path: outputPath } });
826
+ return;
827
+ }
695
828
  success(`已下载到 ${outputPath}`);
696
829
  } catch (err) {
830
+ if (shouldOutputJson()) {
831
+ outputJson({ success: false, error: { code: "DOWNLOAD_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
832
+ process.exit(1);
833
+ }
697
834
  error(`下载失败: ${err instanceof Error ? err.message : "未知错误"}`);
698
835
  process.exit(1);
699
836
  }
@@ -701,16 +838,28 @@ async function downloadSkill(name, outputDir) {
701
838
  async function uploadSkill(filePath) {
702
839
  const config = loadConfig();
703
840
  if (!config?.token) {
841
+ if (shouldOutputJson()) {
842
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
843
+ process.exit(1);
844
+ }
704
845
  error("未登录,请先运行 arm login");
705
846
  process.exit(1);
706
847
  }
707
848
  if (!existsSync3(filePath)) {
849
+ if (shouldOutputJson()) {
850
+ outputJson({ success: false, error: { code: "FILE_NOT_FOUND", message: `上传失败: 目录不存在: ${filePath}` } });
851
+ process.exit(1);
852
+ }
708
853
  error(`上传失败: 目录不存在: ${filePath}`);
709
854
  process.exit(1);
710
855
  }
711
856
  const isZip = filePath.toLowerCase().endsWith(".zip");
712
857
  const validation = isZip ? validateZip(filePath) : validateSkillDir(filePath);
713
858
  if (!validation.valid) {
859
+ if (shouldOutputJson()) {
860
+ outputJson({ success: false, error: { code: "VALIDATION_FAILED", message: validation.errors.join(", ") } });
861
+ process.exit(1);
862
+ }
714
863
  error(`上传失败: ${validation.errors.join(", ")}`);
715
864
  process.exit(1);
716
865
  }
@@ -724,11 +873,21 @@ async function uploadSkill(filePath) {
724
873
  execSync2(`cd "${dirname(filePath)}" && zip -r "${zipPath}" "${basename(filePath)}" -x ".*"`, { stdio: "pipe" });
725
874
  }
726
875
  const client = new ApiClient(config.serverUrl, config.token);
727
- info(`正在上传 ${filePath}...`);
876
+ if (shouldOutputJson()) {
877
+ info(`正在上传 ${filePath}...`);
878
+ }
728
879
  const skill = await client.uploadSkill(zipPath);
880
+ if (shouldOutputJson()) {
881
+ outputJson({ success: true, data: skill });
882
+ return;
883
+ }
729
884
  success(`上传成功! Skill: ${skill.name}`);
730
885
  } catch (err) {
731
886
  console.error("DEBUG upload error:", err);
887
+ if (shouldOutputJson()) {
888
+ outputJson({ success: false, error: { code: "UPLOAD_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
889
+ process.exit(1);
890
+ }
732
891
  error(`上传失败: ${err instanceof Error ? err.message : "未知错误"}`);
733
892
  process.exit(1);
734
893
  } finally {
@@ -738,12 +897,20 @@ async function uploadSkill(filePath) {
738
897
  async function mySkills() {
739
898
  const config = loadConfig();
740
899
  if (!config?.token) {
900
+ if (shouldOutputJson()) {
901
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
902
+ process.exit(1);
903
+ }
741
904
  error("未登录,请先运行 arm login");
742
905
  process.exit(1);
743
906
  }
744
907
  const client = new ApiClient(config.serverUrl, config.token);
745
908
  try {
746
909
  const skills = await client.getMySkills();
910
+ if (shouldOutputJson()) {
911
+ outputJson({ success: true, data: skills });
912
+ return;
913
+ }
747
914
  if (skills.length === 0) {
748
915
  info("您还没有发布任何 Skill");
749
916
  return;
@@ -756,6 +923,10 @@ async function mySkills() {
756
923
  console.log("");
757
924
  }
758
925
  } catch (err) {
926
+ if (shouldOutputJson()) {
927
+ outputJson({ success: false, error: { code: "LIST_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
928
+ process.exit(1);
929
+ }
759
930
  error(`获取列表失败: ${err instanceof Error ? err.message : "未知错误"}`);
760
931
  process.exit(1);
761
932
  }
@@ -763,14 +934,26 @@ async function mySkills() {
763
934
  async function deleteSkill(name) {
764
935
  const config = loadConfig();
765
936
  if (!config?.token) {
937
+ if (shouldOutputJson()) {
938
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
939
+ process.exit(1);
940
+ }
766
941
  error("未登录,请先运行 arm login");
767
942
  process.exit(1);
768
943
  }
769
944
  const client = new ApiClient(config.serverUrl, config.token);
770
945
  try {
771
946
  await client.deleteSkill(name);
947
+ if (shouldOutputJson()) {
948
+ outputJson({ success: true, data: { name } });
949
+ return;
950
+ }
772
951
  success(`已删除 ${name}`);
773
952
  } catch (err) {
953
+ if (shouldOutputJson()) {
954
+ outputJson({ success: false, error: { code: "DELETE_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
955
+ process.exit(1);
956
+ }
774
957
  error(`删除失败: ${err instanceof Error ? err.message : "未知错误"}`);
775
958
  process.exit(1);
776
959
  }
@@ -778,6 +961,21 @@ async function deleteSkill(name) {
778
961
  async function validateSkill(filePath) {
779
962
  const isDir = existsSync3(filePath) && statSync2(filePath).isDirectory();
780
963
  const result = isDir ? validateSkillDir(filePath) : validateZip(filePath);
964
+ if (shouldOutputJson()) {
965
+ outputJson({
966
+ success: result.valid,
967
+ data: {
968
+ valid: result.valid,
969
+ errors: result.errors,
970
+ warnings: result.warnings,
971
+ metadata: result.metadata
972
+ }
973
+ });
974
+ if (!result.valid) {
975
+ process.exit(1);
976
+ }
977
+ return;
978
+ }
781
979
  if (result.valid) {
782
980
  success("验证通过!");
783
981
  } else {
@@ -821,15 +1019,240 @@ import { writeFileSync as writeFileSync3, existsSync as existsSync4 } from "fs";
821
1019
  import { join as join4 } from "path";
822
1020
  import { execSync as execSync3 } from "child_process";
823
1021
  import { mkdtempSync as mkdtempSync3, rmSync as rmSync3 } from "fs";
1022
+ async function createAgent(name, options = {}) {
1023
+ const config = loadConfig();
1024
+ if (!config?.token) {
1025
+ if (shouldOutputJson()) {
1026
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
1027
+ process.exit(1);
1028
+ }
1029
+ error("未登录,请先运行 arm login");
1030
+ process.exit(1);
1031
+ }
1032
+ const client = new ApiClient(config.serverUrl, config.token);
1033
+ try {
1034
+ const skills = options.skills?.map((skillId, index) => ({
1035
+ skillId,
1036
+ config: options.skillConfigs?.[index] ? JSON.parse(options.skillConfigs[index]) : undefined
1037
+ }));
1038
+ const knowledges = options.knowledges?.map((knowledgeId, index) => ({
1039
+ knowledgeId,
1040
+ retrievalConfig: options.knowledgeConfigs?.[index] ? JSON.parse(options.knowledgeConfigs[index]) : undefined
1041
+ }));
1042
+ const result = await client.createAgent({
1043
+ name,
1044
+ description: options.description,
1045
+ prompt: options.prompt,
1046
+ avatar: options.avatar,
1047
+ skills,
1048
+ knowledges
1049
+ });
1050
+ if (shouldOutputJson()) {
1051
+ outputJson({ success: true, data: result });
1052
+ return;
1053
+ }
1054
+ success(`Agent "${name}" 创建成功 (ID: ${result.id})`);
1055
+ } catch (err) {
1056
+ if (shouldOutputJson()) {
1057
+ outputJson({ success: false, error: { code: "CREATE_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
1058
+ process.exit(1);
1059
+ }
1060
+ error(`创建失败: ${err instanceof Error ? err.message : "未知错误"}`);
1061
+ process.exit(1);
1062
+ }
1063
+ }
1064
+ async function updateAgent(id, options = {}) {
1065
+ const config = loadConfig();
1066
+ if (!config?.token) {
1067
+ if (shouldOutputJson()) {
1068
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
1069
+ process.exit(1);
1070
+ }
1071
+ error("未登录,请先运行 arm login");
1072
+ process.exit(1);
1073
+ }
1074
+ const client = new ApiClient(config.serverUrl, config.token);
1075
+ try {
1076
+ const updateData = {};
1077
+ if (options.name !== undefined)
1078
+ updateData.name = options.name;
1079
+ if (options.description !== undefined)
1080
+ updateData.description = options.description;
1081
+ if (options.prompt !== undefined)
1082
+ updateData.prompt = options.prompt;
1083
+ if (options.avatar !== undefined)
1084
+ updateData.avatar = options.avatar;
1085
+ if (options.status !== undefined)
1086
+ updateData.status = options.status;
1087
+ const result = await client.updateAgent(id, updateData);
1088
+ if (shouldOutputJson()) {
1089
+ outputJson({ success: true, data: result });
1090
+ return;
1091
+ }
1092
+ success(`Agent "${id}" 更新成功`);
1093
+ } catch (err) {
1094
+ if (shouldOutputJson()) {
1095
+ outputJson({ success: false, error: { code: "UPDATE_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
1096
+ process.exit(1);
1097
+ }
1098
+ error(`更新失败: ${err instanceof Error ? err.message : "未知错误"}`);
1099
+ process.exit(1);
1100
+ }
1101
+ }
1102
+ async function deleteAgent(id) {
1103
+ const config = loadConfig();
1104
+ if (!config?.token) {
1105
+ if (shouldOutputJson()) {
1106
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
1107
+ process.exit(1);
1108
+ }
1109
+ error("未登录,请先运行 arm login");
1110
+ process.exit(1);
1111
+ }
1112
+ const client = new ApiClient(config.serverUrl, config.token);
1113
+ try {
1114
+ await client.deleteAgent(id);
1115
+ if (shouldOutputJson()) {
1116
+ outputJson({ success: true, data: { id } });
1117
+ return;
1118
+ }
1119
+ success(`Agent "${id}" 删除成功`);
1120
+ } catch (err) {
1121
+ if (shouldOutputJson()) {
1122
+ outputJson({ success: false, error: { code: "DELETE_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
1123
+ process.exit(1);
1124
+ }
1125
+ error(`删除失败: ${err instanceof Error ? err.message : "未知错误"}`);
1126
+ process.exit(1);
1127
+ }
1128
+ }
1129
+ async function bindSkill(id, skillId, config) {
1130
+ const configStore = loadConfig();
1131
+ if (!configStore?.token) {
1132
+ if (shouldOutputJson()) {
1133
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
1134
+ process.exit(1);
1135
+ }
1136
+ error("未登录,请先运行 arm login");
1137
+ process.exit(1);
1138
+ }
1139
+ const client = new ApiClient(configStore.serverUrl, configStore.token);
1140
+ try {
1141
+ const parsedConfig = config ? JSON.parse(config) : undefined;
1142
+ await client.bindSkillToAgent(id, skillId, parsedConfig);
1143
+ if (shouldOutputJson()) {
1144
+ outputJson({ success: true, data: { agentId: id, skillId, config: parsedConfig } });
1145
+ return;
1146
+ }
1147
+ success(`Skill "${skillId}" 已绑定到 Agent "${id}"`);
1148
+ } catch (err) {
1149
+ if (shouldOutputJson()) {
1150
+ outputJson({ success: false, error: { code: "BIND_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
1151
+ process.exit(1);
1152
+ }
1153
+ error(`绑定失败: ${err instanceof Error ? err.message : "未知错误"}`);
1154
+ process.exit(1);
1155
+ }
1156
+ }
1157
+ async function unbindSkill(id, skillId) {
1158
+ const config = loadConfig();
1159
+ if (!config?.token) {
1160
+ if (shouldOutputJson()) {
1161
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
1162
+ process.exit(1);
1163
+ }
1164
+ error("未登录,请先运行 arm login");
1165
+ process.exit(1);
1166
+ }
1167
+ const client = new ApiClient(config.serverUrl, config.token);
1168
+ try {
1169
+ await client.unbindSkillFromAgent(id, skillId);
1170
+ if (shouldOutputJson()) {
1171
+ outputJson({ success: true, data: { agentId: id, skillId } });
1172
+ return;
1173
+ }
1174
+ success(`Skill "${skillId}" 已从 Agent "${id}" 解绑`);
1175
+ } catch (err) {
1176
+ if (shouldOutputJson()) {
1177
+ outputJson({ success: false, error: { code: "UNBIND_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
1178
+ process.exit(1);
1179
+ }
1180
+ error(`解绑失败: ${err instanceof Error ? err.message : "未知错误"}`);
1181
+ process.exit(1);
1182
+ }
1183
+ }
1184
+ async function bindKnowledge(id, knowledgeId, retrievalConfig) {
1185
+ const configStore = loadConfig();
1186
+ if (!configStore?.token) {
1187
+ if (shouldOutputJson()) {
1188
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
1189
+ process.exit(1);
1190
+ }
1191
+ error("未登录,请先运行 arm login");
1192
+ process.exit(1);
1193
+ }
1194
+ const client = new ApiClient(configStore.serverUrl, configStore.token);
1195
+ try {
1196
+ const parsedConfig = retrievalConfig ? JSON.parse(retrievalConfig) : undefined;
1197
+ await client.bindKnowledgeToAgent(id, knowledgeId, parsedConfig);
1198
+ if (shouldOutputJson()) {
1199
+ outputJson({ success: true, data: { agentId: id, knowledgeId, retrievalConfig: parsedConfig } });
1200
+ return;
1201
+ }
1202
+ success(`Knowledge "${knowledgeId}" 已绑定到 Agent "${id}"`);
1203
+ } catch (err) {
1204
+ if (shouldOutputJson()) {
1205
+ outputJson({ success: false, error: { code: "BIND_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
1206
+ process.exit(1);
1207
+ }
1208
+ error(`绑定失败: ${err instanceof Error ? err.message : "未知错误"}`);
1209
+ process.exit(1);
1210
+ }
1211
+ }
1212
+ async function unbindKnowledge(id, knowledgeId) {
1213
+ const config = loadConfig();
1214
+ if (!config?.token) {
1215
+ if (shouldOutputJson()) {
1216
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
1217
+ process.exit(1);
1218
+ }
1219
+ error("未登录,请先运行 arm login");
1220
+ process.exit(1);
1221
+ }
1222
+ const client = new ApiClient(config.serverUrl, config.token);
1223
+ try {
1224
+ await client.unbindKnowledgeFromAgent(id, knowledgeId);
1225
+ if (shouldOutputJson()) {
1226
+ outputJson({ success: true, data: { agentId: id, knowledgeId } });
1227
+ return;
1228
+ }
1229
+ success(`Knowledge "${knowledgeId}" 已从 Agent "${id}" 解绑`);
1230
+ } catch (err) {
1231
+ if (shouldOutputJson()) {
1232
+ outputJson({ success: false, error: { code: "UNBIND_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
1233
+ process.exit(1);
1234
+ }
1235
+ error(`解绑失败: ${err instanceof Error ? err.message : "未知错误"}`);
1236
+ process.exit(1);
1237
+ }
1238
+ }
824
1239
  async function listAgents() {
825
1240
  const config = loadConfig();
826
1241
  if (!config?.token) {
1242
+ if (shouldOutputJson()) {
1243
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
1244
+ process.exit(1);
1245
+ }
827
1246
  error("未登录,请先运行 arm login");
828
1247
  process.exit(1);
829
1248
  }
830
1249
  const client = new ApiClient(config.serverUrl, config.token);
831
1250
  try {
832
1251
  const result = await client.listAgents();
1252
+ if (shouldOutputJson()) {
1253
+ outputJson({ success: true, data: result });
1254
+ return;
1255
+ }
833
1256
  if (result.agents.length === 0) {
834
1257
  info("暂无 Agent");
835
1258
  return;
@@ -842,6 +1265,10 @@ async function listAgents() {
842
1265
  console.log("");
843
1266
  }
844
1267
  } catch (err) {
1268
+ if (shouldOutputJson()) {
1269
+ outputJson({ success: false, error: { code: "LIST_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
1270
+ process.exit(1);
1271
+ }
845
1272
  error(`获取列表失败: ${err instanceof Error ? err.message : "未知错误"}`);
846
1273
  process.exit(1);
847
1274
  }
@@ -849,12 +1276,20 @@ async function listAgents() {
849
1276
  async function searchAgents(keyword) {
850
1277
  const config = loadConfig();
851
1278
  if (!config?.token) {
1279
+ if (shouldOutputJson()) {
1280
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
1281
+ process.exit(1);
1282
+ }
852
1283
  error("未登录,请先运行 arm login");
853
1284
  process.exit(1);
854
1285
  }
855
1286
  const client = new ApiClient(config.serverUrl, config.token);
856
1287
  try {
857
1288
  const result = await client.listAgents(keyword);
1289
+ if (shouldOutputJson()) {
1290
+ outputJson({ success: true, data: result });
1291
+ return;
1292
+ }
858
1293
  if (result.agents.length === 0) {
859
1294
  info(`没有找到包含 "${keyword}" 的 Agent`);
860
1295
  return;
@@ -867,6 +1302,10 @@ async function searchAgents(keyword) {
867
1302
  console.log("");
868
1303
  }
869
1304
  } catch (err) {
1305
+ if (shouldOutputJson()) {
1306
+ outputJson({ success: false, error: { code: "SEARCH_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
1307
+ process.exit(1);
1308
+ }
870
1309
  error(`搜索失败: ${err instanceof Error ? err.message : "未知错误"}`);
871
1310
  process.exit(1);
872
1311
  }
@@ -874,6 +1313,10 @@ async function searchAgents(keyword) {
874
1313
  async function infoAgent(name) {
875
1314
  const config = loadConfig();
876
1315
  if (!config?.token) {
1316
+ if (shouldOutputJson()) {
1317
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
1318
+ process.exit(1);
1319
+ }
877
1320
  error("未登录,请先运行 arm login");
878
1321
  process.exit(1);
879
1322
  }
@@ -882,6 +1325,10 @@ async function infoAgent(name) {
882
1325
  const result = await client.listAgents(name);
883
1326
  const agent = result.agents.find((a) => a.name === name);
884
1327
  if (!agent) {
1328
+ if (shouldOutputJson()) {
1329
+ outputJson({ success: false, error: { code: "NOT_FOUND", message: `Agent "${name}" 不存在` } });
1330
+ process.exit(1);
1331
+ }
885
1332
  error(`Agent "${name}" 不存在`);
886
1333
  process.exit(1);
887
1334
  }
@@ -897,8 +1344,16 @@ async function infoAgent(name) {
897
1344
  });
898
1345
  fullAgent.knowledges = await Promise.all(knowledgeNamePromises);
899
1346
  }
1347
+ if (shouldOutputJson()) {
1348
+ outputJson({ success: true, data: fullAgent });
1349
+ return;
1350
+ }
900
1351
  console.log(formatAgentDetail(fullAgent));
901
1352
  } catch (err) {
1353
+ if (shouldOutputJson()) {
1354
+ outputJson({ success: false, error: { code: "INFO_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
1355
+ process.exit(1);
1356
+ }
902
1357
  error(`获取详情失败: ${err instanceof Error ? err.message : "未知错误"}`);
903
1358
  process.exit(1);
904
1359
  }
@@ -906,6 +1361,10 @@ async function infoAgent(name) {
906
1361
  async function downloadAgent(name, outputDir) {
907
1362
  const config = loadConfig();
908
1363
  if (!config?.token) {
1364
+ if (shouldOutputJson()) {
1365
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
1366
+ process.exit(1);
1367
+ }
909
1368
  error("未登录,请先运行 arm login");
910
1369
  process.exit(1);
911
1370
  }
@@ -914,10 +1373,16 @@ async function downloadAgent(name, outputDir) {
914
1373
  const result = await client.listAgents(name);
915
1374
  const agent = result.agents.find((a) => a.name === name);
916
1375
  if (!agent) {
1376
+ if (shouldOutputJson()) {
1377
+ outputJson({ success: false, error: { code: "NOT_FOUND", message: `Agent "${name}" 不存在` } });
1378
+ process.exit(1);
1379
+ }
917
1380
  error(`Agent "${name}" 不存在`);
918
1381
  process.exit(1);
919
1382
  }
920
- info(`正在下载 ${name}...`);
1383
+ if (shouldOutputJson()) {
1384
+ info(`正在下载 ${name}...`);
1385
+ }
921
1386
  const { buffer, version } = await client.downloadAgent(agent.id);
922
1387
  const tempDir = mkdtempSync3("/tmp/agent-download-");
923
1388
  const zipPath = join4(tempDir, `${name}.zip`);
@@ -932,8 +1397,16 @@ async function downloadAgent(name, outputDir) {
932
1397
  execSync3(`cp -r "${tempDir}"/* "${targetDir}/"`, { stdio: "pipe" });
933
1398
  }
934
1399
  rmSync3(tempDir, { recursive: true, force: true });
1400
+ if (shouldOutputJson()) {
1401
+ outputJson({ success: true, data: { path: targetDir, version } });
1402
+ return;
1403
+ }
935
1404
  success(`已下载到 ${targetDir} (版本: ${version})`);
936
1405
  } catch (err) {
1406
+ if (shouldOutputJson()) {
1407
+ outputJson({ success: false, error: { code: "DOWNLOAD_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
1408
+ process.exit(1);
1409
+ }
937
1410
  error(`下载失败: ${err instanceof Error ? err.message : "未知错误"}`);
938
1411
  process.exit(1);
939
1412
  }
@@ -947,12 +1420,20 @@ import { mkdtempSync as mkdtempSync4, rmSync as rmSync4 } from "fs";
947
1420
  async function listKnowledge() {
948
1421
  const config = loadConfig();
949
1422
  if (!config?.token) {
1423
+ if (shouldOutputJson()) {
1424
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
1425
+ process.exit(1);
1426
+ }
950
1427
  error("未登录,请先运行 arm login");
951
1428
  process.exit(1);
952
1429
  }
953
1430
  const client = new ApiClient(config.serverUrl, config.token);
954
1431
  try {
955
1432
  const result = await client.listKnowledge();
1433
+ if (shouldOutputJson()) {
1434
+ outputJson({ success: true, data: result });
1435
+ return;
1436
+ }
956
1437
  if (result.knowledges.length === 0) {
957
1438
  info("暂无 Knowledge");
958
1439
  return;
@@ -965,6 +1446,10 @@ async function listKnowledge() {
965
1446
  console.log("");
966
1447
  }
967
1448
  } catch (err) {
1449
+ if (shouldOutputJson()) {
1450
+ outputJson({ success: false, error: { code: "LIST_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
1451
+ process.exit(1);
1452
+ }
968
1453
  error(`获取列表失败: ${err instanceof Error ? err.message : "未知错误"}`);
969
1454
  process.exit(1);
970
1455
  }
@@ -972,12 +1457,20 @@ async function listKnowledge() {
972
1457
  async function searchKnowledge(keyword) {
973
1458
  const config = loadConfig();
974
1459
  if (!config?.token) {
1460
+ if (shouldOutputJson()) {
1461
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
1462
+ process.exit(1);
1463
+ }
975
1464
  error("未登录,请先运行 arm login");
976
1465
  process.exit(1);
977
1466
  }
978
1467
  const client = new ApiClient(config.serverUrl, config.token);
979
1468
  try {
980
1469
  const result = await client.listKnowledge(keyword);
1470
+ if (shouldOutputJson()) {
1471
+ outputJson({ success: true, data: result });
1472
+ return;
1473
+ }
981
1474
  if (result.knowledges.length === 0) {
982
1475
  info(`没有找到包含 "${keyword}" 的 Knowledge`);
983
1476
  return;
@@ -990,6 +1483,10 @@ async function searchKnowledge(keyword) {
990
1483
  console.log("");
991
1484
  }
992
1485
  } catch (err) {
1486
+ if (shouldOutputJson()) {
1487
+ outputJson({ success: false, error: { code: "SEARCH_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
1488
+ process.exit(1);
1489
+ }
993
1490
  error(`搜索失败: ${err instanceof Error ? err.message : "未知错误"}`);
994
1491
  process.exit(1);
995
1492
  }
@@ -997,14 +1494,26 @@ async function searchKnowledge(keyword) {
997
1494
  async function infoKnowledge(name) {
998
1495
  const config = loadConfig();
999
1496
  if (!config?.token) {
1497
+ if (shouldOutputJson()) {
1498
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
1499
+ process.exit(1);
1500
+ }
1000
1501
  error("未登录,请先运行 arm login");
1001
1502
  process.exit(1);
1002
1503
  }
1003
1504
  const client = new ApiClient(config.serverUrl, config.token);
1004
1505
  try {
1005
1506
  const knowledge = await client.getKnowledge(name);
1507
+ if (shouldOutputJson()) {
1508
+ outputJson({ success: true, data: knowledge });
1509
+ return;
1510
+ }
1006
1511
  console.log(formatKnowledgeDetail(knowledge));
1007
1512
  } catch (err) {
1513
+ if (shouldOutputJson()) {
1514
+ outputJson({ success: false, error: { code: "INFO_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
1515
+ process.exit(1);
1516
+ }
1008
1517
  error(`获取详情失败: ${err instanceof Error ? err.message : "未知错误"}`);
1009
1518
  process.exit(1);
1010
1519
  }
@@ -1012,17 +1521,31 @@ async function infoKnowledge(name) {
1012
1521
  async function downloadKnowledge(name, outputDir) {
1013
1522
  const config = loadConfig();
1014
1523
  if (!config?.token) {
1524
+ if (shouldOutputJson()) {
1525
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
1526
+ process.exit(1);
1527
+ }
1015
1528
  error("未登录,请先运行 arm login");
1016
1529
  process.exit(1);
1017
1530
  }
1018
1531
  const client = new ApiClient(config.serverUrl, config.token);
1019
1532
  try {
1020
- info(`正在下载 ${name}...`);
1533
+ if (shouldOutputJson()) {
1534
+ info(`正在下载 ${name}...`);
1535
+ }
1021
1536
  const buffer = await client.downloadKnowledge(name);
1022
1537
  const outputPath = join5(outputDir || ".", `${name}.zip`);
1023
1538
  writeFileSync4(outputPath, Buffer.from(buffer));
1539
+ if (shouldOutputJson()) {
1540
+ outputJson({ success: true, data: { path: outputPath } });
1541
+ return;
1542
+ }
1024
1543
  success(`已下载到 ${outputPath}`);
1025
1544
  } catch (err) {
1545
+ if (shouldOutputJson()) {
1546
+ outputJson({ success: false, error: { code: "DOWNLOAD_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
1547
+ process.exit(1);
1548
+ }
1026
1549
  error(`下载失败: ${err instanceof Error ? err.message : "未知错误"}`);
1027
1550
  process.exit(1);
1028
1551
  }
@@ -1030,10 +1553,18 @@ async function downloadKnowledge(name, outputDir) {
1030
1553
  async function uploadKnowledge(filePath) {
1031
1554
  const config = loadConfig();
1032
1555
  if (!config?.token) {
1556
+ if (shouldOutputJson()) {
1557
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
1558
+ process.exit(1);
1559
+ }
1033
1560
  error("未登录,请先运行 arm login");
1034
1561
  process.exit(1);
1035
1562
  }
1036
1563
  if (!existsSync5(filePath)) {
1564
+ if (shouldOutputJson()) {
1565
+ outputJson({ success: false, error: { code: "FILE_NOT_FOUND", message: `上传失败: 目录不存在: ${filePath}` } });
1566
+ process.exit(1);
1567
+ }
1037
1568
  error(`上传失败: 目录不存在: ${filePath}`);
1038
1569
  process.exit(1);
1039
1570
  }
@@ -1047,10 +1578,20 @@ async function uploadKnowledge(filePath) {
1047
1578
  execSync4(`cp "${filePath}" "${zipPath}"`, { stdio: "pipe" });
1048
1579
  }
1049
1580
  const client = new ApiClient(config.serverUrl, config.token);
1050
- info(`正在上传 ${filePath}...`);
1581
+ if (shouldOutputJson()) {
1582
+ info(`正在上传 ${filePath}...`);
1583
+ }
1051
1584
  const knowledge = await client.uploadKnowledge(zipPath);
1585
+ if (shouldOutputJson()) {
1586
+ outputJson({ success: true, data: knowledge });
1587
+ return;
1588
+ }
1052
1589
  success(`上传成功! Knowledge: ${knowledge.name}`);
1053
1590
  } catch (err) {
1591
+ if (shouldOutputJson()) {
1592
+ outputJson({ success: false, error: { code: "UPLOAD_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
1593
+ process.exit(1);
1594
+ }
1054
1595
  error(`上传失败: ${err instanceof Error ? err.message : "未知错误"}`);
1055
1596
  process.exit(1);
1056
1597
  } finally {
@@ -1060,12 +1601,20 @@ async function uploadKnowledge(filePath) {
1060
1601
  async function myKnowledge() {
1061
1602
  const config = loadConfig();
1062
1603
  if (!config?.token) {
1604
+ if (shouldOutputJson()) {
1605
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
1606
+ process.exit(1);
1607
+ }
1063
1608
  error("未登录,请先运行 arm login");
1064
1609
  process.exit(1);
1065
1610
  }
1066
1611
  const client = new ApiClient(config.serverUrl, config.token);
1067
1612
  try {
1068
1613
  const knowledges = await client.getMyKnowledge();
1614
+ if (shouldOutputJson()) {
1615
+ outputJson({ success: true, data: knowledges });
1616
+ return;
1617
+ }
1069
1618
  if (knowledges.length === 0) {
1070
1619
  info("您还没有发布任何 Knowledge");
1071
1620
  return;
@@ -1078,6 +1627,10 @@ async function myKnowledge() {
1078
1627
  console.log("");
1079
1628
  }
1080
1629
  } catch (err) {
1630
+ if (shouldOutputJson()) {
1631
+ outputJson({ success: false, error: { code: "LIST_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
1632
+ process.exit(1);
1633
+ }
1081
1634
  error(`获取列表失败: ${err instanceof Error ? err.message : "未知错误"}`);
1082
1635
  process.exit(1);
1083
1636
  }
@@ -1085,14 +1638,26 @@ async function myKnowledge() {
1085
1638
  async function deleteKnowledge(name) {
1086
1639
  const config = loadConfig();
1087
1640
  if (!config?.token) {
1641
+ if (shouldOutputJson()) {
1642
+ outputJson({ success: false, error: { code: "NOT_LOGGED_IN", message: "未登录,请先运行 arm login" } });
1643
+ process.exit(1);
1644
+ }
1088
1645
  error("未登录,请先运行 arm login");
1089
1646
  process.exit(1);
1090
1647
  }
1091
1648
  const client = new ApiClient(config.serverUrl, config.token);
1092
1649
  try {
1093
1650
  await client.deleteKnowledge(name);
1651
+ if (shouldOutputJson()) {
1652
+ outputJson({ success: true, data: { name } });
1653
+ return;
1654
+ }
1094
1655
  success(`已删除 ${name}`);
1095
1656
  } catch (err) {
1657
+ if (shouldOutputJson()) {
1658
+ outputJson({ success: false, error: { code: "DELETE_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
1659
+ process.exit(1);
1660
+ }
1096
1661
  error(`删除失败: ${err instanceof Error ? err.message : "未知错误"}`);
1097
1662
  process.exit(1);
1098
1663
  }
@@ -1257,6 +1822,15 @@ async function main() {
1257
1822
  case "me":
1258
1823
  await getCurrentUser();
1259
1824
  break;
1825
+ case "output":
1826
+ if (subCommand === "json" || subCommand === "text") {
1827
+ setOutputMode(subCommand);
1828
+ console.log(`输出模式已设置为: ${subCommand}`);
1829
+ } else {
1830
+ const mode = getOutputMode();
1831
+ console.log(`当前输出模式: ${mode}`);
1832
+ }
1833
+ break;
1260
1834
  case "agent":
1261
1835
  switch (subCommand) {
1262
1836
  case "ls":
@@ -1283,6 +1857,145 @@ async function main() {
1283
1857
  }
1284
1858
  await downloadAgent(args[2], args[3]);
1285
1859
  break;
1860
+ case "create":
1861
+ if (!args[2]) {
1862
+ console.error(`用法: arm agent create <name> [--description="..."] [--prompt="..."] [--avatar="..."] [--skill=id] [--knowledge=id] [--skill-config='{...}'] [--knowledge-config='{...}'] [--json]`);
1863
+ process.exit(1);
1864
+ }
1865
+ {
1866
+ const name = args[2];
1867
+ const options = {};
1868
+ const skills = [];
1869
+ const knowledges = [];
1870
+ const skillConfigs = [];
1871
+ const knowledgeConfigs = [];
1872
+ for (let i = 3;i < args.length; i++) {
1873
+ const arg = args[i];
1874
+ if (arg.startsWith("--description=")) {
1875
+ options.description = arg.split("=").slice(1).join("=");
1876
+ } else if (arg.startsWith("--prompt=")) {
1877
+ options.prompt = arg.split("=").slice(1).join("=");
1878
+ } else if (arg.startsWith("--avatar=")) {
1879
+ options.avatar = arg.split("=").slice(1).join("=");
1880
+ } else if (arg.startsWith("--skill=")) {
1881
+ skills.push(arg.split("=").slice(1).join("="));
1882
+ } else if (arg.startsWith("--knowledge=")) {
1883
+ knowledges.push(arg.split("=").slice(1).join("="));
1884
+ } else if (arg.startsWith("--skill-config=")) {
1885
+ skillConfigs.push(arg.split("=").slice(1).join("="));
1886
+ } else if (arg.startsWith("--knowledge-config=")) {
1887
+ knowledgeConfigs.push(arg.split("=").slice(1).join("="));
1888
+ }
1889
+ }
1890
+ await createAgent(name, {
1891
+ description: options.description,
1892
+ prompt: options.prompt,
1893
+ avatar: options.avatar,
1894
+ skills,
1895
+ knowledges,
1896
+ skillConfigs,
1897
+ knowledgeConfigs
1898
+ });
1899
+ }
1900
+ break;
1901
+ case "update":
1902
+ if (!args[2]) {
1903
+ console.error('用法: arm agent update <id> [--name="..."] [--description="..."] [--prompt="..."] [--avatar="..."] [--status=active|draft] [--json]');
1904
+ process.exit(1);
1905
+ }
1906
+ {
1907
+ const id = args[2];
1908
+ const options = {};
1909
+ for (let i = 3;i < args.length; i++) {
1910
+ const arg = args[i];
1911
+ if (arg.startsWith("--name=")) {
1912
+ options.name = arg.split("=").slice(1).join("=");
1913
+ } else if (arg.startsWith("--description=")) {
1914
+ options.description = arg.split("=").slice(1).join("=");
1915
+ } else if (arg.startsWith("--prompt=")) {
1916
+ options.prompt = arg.split("=").slice(1).join("=");
1917
+ } else if (arg.startsWith("--avatar=")) {
1918
+ options.avatar = arg.split("=").slice(1).join("=");
1919
+ } else if (arg.startsWith("--status=")) {
1920
+ options.status = arg.split("=").slice(1).join("=");
1921
+ }
1922
+ }
1923
+ await updateAgent(id, {
1924
+ name: options.name,
1925
+ description: options.description,
1926
+ prompt: options.prompt,
1927
+ avatar: options.avatar,
1928
+ status: options.status
1929
+ });
1930
+ }
1931
+ break;
1932
+ case "delete":
1933
+ if (!args[2]) {
1934
+ console.error("用法: arm agent delete <id> [--json]");
1935
+ process.exit(1);
1936
+ }
1937
+ await deleteAgent(args[2]);
1938
+ break;
1939
+ case "bind":
1940
+ if (!args[2]) {
1941
+ console.error("用法: arm agent bind <id> --skill=<skillId> [--skill-config='{...}'] 或 arm agent bind <id> --knowledge=<knowledgeId> [--knowledge-config='{...}'] [--json]");
1942
+ process.exit(1);
1943
+ }
1944
+ {
1945
+ const id = args[2];
1946
+ let skillId;
1947
+ let knowledgeId;
1948
+ let skillConfig;
1949
+ let knowledgeConfig;
1950
+ for (let i = 3;i < args.length; i++) {
1951
+ const arg = args[i];
1952
+ if (arg.startsWith("--skill=")) {
1953
+ skillId = arg.split("=").slice(1).join("=");
1954
+ } else if (arg.startsWith("--knowledge=")) {
1955
+ knowledgeId = arg.split("=").slice(1).join("=");
1956
+ } else if (arg.startsWith("--skill-config=")) {
1957
+ skillConfig = arg.split("=").slice(1).join("=");
1958
+ } else if (arg.startsWith("--knowledge-config=")) {
1959
+ knowledgeConfig = arg.split("=").slice(1).join("=");
1960
+ }
1961
+ }
1962
+ if (skillId) {
1963
+ await bindSkill(id, skillId, skillConfig);
1964
+ } else if (knowledgeId) {
1965
+ await bindKnowledge(id, knowledgeId, knowledgeConfig);
1966
+ } else {
1967
+ console.error("用法: arm agent bind <id> --skill=<skillId> 或 --knowledge=<knowledgeId>");
1968
+ process.exit(1);
1969
+ }
1970
+ }
1971
+ break;
1972
+ case "unbind":
1973
+ if (!args[2]) {
1974
+ console.error("用法: arm agent unbind <id> --skill=<skillId> 或 --knowledge=<knowledgeId> [--json]");
1975
+ process.exit(1);
1976
+ }
1977
+ {
1978
+ const id = args[2];
1979
+ let skillId;
1980
+ let knowledgeId;
1981
+ for (let i = 3;i < args.length; i++) {
1982
+ const arg = args[i];
1983
+ if (arg.startsWith("--skill=")) {
1984
+ skillId = arg.split("=").slice(1).join("=");
1985
+ } else if (arg.startsWith("--knowledge=")) {
1986
+ knowledgeId = arg.split("=").slice(1).join("=");
1987
+ }
1988
+ }
1989
+ if (skillId) {
1990
+ await unbindSkill(id, skillId);
1991
+ } else if (knowledgeId) {
1992
+ await unbindKnowledge(id, knowledgeId);
1993
+ } else {
1994
+ console.error("用法: arm agent unbind <id> --skill=<skillId> 或 --knowledge=<knowledgeId>");
1995
+ process.exit(1);
1996
+ }
1997
+ }
1998
+ break;
1286
1999
  default:
1287
2000
  console.log(`
1288
2001
  可用命令:
@@ -1290,6 +2003,14 @@ async function main() {
1290
2003
  arm agent search <keyword> 搜索 Agent
1291
2004
  arm agent info <name> 查看 Agent 详情
1292
2005
  arm agent download <name> [dir] 下载 Agent
2006
+ arm agent create <name> 创建 Agent (--description, --prompt, --avatar, --skill, --knowledge)
2007
+ arm agent update <id> 更新 Agent (--name, --description, --prompt, --avatar, --status)
2008
+ arm agent delete <id> 删除 Agent
2009
+ arm agent bind <id> --skill=<id> 绑定 Skill 到 Agent
2010
+ arm agent unbind <id> --skill=<id> 解绑 Skill
2011
+ arm agent bind <id> --knowledge=<id> 绑定 Knowledge 到 Agent
2012
+ arm agent unbind <id> --knowledge=<id> 解绑 Knowledge
2013
+ 所有命令支持 --json 参数获取机器可读输出
1293
2014
  `);
1294
2015
  }
1295
2016
  break;
@@ -1300,6 +2021,7 @@ Agent Resource Management (arm)
1300
2021
  用法:
1301
2022
  arm login <server-url> <api-key> 登录
1302
2023
  arm logout 登出
2024
+ arm output [json|text] 设置/查看输出模式 (默认json)
1303
2025
  arm skill ls 列出所有 Skill
1304
2026
  arm skill search <keyword> 搜索 Skill
1305
2027
  arm skill info <name> 查看 Skill 详情
@@ -1319,8 +2041,16 @@ Agent Resource Management (arm)
1319
2041
  arm agent search <keyword> 搜索 Agent
1320
2042
  arm agent info <name> 查看 Agent 详情
1321
2043
  arm agent download <name> [dir] 下载 Agent
2044
+ arm agent create <name> 创建 Agent
2045
+ arm agent update <id> 更新 Agent
2046
+ arm agent delete <id> 删除 Agent
2047
+ arm agent bind <id> --skill=<id> 绑定 Skill
2048
+ arm agent unbind <id> --skill=<id> 解绑 Skill
2049
+ arm agent bind <id> --knowledge=<id> 绑定 Knowledge
2050
+ arm agent unbind <id> --knowledge=<id> 解绑 Knowledge
1322
2051
  arm server 显示当前服务端
1323
2052
  arm server set <url> 设置服务端
2053
+ 使用 arm <entity> -h 查看详细帮助
1324
2054
  `);
1325
2055
  }
1326
2056
  }