agent-resource-management 2.1.0 → 2.1.1

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/README.md CHANGED
@@ -13,6 +13,7 @@ Agent Resource Management CLI 是一个用于管理 Skills、Knowledges 和 Agen
13
13
  - 上传/下载/删除
14
14
  - 本地验证
15
15
  - 多服务端支持
16
+ - **JSON 输出模式** - 便于 AI Agent 集成
16
17
 
17
18
  ## 安装
18
19
 
@@ -96,10 +97,10 @@ arm agent download workspace-assistant ./agents
96
97
  ### 6. 上传
97
98
 
98
99
  ```bash
99
- # 上传本地 Skill 目录
100
+ # 上传本地 Skill 目录或 ZIP 文件
100
101
  arm skill upload ./my-skills/pdf-tool
101
102
 
102
- # 上传本地 Knowledge 目录
103
+ # 上传本地 Knowledge 文件或目录
103
104
  arm knowledge upload ./my-knowledges/api-doc
104
105
  ```
105
106
 
@@ -113,6 +114,39 @@ arm skill validate ./my-skills/pdf-tool
113
114
  arm skill validate ./my-skills/pdf-tool.zip
114
115
  ```
115
116
 
117
+ ### 8. JSON 输出模式
118
+
119
+ CLI 默认输出 JSON 格式,便于 AI Agent 解析和集成:
120
+
121
+ ```bash
122
+ # 查看当前输出模式
123
+ arm output
124
+
125
+ # 切换为文本模式(人类可读)
126
+ arm output text
127
+
128
+ # 切换为 JSON 模式(默认)
129
+ arm output json
130
+
131
+ # 所有命令都支持 --json 参数强制输出 JSON
132
+ arm agent create my-agent --json
133
+ arm skill ls --json
134
+ ```
135
+
136
+ JSON 输出格式:
137
+
138
+ ```json
139
+ {
140
+ "success": true,
141
+ "data": { ... }
142
+ }
143
+ // 或
144
+ {
145
+ "success": false,
146
+ "error": { "code": "ERROR_CODE", "message": "错误信息" }
147
+ }
148
+ ```
149
+
116
150
  ## 命令参考
117
151
 
118
152
  ### 认证命令
@@ -131,7 +165,7 @@ arm skill validate ./my-skills/pdf-tool.zip
131
165
  | `arm skill search <keyword>` | 搜索 Skills |
132
166
  | `arm skill info <name>` | 查看 Skill 详情 |
133
167
  | `arm skill download <name> [dir]` | 下载 Skill 到指定目录 |
134
- | `arm skill upload <path>` | 上传本地 Skill 目录 |
168
+ | `arm skill upload <path>` | 上传本地 Skill 目录或 ZIP 文件 |
135
169
  | `arm skill my` | 查看我发布的 Skills |
136
170
  | `arm skill delete <name>` | 删除我发布的 Skill |
137
171
  | `arm skill validate <path>` | 验证 Skill 格式(支持目录和 ZIP) |
@@ -144,7 +178,7 @@ arm skill validate ./my-skills/pdf-tool.zip
144
178
  | `arm knowledge search <keyword>` | 搜索 Knowledges |
145
179
  | `arm knowledge info <name>` | 查看 Knowledge 详情 |
146
180
  | `arm knowledge download <name> [dir]` | 下载 Knowledge 到指定目录 |
147
- | `arm knowledge upload <path>` | 上传本地 Knowledge 目录 |
181
+ | `arm knowledge upload <path>` | 上传本地 Knowledge 文件或目录 |
148
182
  | `arm knowledge my` | 查看我发布的 Knowledges |
149
183
  | `arm knowledge delete <name>` | 删除我发布的 Knowledge |
150
184
 
@@ -164,6 +198,26 @@ arm skill validate ./my-skills/pdf-tool.zip
164
198
  | `arm server` | 显示当前服务端 |
165
199
  | `arm server set <url>` | 设置默认服务端 |
166
200
 
201
+ ### 输出模式命令
202
+
203
+ | 命令 | 说明 |
204
+ |------|------|
205
+ | `arm output` | 查看当前输出模式 |
206
+ | `arm output json` | 设置为 JSON 模式(默认) |
207
+ | `arm output text` | 设置为文本模式 |
208
+
209
+ ### 输出格式说明
210
+
211
+ 所有命令都支持 `--json` 或 `-j` 参数强制输出 JSON 格式。当默认模式为 `json` 时,所有命令直接返回 JSON。
212
+
213
+ **Agent 命令(创建/更新/删除/绑定/解绑)** 始终支持 `--json`:
214
+ ```bash
215
+ arm agent create my-agent --json
216
+ arm agent update <id> --name=new-name --json
217
+ arm agent delete <id> --json
218
+ arm agent bind <id> --skill=<id> --json
219
+ ```
220
+
167
221
  ## Skill 格式规范
168
222
 
169
223
  上传的 Skill 目录必须包含 `SKILL.md` 文件,且 frontmatter 必须符合以下格式:
@@ -202,10 +256,13 @@ allowed-tools: tool1 tool2 # 可选,空格分隔
202
256
  "id": "user-id",
203
257
  "name": "username",
204
258
  "email": "user@example.com"
205
- }
259
+ },
260
+ "outputMode": "json"
206
261
  }
207
262
  ```
208
263
 
264
+ 其中 `outputMode` 可选值为 `json`(默认)或 `text`。
265
+
209
266
  ## 开发
210
267
 
211
268
  ```bash
package/dist/main.js CHANGED
@@ -40,6 +40,16 @@ class ApiClient {
40
40
  }
41
41
  return res.data;
42
42
  }
43
+ async register(email, password, name) {
44
+ const res = await this.request("/auth/register", {
45
+ method: "POST",
46
+ body: JSON.stringify({ email, password, name })
47
+ });
48
+ if (!res.ok) {
49
+ throw new Error(res.msg);
50
+ }
51
+ return res.data;
52
+ }
43
53
  async me() {
44
54
  const res = await this.request("/auth/me");
45
55
  if (!res.ok) {
@@ -462,6 +472,47 @@ function formatKnowledgeDetail(knowledge) {
462
472
  }
463
473
 
464
474
  // src/cmd/auth.ts
475
+ async function register(name, email, password) {
476
+ const { readline } = await import("readline");
477
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
478
+ const ask = (question) => new Promise((resolve) => rl.question(question, resolve));
479
+ let finalEmail = email;
480
+ let finalPassword = password;
481
+ let finalName = name;
482
+ if (!finalEmail) {
483
+ finalEmail = await ask("请输入邮箱: ");
484
+ }
485
+ if (!finalPassword) {
486
+ finalPassword = await ask("请输入密码: ");
487
+ }
488
+ if (!finalName) {
489
+ finalName = await ask("请输入用户名: ");
490
+ }
491
+ rl.close();
492
+ if (!finalEmail || !finalPassword || !finalName) {
493
+ error("邮箱、密码和用户名都不能为空");
494
+ process.exit(1);
495
+ }
496
+ if (finalPassword.length < 8) {
497
+ error("密码至少需要 8 个字符");
498
+ process.exit(1);
499
+ }
500
+ const config = loadConfig();
501
+ const serverUrl = config?.serverUrl || "http://localhost:3000";
502
+ const client = new ApiClient(serverUrl);
503
+ try {
504
+ const result = await client.register(finalEmail, finalPassword, finalName);
505
+ saveConfig({
506
+ serverUrl,
507
+ token: result.token,
508
+ user: result.user
509
+ });
510
+ success(`注册成功! 欢迎, ${result.user.name}`);
511
+ } catch (err) {
512
+ error(`注册失败: ${err instanceof Error ? err.message : "未知错误"}`);
513
+ process.exit(1);
514
+ }
515
+ }
465
516
  async function login(serverUrl, apiKey) {
466
517
  try {
467
518
  const client = new ApiClient(serverUrl);
@@ -1587,6 +1638,9 @@ async function uploadKnowledge(filePath) {
1587
1638
  return;
1588
1639
  }
1589
1640
  success(`上传成功! Knowledge: ${knowledge.name}`);
1641
+ if (knowledge.shareUrl) {
1642
+ info(`分享链接: ${knowledge.shareUrl}`);
1643
+ }
1590
1644
  } catch (err) {
1591
1645
  if (shouldOutputJson()) {
1592
1646
  outputJson({ success: false, error: { code: "UPLOAD_FAILED", message: err instanceof Error ? err.message : "未知错误" } });
@@ -1678,6 +1732,21 @@ var command = args[0];
1678
1732
  var subCommand = args[1];
1679
1733
  async function main() {
1680
1734
  switch (command) {
1735
+ case "register":
1736
+ if (args[1] && args[1].startsWith("--")) {
1737
+ const options = {};
1738
+ for (let i = 1;i < args.length; i++) {
1739
+ const arg = args[i];
1740
+ if (arg.startsWith("--")) {
1741
+ const [key, value] = arg.slice(2).split("=");
1742
+ options[key] = value;
1743
+ }
1744
+ }
1745
+ await register(options.name, options.email, options.password);
1746
+ } else {
1747
+ await register(args[1], args[2], args[3]);
1748
+ }
1749
+ break;
1681
1750
  case "login":
1682
1751
  if (!args[1] || !args[2]) {
1683
1752
  console.error("用法: arm login <server-url> <api-key>");
@@ -2019,6 +2088,7 @@ async function main() {
2019
2088
  Agent Resource Management (arm)
2020
2089
 
2021
2090
  用法:
2091
+ arm register [--name=<name>] [--email=<email>] [--password=<password>] 注册 (交互式或参数)
2022
2092
  arm login <server-url> <api-key> 登录
2023
2093
  arm logout 登出
2024
2094
  arm output [json|text] 设置/查看输出模式 (默认json)
package/dist/test.md ADDED
@@ -0,0 +1,3 @@
1
+ # test
2
+ - hi
3
+ - huw
package/dist/test2.md ADDED
@@ -0,0 +1,3 @@
1
+ # test
2
+ - hi
3
+ - huw
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-resource-management",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "arm": "./dist/main.js"
package/src/cmd/auth.ts CHANGED
@@ -2,6 +2,56 @@ import { ApiClient } from '../lib/client';
2
2
  import { loadConfig, saveConfig } from '../lib/storage';
3
3
  import { success, error, info } from '../lib/formatter';
4
4
 
5
+ export async function register(name?: string, email?: string, password?: string): Promise<void> {
6
+ const { readline } = await import('readline');
7
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
8
+
9
+ const ask = (question: string): Promise<string> =>
10
+ new Promise((resolve) => rl.question(question, resolve));
11
+
12
+ let finalEmail = email;
13
+ let finalPassword = password;
14
+ let finalName = name;
15
+
16
+ if (!finalEmail) {
17
+ finalEmail = await ask('请输入邮箱: ');
18
+ }
19
+ if (!finalPassword) {
20
+ finalPassword = await ask('请输入密码: ');
21
+ }
22
+ if (!finalName) {
23
+ finalName = await ask('请输入用户名: ');
24
+ }
25
+ rl.close();
26
+
27
+ if (!finalEmail || !finalPassword || !finalName) {
28
+ error('邮箱、密码和用户名都不能为空');
29
+ process.exit(1);
30
+ }
31
+
32
+ if (finalPassword.length < 8) {
33
+ error('密码至少需要 8 个字符');
34
+ process.exit(1);
35
+ }
36
+
37
+ const config = loadConfig();
38
+ const serverUrl = config?.serverUrl || 'http://localhost:3000';
39
+ const client = new ApiClient(serverUrl);
40
+
41
+ try {
42
+ const result = await client.register(finalEmail, finalPassword, finalName);
43
+ saveConfig({
44
+ serverUrl,
45
+ token: result.token,
46
+ user: result.user,
47
+ });
48
+ success(`注册成功! 欢迎, ${result.user.name}`);
49
+ } catch (err) {
50
+ error(`注册失败: ${err instanceof Error ? err.message : '未知错误'}`);
51
+ process.exit(1);
52
+ }
53
+ }
54
+
5
55
  export async function login(serverUrl: string, apiKey: string): Promise<void> {
6
56
  try {
7
57
  const client = new ApiClient(serverUrl);
@@ -185,6 +185,9 @@ export async function uploadKnowledge(filePath: string): Promise<void> {
185
185
  return;
186
186
  }
187
187
  success(`上传成功! Knowledge: ${knowledge.name}`);
188
+ if (knowledge.shareUrl) {
189
+ info(`分享链接: ${knowledge.shareUrl}`);
190
+ }
188
191
  } catch (err) {
189
192
  if (shouldOutputJson()) {
190
193
  outputJson({ success: false, error: { code: 'UPLOAD_FAILED', message: err instanceof Error ? err.message : '未知错误' } });
package/src/lib/client.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { User, Skill, SkillListResponse, ApiResponse, LoginResponse, Agent, AgentListResponse } from '@pkg/types/skill';
1
+ import type { User, Skill, SkillListResponse, ApiResponse, LoginResponse, RegisterResponse, Agent, AgentListResponse } from '@pkg/types/skill';
2
2
 
3
3
  export class ApiClient {
4
4
  private token: string | null = null;
@@ -49,6 +49,17 @@ export class ApiClient {
49
49
  return res.data;
50
50
  }
51
51
 
52
+ async register(email: string, password: string, name: string): Promise<RegisterResponse> {
53
+ const res = await this.request<RegisterResponse>('/auth/register', {
54
+ method: 'POST',
55
+ body: JSON.stringify({ email, password, name }),
56
+ });
57
+ if (!res.ok) {
58
+ throw new Error(res.msg);
59
+ }
60
+ return res.data;
61
+ }
62
+
52
63
  async me(): Promise<User> {
53
64
  const res = await this.request<User>('/auth/me');
54
65
  if (!res.ok) {
package/src/main.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { login, logout, getCurrentUser } from './cmd/auth';
1
+ import { login, logout, getCurrentUser, register } from './cmd/auth';
2
2
  import { listSkills, searchSkills, infoSkill, downloadSkill, uploadSkill, mySkills, deleteSkill, validateSkill } from './cmd/skill';
3
3
  import { listAgents, searchAgents, infoAgent, downloadAgent, createAgent, updateAgent, deleteAgent, bindSkill, unbindSkill, bindKnowledge, unbindKnowledge } from './cmd/agent';
4
4
  import { listKnowledge, searchKnowledge, infoKnowledge, downloadKnowledge, uploadKnowledge, myKnowledge, deleteKnowledge } from './cmd/knowledge';
@@ -11,6 +11,22 @@ const subCommand = args[1];
11
11
 
12
12
  async function main() {
13
13
  switch (command) {
14
+ case 'register':
15
+ if (args[1] && args[1].startsWith('--')) {
16
+ const options: Record<string, string | undefined> = {};
17
+ for (let i = 1; i < args.length; i++) {
18
+ const arg = args[i];
19
+ if (arg.startsWith('--')) {
20
+ const [key, value] = arg.slice(2).split('=');
21
+ options[key] = value;
22
+ }
23
+ }
24
+ await register(options.name, options.email, options.password);
25
+ } else {
26
+ await register(args[1], args[2], args[3]);
27
+ }
28
+ break;
29
+
14
30
  case 'login':
15
31
  if (!args[1] || !args[2]) {
16
32
  console.error('用法: arm login <server-url> <api-key>');
@@ -368,6 +384,7 @@ async function main() {
368
384
  Agent Resource Management (arm)
369
385
 
370
386
  用法:
387
+ arm register [--name=<name>] [--email=<email>] [--password=<password>] 注册 (交互式或参数)
371
388
  arm login <server-url> <api-key> 登录
372
389
  arm logout 登出
373
390
  arm output [json|text] 设置/查看输出模式 (默认json)