relayax-cli 0.4.20 → 0.4.22

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.
@@ -22,8 +22,7 @@ function registerInstall(program) {
22
22
  program
23
23
  .command('install <slug>')
24
24
  .description('에이전트 패키지를 .relay/agents/에 다운로드합니다')
25
- .option('--join-code <code>', '초대 코드 (Organization 에이전트 설치 시 자동 가입)')
26
- .option('--code <code>', '접근 코드 (private 에이전트 설치 시)')
25
+ .option('--code <code>', '접근 코드 (비공개/내부 에이전트 설치 시)')
27
26
  .option('--global', '글로벌 설치 (홈 디렉토리)')
28
27
  .option('--local', '로컬 설치 (프로젝트 디렉토리)')
29
28
  .option('--project <dir>', '프로젝트 루트 경로 (기본: cwd, 환경변수: RELAY_PROJECT_PATH)')
@@ -66,8 +65,8 @@ function registerInstall(program) {
66
65
  }
67
66
  return token ?? null;
68
67
  }
69
- // Pre-fetch auto-login: --join-code and --code always require auth.
70
- if (_opts.joinCode || _opts.code) {
68
+ // Pre-fetch auto-login: --code always requires auth.
69
+ if (_opts.code) {
71
70
  const token = await ensureToken();
72
71
  if (!token) {
73
72
  if (json) {
@@ -103,19 +102,10 @@ function registerInstall(program) {
103
102
  }
104
103
  }
105
104
  catch { /* ignore parse errors */ }
106
- // Task 2.1: --join-code provided and not yet a member join org then retry
107
- if (_opts.joinCode && membershipStatus !== 'member') {
105
+ // --code provided use unified access-codes API (handles both org join and agent grant)
106
+ if (_opts.code) {
108
107
  if (!json) {
109
- console.error('\x1b[33m⚙ 초대 코드로 Organization에 가입합니다...\x1b[0m');
110
- }
111
- const { joinOrg } = await import('./join.js');
112
- await joinOrg(parsed.owner, _opts.joinCode);
113
- agent = await (0, api_js_1.fetchAgentInfo)(slug);
114
- }
115
- // Task 2.2: --code provided and agent is private → claim access then retry
116
- else if (_opts.code && (errorVisibility === 'private' || purchaseInfo)) {
117
- if (!json) {
118
- console.error('\x1b[33m⚙ 접근 코드로 에이전트 접근 권한을 요청합니다...\x1b[0m');
108
+ console.error('\x1b[33m⚙ 접근 코드로 권한을 요청합니다...\x1b[0m');
119
109
  }
120
110
  const token = await (0, config_js_1.getValidToken)();
121
111
  if (!token) {
@@ -132,21 +122,20 @@ function registerInstall(program) {
132
122
  }
133
123
  process.exit(1);
134
124
  }
135
- const claimRes = await fetch(`${config_js_1.API_URL}/api/agents/${parsed.name}/claim-access`, {
125
+ const codeRes = await fetch(`${config_js_1.API_URL}/api/access-codes/${_opts.code}/use`, {
136
126
  method: 'POST',
137
127
  headers: {
138
128
  'Content-Type': 'application/json',
139
129
  Authorization: `Bearer ${token}`,
140
130
  },
141
- body: JSON.stringify({ code: _opts.code, owner: parsed.owner }),
142
131
  signal: AbortSignal.timeout(10000),
143
132
  });
144
- if (!claimRes.ok) {
145
- const claimBody = (await claimRes.json().catch(() => ({})));
146
- const claimErrCode = claimBody.error ?? String(claimRes.status);
147
- if (claimErrCode === 'INVALID_LINK')
148
- throw new Error('초대 링크가 유효하지 않거나 만료되었습니다.');
149
- throw new Error(claimBody.message ?? `접근 권한 요청 실패 (${claimRes.status})`);
133
+ if (!codeRes.ok) {
134
+ const codeBody = (await codeRes.json().catch(() => ({})));
135
+ const codeErrCode = codeBody.error ?? String(codeRes.status);
136
+ if (codeErrCode === 'INVALID_LINK')
137
+ throw new Error('접근 코드가 유효하지 않거나 만료되었습니다.');
138
+ throw new Error(codeBody.message ?? `접근 권한 요청 실패 (${codeRes.status})`);
150
139
  }
151
140
  agent = await (0, api_js_1.fetchAgentInfo)(slug);
152
141
  }
@@ -195,12 +184,12 @@ function registerInstall(program) {
195
184
  error: 'ACCESS_REQUIRED',
196
185
  message: '이 에이전트는 접근 권한이 필요합니다.',
197
186
  slug,
198
- fix: '초대 코드가 있으면 `relay install ' + slugInput + ' --join-code <코드>`로 가입하세요.',
187
+ fix: '접근 코드가 있으면 `relay install ' + slugInput + ' --code <코드>`로 설치하세요.',
199
188
  }));
200
189
  }
201
190
  else {
202
191
  console.error('\x1b[31m이 에이전트는 접근 권한이 필요합니다.\x1b[0m');
203
- console.error('\x1b[33m초대 코드가 있으면 `relay install ' + slugInput + ' --join-code <코드>`로 가입하세요.\x1b[0m');
192
+ console.error('\x1b[33m접근 코드가 있으면 `relay install ' + slugInput + ' --code <코드>`로 설치하세요.\x1b[0m');
204
193
  }
205
194
  process.exit(1);
206
195
  }
@@ -632,37 +632,36 @@ function registerPublish(program) {
632
632
  internal: '내부',
633
633
  };
634
634
  const currentVisLabel = visLabelMap[config.visibility ?? 'public'] ?? config.visibility;
635
- const confirmVisChoices = hasOrg
636
- ? [
637
- {
638
- name: `공개 — 조직 밖의 누구나 사용 가능${defaultVisibility === 'public' ? ' ✓ 추천' : ''}`,
639
- value: 'public',
640
- },
641
- {
642
- name: '비공개 조직 내의 허가된 사용자만 사용 가능',
643
- value: 'private',
644
- },
645
- ]
646
- : [
647
- {
648
- name: `공개 — 누구나 검색 및 설치 가능${defaultVisibility === 'public' ? ' ✓ 추천' : ''}`,
649
- value: 'public',
650
- },
651
- {
652
- name: '비공개 — 허가 코드 등록자만 사용 가능',
653
- value: 'private',
654
- },
655
- ];
656
- if (hasOrg) {
635
+ const currentVis = config.visibility ?? defaultVisibility;
636
+ const confirmVisChoices = [
637
+ {
638
+ name: `${currentVisLabel} 유지`,
639
+ value: currentVis,
640
+ },
641
+ ];
642
+ // 나머지 옵션 추가 (현재 제외)
643
+ if (currentVis !== 'public') {
644
+ confirmVisChoices.push({
645
+ name: hasOrg ? '공개 — 조직 밖의 누구나 사용 가능' : '공개 — 누구나 검색 및 설치 가능',
646
+ value: 'public',
647
+ });
648
+ }
649
+ if (currentVis !== 'private') {
650
+ confirmVisChoices.push({
651
+ name: hasOrg ? '비공개 — 조직 내의 허가된 사용자만 사용 가능' : '비공개 — 허가 코드 등록자만 사용 가능',
652
+ value: 'private',
653
+ });
654
+ }
655
+ if (hasOrg && currentVis !== 'internal') {
657
656
  confirmVisChoices.push({
658
657
  name: '내부 — 조직 내의 누구나 사용 가능',
659
658
  value: 'internal',
660
659
  });
661
660
  }
662
661
  const newVisibility = await promptConfirmVis({
663
- message: `공개 범위: ${currentVisLabel} — 유지하거나 변경하세요`,
662
+ message: `공개 범위: ${currentVisLabel}`,
664
663
  choices: confirmVisChoices,
665
- default: config.visibility ?? defaultVisibility,
664
+ default: currentVis,
666
665
  });
667
666
  if (newVisibility !== config.visibility) {
668
667
  config.visibility = newVisibility;
@@ -832,10 +831,7 @@ function registerPublish(program) {
832
831
  // npx turnkey install command (works everywhere, no pre-install needed)
833
832
  const visibility = config.visibility ?? 'public';
834
833
  let npxInstallCmd;
835
- if (visibility === 'internal' && accessCode) {
836
- npxInstallCmd = `npx relayax-cli install ${result.slug} --join-code ${accessCode}`;
837
- }
838
- else if (visibility === 'private' && accessCode) {
834
+ if ((visibility === 'internal' || visibility === 'private') && accessCode) {
839
835
  npxInstallCmd = `npx relayax-cli install ${result.slug} --code ${accessCode}`;
840
836
  }
841
837
  else {
package/dist/index.js CHANGED
@@ -65,4 +65,12 @@ program
65
65
  .action(async () => {
66
66
  await (0, server_js_1.startMcpServer)();
67
67
  });
68
+ // 모든 명령 실행 전 버전 표시 (--json, mcp, --version, --help 제외)
69
+ program.hook('preAction', (_thisCommand, actionCommand) => {
70
+ const isJson = program.opts().json ?? false;
71
+ const isMcp = actionCommand.name() === 'mcp';
72
+ if (!isJson && !isMcp && process.stderr.isTTY) {
73
+ process.stderr.write(`\x1b[2mrelay v${pkg.version}\x1b[0m\n`);
74
+ }
75
+ });
68
76
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "relayax-cli",
3
- "version": "0.4.20",
3
+ "version": "0.4.22",
4
4
  "description": "RelayAX Agent Team Marketplace CLI - Install and manage agent teams",
5
5
  "main": "dist/index.js",
6
6
  "bin": {