relayax-cli 0.4.13 → 0.4.15

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.
@@ -14,20 +14,6 @@ const command_adapter_js_1 = require("../lib/command-adapter.js");
14
14
  const config_js_1 = require("../lib/config.js");
15
15
  // eslint-disable-next-line @typescript-eslint/no-var-requires
16
16
  const pkg = require('../../package.json');
17
- const VALID_AGENT_DIRS = ['skills', 'agents', 'rules', 'commands'];
18
- function resolveTools(toolsArg) {
19
- const raw = toolsArg.trim().toLowerCase();
20
- if (raw === 'all') {
21
- return ai_tools_js_1.AI_TOOLS.map((t) => t.value);
22
- }
23
- const tokens = raw.split(',').map((t) => t.trim()).filter(Boolean);
24
- const valid = new Set(ai_tools_js_1.AI_TOOLS.map((t) => t.value));
25
- const invalid = tokens.filter((t) => !valid.has(t));
26
- if (invalid.length > 0) {
27
- throw new Error(`알 수 없는 도구: ${invalid.join(', ')}\n사용 가능: ${[...valid].join(', ')}`);
28
- }
29
- return tokens;
30
- }
31
17
  function showWelcome() {
32
18
  const lines = [
33
19
  '',
@@ -48,23 +34,6 @@ function showWelcome() {
48
34
  ];
49
35
  console.log(lines.join('\n'));
50
36
  }
51
- async function selectToolsInteractively(detectedIds) {
52
- const { checkbox } = await import('@inquirer/prompts');
53
- const choices = ai_tools_js_1.AI_TOOLS.map((tool) => {
54
- const detected = detectedIds.has(tool.value);
55
- return {
56
- name: detected ? `${tool.name} \x1b[32m(detected)\x1b[0m` : tool.name,
57
- value: tool.value,
58
- checked: detected,
59
- };
60
- });
61
- const selected = await checkbox({
62
- message: `연결할 에이전트 CLI를 선택하세요`,
63
- choices,
64
- pageSize: 8,
65
- });
66
- return selected;
67
- }
68
37
  /**
69
38
  * 글로벌 User 커맨드를 감지된 모든 에이전트 CLI에 설치한다.
70
39
  * ~/{skillsDir}/commands/relay/ 에 설치.
@@ -111,23 +80,6 @@ function installGlobalUserCommands() {
111
80
  function hasGlobalUserCommands() {
112
81
  return command_adapter_js_1.USER_COMMANDS.every((cmd) => fs_1.default.existsSync((0, command_adapter_js_1.getGlobalCommandPath)(cmd.id)));
113
82
  }
114
- /**
115
- * 에이전트 프로젝트인지 감지한다 (.relay/ 디렉토리 내 relay.yaml 또는 에이전트 디렉토리 구조).
116
- */
117
- function isAgentProject(projectPath) {
118
- const relayDir = path_1.default.join(projectPath, '.relay');
119
- if (!fs_1.default.existsSync(relayDir))
120
- return false;
121
- if (fs_1.default.existsSync(path_1.default.join(relayDir, 'relay.yaml'))) {
122
- return true;
123
- }
124
- return VALID_AGENT_DIRS.some((d) => {
125
- const dirPath = path_1.default.join(relayDir, d);
126
- if (!fs_1.default.existsSync(dirPath))
127
- return false;
128
- return fs_1.default.readdirSync(dirPath).filter((f) => !f.startsWith('.')).length > 0;
129
- });
130
- }
131
83
  function registerInit(program) {
132
84
  program
133
85
  .command('init')
@@ -142,8 +94,6 @@ function registerInit(program) {
142
94
  const autoMode = opts.auto === true || opts.all === true || !process.stdin.isTTY;
143
95
  const projectPath = (0, paths_js_1.resolveProjectPath)(opts.project);
144
96
  const detected = (0, ai_tools_js_1.detectAgentCLIs)(projectPath);
145
- const detectedIds = new Set(detected.map((t) => t.value));
146
- const isBuilder = isAgentProject(projectPath);
147
97
  // ── 0. --json 모드에서 --tools/--all 없으면 MISSING_TOOLS 에러 ──
148
98
  if (json && !opts.tools && !opts.all && !opts.auto) {
149
99
  const detectedOptions = detected.map((t) => ({ value: t.value, label: t.name }));
@@ -177,84 +127,18 @@ function registerInit(program) {
177
127
  };
178
128
  (0, config_js_1.saveInstalled)(installed);
179
129
  }
180
- // ── 2. 로컬 Builder 커맨드 (에이전트 프로젝트인 경우) ──
181
- // relay-publish가 글로벌로 승격되어 BUILDER_COMMANDS가 비어있으면 스킵
182
- const localResults = [];
183
- if (isBuilder && command_adapter_js_1.BUILDER_COMMANDS.length > 0) {
184
- // 도구 선택
185
- let targetToolIds;
186
- if (opts.tools) {
187
- targetToolIds = resolveTools(opts.tools);
188
- }
189
- else if (!autoMode) {
190
- // interactive mode: only when stdin is a TTY and not --auto/--json
191
- showWelcome();
192
- if (detected.length > 0) {
193
- console.log(` 감지된 에이전트 CLI: \x1b[36m${detected.map((t) => t.name).join(', ')}\x1b[0m\n`);
194
- }
195
- console.log(' \x1b[2mBuilder 프로젝트 감지 → 로컬 Builder 커맨드도 설치합니다.\x1b[0m\n');
196
- targetToolIds = await selectToolsInteractively(detectedIds);
197
- if (targetToolIds.length === 0) {
198
- console.log('\n 선택된 도구가 없습니다.');
199
- // 글로벌은 이미 설치됨
200
- if (globalStatus === 'installed') {
201
- console.log(' 글로벌 User 커맨드는 설치되었습니다.\n');
202
- }
203
- return;
204
- }
205
- }
206
- else {
207
- // auto mode: use detected CLIs, or all available tools if none detected
208
- if (detected.length > 0) {
209
- targetToolIds = detected.map((t) => t.value);
210
- }
211
- else {
212
- targetToolIds = ai_tools_js_1.AI_TOOLS.map((t) => t.value);
213
- }
214
- }
215
- // Builder 커맨드 설치 (기존 파일 중 현재 목록에 없는 것 제거)
216
- const builderIds = new Set(command_adapter_js_1.BUILDER_COMMANDS.map((c) => c.id));
217
- for (const toolId of targetToolIds) {
218
- const tool = ai_tools_js_1.AI_TOOLS.find((t) => t.value === toolId);
219
- if (!tool)
220
- continue;
221
- const adapter = (0, command_adapter_js_1.createAdapter)(tool);
222
- const localDir = path_1.default.join(projectPath, tool.skillsDir, 'commands', 'relay');
223
- // 기존 로컬 커맨드 중 Builder 목록에 없는 것 제거
224
- if (fs_1.default.existsSync(localDir)) {
225
- for (const file of fs_1.default.readdirSync(localDir)) {
226
- const id = file.replace(/\.md$/, '');
227
- if (!builderIds.has(id)) {
228
- fs_1.default.unlinkSync(path_1.default.join(localDir, file));
229
- }
230
- }
231
- }
232
- const installedCommands = [];
233
- for (const cmd of command_adapter_js_1.BUILDER_COMMANDS) {
234
- const filePath = path_1.default.join(projectPath, adapter.getFilePath(cmd.id));
235
- const fileContent = adapter.formatFile(cmd);
236
- fs_1.default.mkdirSync(path_1.default.dirname(filePath), { recursive: true });
237
- fs_1.default.writeFileSync(filePath, fileContent);
238
- installedCommands.push(cmd.id);
239
- }
240
- localResults.push({ tool: tool.name, commands: installedCommands });
241
- }
242
- }
243
- else if (!autoMode) {
244
- // User 모드: 글로벌만 설치, 안내 표시
130
+ if (!autoMode) {
245
131
  showWelcome();
246
132
  }
247
- // ── 3. 출력 ──
133
+ // ── 2. 출력 ──
248
134
  if (json) {
249
135
  console.log(JSON.stringify({
250
136
  status: 'ok',
251
- mode: isBuilder ? 'builder' : 'user',
252
137
  global: {
253
138
  status: globalStatus,
254
139
  path: (0, command_adapter_js_1.getGlobalCommandDir)(),
255
140
  commands: command_adapter_js_1.USER_COMMANDS.map((c) => c.id),
256
141
  },
257
- local: isBuilder ? localResults : undefined,
258
142
  }));
259
143
  }
260
144
  else {
@@ -270,28 +154,15 @@ function registerInit(program) {
270
154
  // 글로벌
271
155
  {
272
156
  const toolNames = globalTools.length > 0 ? globalTools.join(', ') : '(감지된 CLI 없음)';
273
- console.log(` \x1b[36mUser 커맨드 (글로벌)\x1b[0m — ${globalStatus === 'updated' ? '업데이트됨' : '설치됨'}`);
157
+ console.log(` \x1b[36m커맨드 (글로벌)\x1b[0m — ${globalStatus === 'updated' ? '업데이트됨' : '설치됨'}`);
274
158
  console.log(` 감지된 CLI: \x1b[36m${toolNames}\x1b[0m`);
275
159
  for (const cmd of command_adapter_js_1.USER_COMMANDS) {
276
160
  console.log(` /${cmd.id}`);
277
161
  }
278
162
  console.log();
279
163
  }
280
- // 로컬 Builder
281
- if (localResults.length > 0) {
282
- console.log(` \x1b[36mBuilder 커맨드 (로컬)\x1b[0m`);
283
- for (const r of localResults) {
284
- console.log(` ${r.tool}`);
285
- for (const cmd of r.commands) {
286
- console.log(` /${cmd}`);
287
- }
288
- }
289
- console.log();
290
- }
291
- if (!isBuilder) {
292
- console.log(' 에이전트를 만들려면 \x1b[33mrelay create <name>\x1b[0m을 사용하세요.');
293
- console.log();
294
- }
164
+ console.log(' 에이전트를 만들려면 \x1b[33mrelay create <name>\x1b[0m을 사용하세요.');
165
+ console.log();
295
166
  console.log(' IDE를 재시작하면 슬래시 커맨드가 활성화됩니다.');
296
167
  }
297
168
  });
@@ -784,28 +784,28 @@ function registerPublish(program) {
784
784
  // preamble update is best-effort — publish already succeeded
785
785
  }
786
786
  if (json) {
787
- console.log(JSON.stringify(result));
787
+ // Enrich JSON output with plugin_url if git_url available
788
+ const jsonResult = { ...result };
789
+ const resultGitUrl = jsonResult.git_url;
790
+ if (resultGitUrl) {
791
+ const pSlug = jsonResult.slug.startsWith('@') ? jsonResult.slug.slice(1) : jsonResult.slug;
792
+ const pName = pSlug.includes('/') ? pSlug.split('/')[1] : pSlug;
793
+ jsonResult.plugin_url = `${config_js_1.API_URL}/api/registry/@${pSlug}/plugin`;
794
+ jsonResult.plugin_install_cmd = `/plugin install ${pName}`;
795
+ }
796
+ jsonResult.platforms = generatedPlatforms;
797
+ console.log(JSON.stringify(jsonResult));
788
798
  }
789
799
  else {
790
800
  console.log(`\n\x1b[32m✓ ${config.name} 배포 완료\x1b[0m v${result.version}`);
791
801
  console.log(` 슬러그: \x1b[36m${result.slug}\x1b[0m`);
792
802
  console.log(` URL: \x1b[36m${result.url}\x1b[0m`);
793
- // Show generated platform manifests
794
- if (generatedPlatforms.length > 0) {
795
- console.log(`\n \x1b[90m플랫폼 매니페스트:\x1b[0m ${generatedPlatforms.join(', ')}`);
796
- }
797
- // Show Claude Code plugin install command if claude-code manifest was generated
798
- if (generatedPlatforms.includes('claude-code')) {
799
- const pluginSlug = result.slug.startsWith('@') ? result.slug.slice(1) : result.slug;
800
- const pluginUrl = `${config_js_1.API_URL}/api/registry/@${pluginSlug}/plugin`;
801
- console.log(`\n \x1b[90mClaude Code 플러그인:\x1b[0m`);
802
- console.log(` \x1b[36m/plugin marketplace add ${pluginUrl}\x1b[0m`);
803
- }
804
- // Show shareable onboarding guide as a plain copyable block
805
- if (isTTY) {
803
+ // Build share block
804
+ {
806
805
  const detailSlug = result.slug.startsWith('@') ? result.slug.slice(1) : result.slug;
807
806
  const accessCode = result.access_code;
808
- // Primary: npx 설치 명령어 한 줄
807
+ const gitUrl = result.git_url;
808
+ // CLI install command
809
809
  const visibility = config.visibility ?? 'public';
810
810
  let installCmd;
811
811
  if (visibility === 'internal' && accessCode) {
@@ -817,12 +817,46 @@ function registerPublish(program) {
817
817
  else {
818
818
  installCmd = `npx relayax-cli install ${result.slug}`;
819
819
  }
820
- console.log(`\n \x1b[90m공유하세요:\x1b[0m`);
821
- console.log(` ┌${''.repeat(installCmd.length + 2)}┐`);
822
- console.log(` │ ${installCmd} │`);
823
- console.log(` └${'─'.repeat(installCmd.length + 2)}┘`);
824
- // Secondary: 에이전트 소개 페이지
825
- console.log(`\n \x1b[90m에이전트 소개: \x1b[36mhttps://relayax.com/@${detailSlug}\x1b[0m`);
820
+ // Plugin install commands (marketplace add + plugin install)
821
+ const pluginSlug = detailSlug.includes('/') ? detailSlug.split('/')[1] : detailSlug;
822
+ const pluginUrl = gitUrl ? `${config_js_1.API_URL}/api/registry/@${detailSlug}/plugin` : null;
823
+ // ── CLI 설치 (복사용) ──
824
+ console.log(`\n \x1b[1m▸ CLI 설치\x1b[0m`);
825
+ console.log(` ┌─`);
826
+ console.log(` │ ${installCmd}`);
827
+ console.log(` └─`);
828
+ // ── Claude Code Plugin 설치 (복사용) ──
829
+ if (pluginUrl) {
830
+ console.log(`\n \x1b[1m▸ Claude Code Plugin 설치\x1b[0m`);
831
+ console.log(` ┌─`);
832
+ console.log(` │ /plugin marketplace add ${pluginUrl}`);
833
+ console.log(` │ /plugin install ${pluginSlug}`);
834
+ console.log(` └─`);
835
+ }
836
+ // ── 소개 페이지 ──
837
+ console.log(`\n \x1b[90m소개 페이지:\x1b[0m https://relayax.com/@${detailSlug}`);
838
+ // ── 공유 텍스트 (코드블록, 그대로 복붙) ──
839
+ if (isTTY) {
840
+ const shareBlock = [
841
+ `[${config.name}] 설치하기`,
842
+ ``,
843
+ `# CLI`,
844
+ installCmd,
845
+ ];
846
+ if (pluginUrl) {
847
+ shareBlock.push(``, `# Claude Code Plugin`, `/plugin marketplace add ${pluginUrl}`, `/plugin install ${pluginSlug}`);
848
+ }
849
+ shareBlock.push(``, `소개: https://relayax.com/@${detailSlug}`);
850
+ const maxLen = Math.max(...shareBlock.map((l) => l.length));
851
+ const border = '─'.repeat(maxLen + 2);
852
+ console.log(`\n \x1b[90m┌${border}┐\x1b[0m`);
853
+ for (const line of shareBlock) {
854
+ const pad = ' '.repeat(maxLen - line.length);
855
+ console.log(` \x1b[90m│\x1b[0m ${line}${pad} \x1b[90m│\x1b[0m`);
856
+ }
857
+ console.log(` \x1b[90m└${border}┘\x1b[0m`);
858
+ console.log(` \x1b[90m↑ 팀에 공유하세요\x1b[0m`);
859
+ }
826
860
  }
827
861
  }
828
862
  }
@@ -3,6 +3,27 @@ relay.yaml이 없으면 새로 만들고, 있으면 변경사항을 반영합니
3
3
 
4
4
  > 빌더는 터미널 환경에서 작업합니다. CLI 명령어를 직접 실행하세요.
5
5
 
6
+ ## 핵심 원칙: 의사결정 포인트에서 사용자 질문
7
+
8
+ 각 단계에서 **선택지가 2개 이상**이면 반드시 사용자에게 질문하고 답변을 기다리세요.
9
+ (AskUserQuestion 등 사용자 입력을 받는 도구를 사용하세요.)
10
+ 선택지가 1개뿐이거나 자동 판단이 가능하면 결과를 보여주고 바로 진행합니다.
11
+
12
+ ### 사용자 입력이 필요한 경우 (멈추고 질문하고 답변을 기다림)
13
+ - 소스가 2개 이상 감지됨 → "어떤 콘텐츠를 포함할까요?"
14
+ - Org가 1개 이상 있음 → "개인 배포 vs Org 배포?"
15
+ - visibility 옵션이 2개 이상 → "공개 범위를 선택해주세요"
16
+ - 포지셔닝 확인 → 분석 결과를 보여주고 "이대로 진행할까요?"
17
+ - 배포 최종 확인 → relay.yaml 요약을 보여주고 "배포할까요?"
18
+
19
+ **질문 후 반드시 사용자의 답변을 받을 때까지 다음 단계로 넘어가지 마세요.**
20
+ 텍스트로 질문을 출력한 뒤 혼자 답변하고 진행하면 안 됩니다.
21
+
22
+ ### 자동 진행하는 경우 (질문 불필요)
23
+ - 소스가 1개뿐 → 해당 소스 자동 선택, 결과만 보여줌
24
+ - 이미 relay.yaml이 있고 변경사항이 명확함 → 요약 후 진행
25
+ - 로그인이 필요 → 자동으로 `relay login` 실행
26
+
6
27
  ## 분기: 최초 생성 vs 업데이트
7
28
 
8
29
  `.relay/relay.yaml`이 있는지 확인합니다.
@@ -17,7 +38,9 @@ relay.yaml이 없으면 새로 만들고, 있으면 변경사항을 반영합니
17
38
  ### 1. 콘텐츠 파악
18
39
 
19
40
  `relay package --init --json`으로 소스를 스캔합니다.
20
- 결과의 `sources[]`에서 사용자에게 어떤 콘텐츠를 포함할지 물어봅니다.
41
+
42
+ - **소스가 2개 이상** → `sources[]`를 정리하여 보여주고, **사용자에게 질문하여 어떤 콘텐츠를 포함할지 물어봅니다.** 사용자가 답변할 때까지 다음 단계로 넘어가지 마세요.
43
+ - **소스가 1개** → 해당 소스를 자동 선택하고 결과를 보여준 뒤 바로 진행합니다.
21
44
 
22
45
  선택된 콘텐츠의 파일을 직접 읽어 기능을 파악합니다:
23
46
  - SKILL.md, 에이전트 파일, 커맨드 파일의 내용
@@ -35,6 +58,9 @@ relay.yaml이 없으면 새로 만들고, 있으면 변경사항을 반영합니
35
58
  이름(name)은 한국어 가능. slug는 영문 소문자+하이픈.
36
59
  설명은 설치자 관점으로 ("~를 자동화합니다").
37
60
 
61
+ 포지셔닝 결과를 표로 정리하여 보여주고, **사용자에게 질문하여 확인받으세요.**
62
+ ("이 포지셔닝으로 진행할까요? 수정할 부분이 있으면 알려주세요.")
63
+
38
64
  ### 3. requires 판단 + 보안 점검
39
65
 
40
66
  콘텐츠 파일을 읽고 requires를 판단합니다:
@@ -53,22 +79,30 @@ relay.yaml이 없으면 새로 만들고, 있으면 변경사항을 반영합니
53
79
  - 파일 컨텍스트를 읽어 실제 시크릿 vs 예시 코드를 구분
54
80
  - 발견 시 **반드시 경고**하고 환경변수 대체 안내
55
81
 
56
- ### 4. relay.yaml 작성 & 배포
82
+ ### 4. 배포 설정
57
83
 
58
- 판단 결과를 relay.yaml에 반영합니다:
84
+ `relay orgs list --json`으로 Org 목록을 조회합니다.
85
+
86
+ **항상 사용자에게 질문합니다** (AskUserQuestion 등 사용자 입력 도구 사용):
87
+ - **Org가 1개 이상** → "개인 배포 / {org이름}에 배포" 선택
88
+ - **Org가 없음** → "개인 배포 / 새 Organization 만들기" 선택
89
+ - "새 Organization 만들기" 선택 시 → `relay orgs create "이름"` 실행 후 해당 Org에 배포
90
+
91
+ 선택에 따라 **사용자에게 질문하여 visibility를 물어봅니다:**
92
+ - **Org 없이 배포**: `public`, `private` (2개)
93
+ - **Org에 배포**: `public`, `private`, `internal` (3개)
94
+ - `public` — 누구나 설치
95
+ - `private` — 접근 링크가 있는 사람만 설치
96
+ - `internal` — Org 멤버만 설치 (Org 배포 시에만 선택 가능)
97
+
98
+ ### 5. relay.yaml 작성 & 배포
99
+
100
+ 위 결과를 relay.yaml에 반영합니다:
59
101
  - name, slug, description, version, tags
60
102
  - requires (판단 결과)
61
- - org: `relay orgs list --json`으로 Org 목록을 조회합니다.
62
- - Org가 있으면: 개인 배포 vs Org 배포를 사용자에게 물어봅니다.
63
- - Org가 없으면: 개인 배포로 진행합니다.
64
- - visibility: Org 선택 결과에 따라 옵션이 달라집니다:
65
- - **Org 없이 배포**: `public`, `private` (2개)
66
- - **Org에 배포**: `public`, `private`, `internal` (3개)
67
- - `public` — 누구나 설치
68
- - `private` — 접근 링크가 있는 사람만 설치
69
- - `internal` — Org 멤버만 설치 (Org 배포 시에만 선택 가능)
103
+ - org, visibility
70
104
 
71
- `relay publish --json`으로 배포합니다.
105
+ **사용자에게 질문하여 최종 확인** 후 `relay publish --json`으로 배포합니다.
72
106
 
73
107
  ---
74
108
 
@@ -80,7 +114,7 @@ relay.yaml이 없으면 새로 만들고, 있으면 변경사항을 반영합니
80
114
  - 변경된 콘텐츠 (modified)
81
115
  - 새로 추가된 콘텐츠 (new_items)
82
116
 
83
- 사용자에게 어떤 부분을 변경하려는지 물어봅니다:
117
+ **사용자에게 질문하여 어떤 부분을 변경하려는지 물어봅니다:**
84
118
  - 콘텐츠 변경 반영 (sync)
85
119
  - 새 스킬/커맨드 추가
86
120
  - 설명/태그 개선
@@ -96,13 +130,25 @@ relay.yaml이 없으면 새로 만들고, 있으면 변경사항을 반영합니
96
130
 
97
131
  ### 3. 배포
98
132
 
133
+ 변경 요약을 보여주고 **사용자에게 질문하여 최종 확인** 후 배포합니다.
99
134
  `relay publish --json`으로 배포합니다.
100
- 버전 범프가 필요하면 사용자에게 patch/minor/major 중 확인합니다.
135
+ 버전 범프가 필요하면 사용자에게 질문하여 patch/minor/major 중 확인합니다.
101
136
 
102
137
  ---
103
138
 
104
- ## 공유 문구
139
+ ## 배포 완료 후 공유 안내
140
+
141
+ `relay publish --json` 출력 결과를 파싱하여 다음을 보여주세요:
105
142
 
106
- 배포 완료 `relay publish` 출력에 포함된 공유 문구를 보여줍니다.
143
+ 1. **배포 결과 요약** slug, 버전, 공개 범위, URL
144
+ 2. **설치 방법** — CLI 출력에 코드블록 형태로 이미 포함되어 있으므로, 그 내용을 사용자에게 안내합니다:
145
+ - CLI: `npx relayax-cli install {slug}`
146
+ - 출력에 `plugin_url`이 있으면 Claude Code Plugin:
147
+ ```
148
+ /plugin marketplace add {pluginUrl}
149
+ /plugin install {slug}
150
+ ```
151
+ - 에이전트 소개 페이지 URL
152
+ 3. **공유 텍스트** — CLI 출력의 공유 블록(┌─ ... ─┘)을 그대로 안내합니다. 팀에 바로 복붙할 수 있는 코드블록 형태입니다.
107
153
 
108
154
  {{ERROR_HANDLING_GUIDE}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "relayax-cli",
3
- "version": "0.4.13",
3
+ "version": "0.4.15",
4
4
  "description": "RelayAX Agent Team Marketplace CLI - Install and manage agent teams",
5
5
  "main": "dist/index.js",
6
6
  "bin": {