relayax-cli 0.3.49 → 0.3.51
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.
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
+
interface CommandEntry {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
}
|
|
6
|
+
interface Components {
|
|
7
|
+
agents: number;
|
|
8
|
+
rules: number;
|
|
9
|
+
skills: number;
|
|
10
|
+
}
|
|
2
11
|
export interface RequiresCli {
|
|
3
12
|
name: string;
|
|
4
13
|
install?: string;
|
|
@@ -35,4 +44,49 @@ export interface Requires {
|
|
|
35
44
|
};
|
|
36
45
|
permissions?: string[];
|
|
37
46
|
}
|
|
47
|
+
interface AgentDetail {
|
|
48
|
+
name: string;
|
|
49
|
+
description: string;
|
|
50
|
+
uses: string[];
|
|
51
|
+
}
|
|
52
|
+
interface SkillDetail {
|
|
53
|
+
name: string;
|
|
54
|
+
description: string;
|
|
55
|
+
uses: string[];
|
|
56
|
+
}
|
|
57
|
+
export interface PublishMetadata {
|
|
58
|
+
slug: string;
|
|
59
|
+
name: string;
|
|
60
|
+
description: string;
|
|
61
|
+
long_description?: string;
|
|
62
|
+
tags: string[];
|
|
63
|
+
commands: CommandEntry[];
|
|
64
|
+
components: Components;
|
|
65
|
+
version: string;
|
|
66
|
+
changelog?: string;
|
|
67
|
+
requires?: Requires;
|
|
68
|
+
visibility?: 'public' | 'private' | 'internal';
|
|
69
|
+
type?: 'command' | 'passive' | 'hybrid';
|
|
70
|
+
cli_version?: string;
|
|
71
|
+
agent_names?: string[];
|
|
72
|
+
skill_names?: string[];
|
|
73
|
+
agent_details?: AgentDetail[];
|
|
74
|
+
skill_details?: SkillDetail[];
|
|
75
|
+
org_slug?: string;
|
|
76
|
+
}
|
|
77
|
+
export declare function createTarball(agentDir: string): Promise<string>;
|
|
78
|
+
interface PublishResult {
|
|
79
|
+
status: string;
|
|
80
|
+
slug: string;
|
|
81
|
+
version: string;
|
|
82
|
+
url: string;
|
|
83
|
+
profile?: {
|
|
84
|
+
username?: string;
|
|
85
|
+
display_name?: string;
|
|
86
|
+
contact_links?: Record<string, string>;
|
|
87
|
+
default_welcome?: string;
|
|
88
|
+
} | null;
|
|
89
|
+
}
|
|
90
|
+
export declare function publishToApi(token: string, tarPath: string, metadata: PublishMetadata): Promise<PublishResult>;
|
|
38
91
|
export declare function registerPublish(program: Command): void;
|
|
92
|
+
export {};
|
package/dist/commands/publish.js
CHANGED
|
@@ -3,6 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createTarball = createTarball;
|
|
7
|
+
exports.publishToApi = publishToApi;
|
|
6
8
|
exports.registerPublish = registerPublish;
|
|
7
9
|
const fs_1 = __importDefault(require("fs"));
|
|
8
10
|
const path_1 = __importDefault(require("path"));
|
package/dist/lib/ai-tools.js
CHANGED
|
@@ -33,9 +33,11 @@ exports.AI_TOOLS = [
|
|
|
33
33
|
{ name: 'Factory Droid', value: 'factory', skillsDir: '.factory' },
|
|
34
34
|
{ name: 'Gemini CLI', value: 'gemini', skillsDir: '.gemini' },
|
|
35
35
|
{ name: 'GitHub Copilot', value: 'github-copilot', skillsDir: '.github' },
|
|
36
|
+
{ name: 'Hermes Agent', value: 'hermes', skillsDir: '.hermes' },
|
|
36
37
|
{ name: 'iFlow', value: 'iflow', skillsDir: '.iflow' },
|
|
37
38
|
{ name: 'Kilo Code', value: 'kilocode', skillsDir: '.kilocode' },
|
|
38
39
|
{ name: 'Kiro', value: 'kiro', skillsDir: '.kiro' },
|
|
40
|
+
{ name: 'OpenClaw', value: 'openclaw', skillsDir: '.openclaw' },
|
|
39
41
|
{ name: 'OpenCode', value: 'opencode', skillsDir: '.opencode' },
|
|
40
42
|
{ name: 'Pi', value: 'pi', skillsDir: '.pi' },
|
|
41
43
|
{ name: 'Qoder', value: 'qoder', skillsDir: '.qoder' },
|
|
@@ -13,6 +13,36 @@ exports.formatCommandFile = formatCommandFile;
|
|
|
13
13
|
const os_1 = __importDefault(require("os"));
|
|
14
14
|
const path_1 = __importDefault(require("path"));
|
|
15
15
|
const index_js_1 = require("../prompts/index.js");
|
|
16
|
+
/**
|
|
17
|
+
* 환경 감지 프리앰블.
|
|
18
|
+
* slash command 실행 시 MCP tool 사용 가능 여부를 먼저 판별하여,
|
|
19
|
+
* 이후 모든 CLI 명령어를 적절한 방식으로 실행하도록 안내.
|
|
20
|
+
*/
|
|
21
|
+
const ENV_PREAMBLE = `## 환경 감지
|
|
22
|
+
|
|
23
|
+
이 커맨드를 실행하기 전에 환경을 판별하세요:
|
|
24
|
+
|
|
25
|
+
1. **relay MCP tool 사용 가능 여부 확인**: relay_status 같은 relay MCP tool을 호출할 수 있는지 확인하세요.
|
|
26
|
+
- 사용 가능 → **MCP 모드**로 실행 (아래 표 참고)
|
|
27
|
+
- 사용 불가 → **CLI 모드**로 실행 (bash 명령어 그대로 사용)
|
|
28
|
+
|
|
29
|
+
2. MCP 모드에서의 명령어 변환:
|
|
30
|
+
|
|
31
|
+
| CLI 명령어 | MCP tool |
|
|
32
|
+
|---|---|
|
|
33
|
+
| \`relay status\` | \`relay_status\` tool 호출 |
|
|
34
|
+
| \`relay list --json\` | \`relay_list\` tool 호출 |
|
|
35
|
+
| \`relay search <keyword>\` | \`relay_search\` tool 호출 |
|
|
36
|
+
| \`relay install <slug>\` | \`relay_install\` tool 호출 |
|
|
37
|
+
| \`relay uninstall <slug>\` | \`relay_uninstall\` tool 호출 |
|
|
38
|
+
| \`relay package --init\` | \`relay_scan\` tool 호출 |
|
|
39
|
+
| \`relay publish\` | \`relay_publish\` tool 호출 |
|
|
40
|
+
|
|
41
|
+
**중요**: 이후 지시에서 \`relay <명령어>\`로 표기된 것은 판별된 환경에 따라 변환하여 실행하세요.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
`;
|
|
16
46
|
/**
|
|
17
47
|
* 로컬 어댑터 — 프로젝트 디렉토리 기준.
|
|
18
48
|
* {projectPath}/{skillsDir}/commands/relay/{id}.md
|
|
@@ -66,12 +96,12 @@ exports.USER_COMMANDS = [
|
|
|
66
96
|
{
|
|
67
97
|
id: 'relay-install',
|
|
68
98
|
description: 'relay에서 에이전트를 설치합니다',
|
|
69
|
-
body: index_js_1.INSTALL_PROMPT,
|
|
99
|
+
body: ENV_PREAMBLE + index_js_1.INSTALL_PROMPT,
|
|
70
100
|
},
|
|
71
101
|
{
|
|
72
102
|
id: 'relay-status',
|
|
73
103
|
description: '설치된 에이전트와 Organization 현황을 확인합니다',
|
|
74
|
-
body: `현재 설치된 에이전트와 소속 Organization 현황을 한눈에 보여줍니다.
|
|
104
|
+
body: ENV_PREAMBLE + `현재 설치된 에이전트와 소속 Organization 현황을 한눈에 보여줍니다.
|
|
75
105
|
|
|
76
106
|
## 실행 방법
|
|
77
107
|
|
|
@@ -160,7 +190,7 @@ ${index_js_1.ERROR_HANDLING_GUIDE}
|
|
|
160
190
|
{
|
|
161
191
|
id: 'relay-uninstall',
|
|
162
192
|
description: '설치된 에이전트를 삭제합니다',
|
|
163
|
-
body: `설치된 에이전트를 제거합니다. CLI가 패키지와 배치된 파일을 모두 정리합니다.
|
|
193
|
+
body: ENV_PREAMBLE + `설치된 에이전트를 제거합니다. CLI가 패키지와 배치된 파일을 모두 정리합니다.
|
|
164
194
|
|
|
165
195
|
## 실행 방법
|
|
166
196
|
|
|
@@ -181,7 +211,7 @@ ${index_js_1.ERROR_HANDLING_GUIDE}
|
|
|
181
211
|
{
|
|
182
212
|
id: 'relay-publish',
|
|
183
213
|
description: '현재 에이전트 패키지를 relay에 배포합니다',
|
|
184
|
-
body: index_js_1.PUBLISH_PROMPT,
|
|
214
|
+
body: ENV_PREAMBLE + index_js_1.PUBLISH_PROMPT,
|
|
185
215
|
},
|
|
186
216
|
];
|
|
187
217
|
// ─── Builder Commands (로컬 설치) ───
|
package/dist/mcp/server.js
CHANGED
|
@@ -16,6 +16,7 @@ const ai_tools_js_1 = require("../lib/ai-tools.js");
|
|
|
16
16
|
const preamble_js_1 = require("../lib/preamble.js");
|
|
17
17
|
const installer_js_1 = require("../lib/installer.js");
|
|
18
18
|
const paths_js_1 = require("../lib/paths.js");
|
|
19
|
+
// prompts are used in MCP Prompt definitions below
|
|
19
20
|
const fs_1 = __importDefault(require("fs"));
|
|
20
21
|
const path_1 = __importDefault(require("path"));
|
|
21
22
|
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
@@ -161,7 +162,30 @@ function createMcpServer() {
|
|
|
161
162
|
}
|
|
162
163
|
catch { /* skip */ }
|
|
163
164
|
}
|
|
164
|
-
|
|
165
|
+
// 버전 확인
|
|
166
|
+
const { checkCliVersion } = await import('../lib/version-check.js');
|
|
167
|
+
const cliUpdate = await checkCliVersion(true);
|
|
168
|
+
return { content: [jsonText({
|
|
169
|
+
cli: { version: pkg.version, update_available: cliUpdate ? cliUpdate.latest : null },
|
|
170
|
+
login: { authenticated: !!token, username },
|
|
171
|
+
agent_clis: detected.map((t) => t.name),
|
|
172
|
+
mounted_paths: mounted.map((m) => m.basePath),
|
|
173
|
+
project,
|
|
174
|
+
})] };
|
|
175
|
+
});
|
|
176
|
+
server.tool('relay_check_update', 'CLI 및 에이전트 업데이트를 확인합니다', {}, async () => {
|
|
177
|
+
const { checkCliVersion, checkAllAgents } = await import('../lib/version-check.js');
|
|
178
|
+
const cliUpdate = await checkCliVersion(true);
|
|
179
|
+
const agentUpdates = await checkAllAgents(true);
|
|
180
|
+
const updates = [];
|
|
181
|
+
if (cliUpdate)
|
|
182
|
+
updates.push({ type: 'cli', current: cliUpdate.current, latest: cliUpdate.latest });
|
|
183
|
+
for (const u of agentUpdates)
|
|
184
|
+
updates.push({ type: 'agent', slug: u.slug, current: u.current, latest: u.latest });
|
|
185
|
+
if (updates.length === 0) {
|
|
186
|
+
return { content: [jsonText({ status: 'up_to_date', message: '모두 최신 버전입니다.', cli_version: pkg.version })] };
|
|
187
|
+
}
|
|
188
|
+
return { content: [jsonText({ status: 'updates_available', updates, message: 'CLI를 업데이트하려면: npm update -g relayax-cli' })] };
|
|
165
189
|
});
|
|
166
190
|
server.tool('relay_scan', '배포 가능한 스킬/에이전트/커맨드를 스캔합니다', {
|
|
167
191
|
project_path: zod_1.z.string().optional().describe('프로젝트 경로'),
|
|
@@ -190,73 +214,61 @@ function createMcpServer() {
|
|
|
190
214
|
}
|
|
191
215
|
return { content: [jsonText({ sources })] };
|
|
192
216
|
});
|
|
193
|
-
server.tool('relay_publish', '에이전트를 마켓플레이스에 배포합니다', {
|
|
194
|
-
project_path: zod_1.z.string().optional().describe('프로젝트 경로'),
|
|
217
|
+
server.tool('relay_publish', '에이전트를 마켓플레이스에 배포합니다 (.relay/ 디렉토리를 tar로 패키징하여 업로드)', {
|
|
218
|
+
project_path: zod_1.z.string().optional().describe('프로젝트 경로 (.relay/relay.yaml이 있는 디렉토리)'),
|
|
195
219
|
}, async ({ project_path }) => {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
220
|
+
try {
|
|
221
|
+
const projectPath = project_path ?? (0, paths_js_1.resolveProjectPath)();
|
|
222
|
+
const relayDir = path_1.default.join(projectPath, '.relay');
|
|
223
|
+
const relayYaml = path_1.default.join(relayDir, 'relay.yaml');
|
|
224
|
+
if (!fs_1.default.existsSync(relayYaml)) {
|
|
225
|
+
return { content: [jsonText({ error: 'NOT_INITIALIZED', message: '.relay/relay.yaml이 없습니다.' })], isError: true };
|
|
226
|
+
}
|
|
227
|
+
const token = await (0, config_js_1.getValidToken)();
|
|
228
|
+
if (!token) {
|
|
229
|
+
return { content: [jsonText({ error: 'LOGIN_REQUIRED', message: '배포하려면 로그인이 필요합니다.' })], isError: true };
|
|
230
|
+
}
|
|
231
|
+
const cfg = js_yaml_1.default.load(fs_1.default.readFileSync(relayYaml, 'utf-8'));
|
|
232
|
+
const { createTarball, publishToApi } = await import('../commands/publish.js');
|
|
233
|
+
const tarPath = await createTarball(relayDir);
|
|
234
|
+
try {
|
|
235
|
+
const metadata = {
|
|
236
|
+
slug: cfg.slug,
|
|
237
|
+
name: cfg.name,
|
|
238
|
+
description: cfg.description ?? '',
|
|
239
|
+
tags: cfg.tags ?? [],
|
|
240
|
+
commands: [],
|
|
241
|
+
components: { skills: 0, agents: 0, rules: 0, commands: 0 },
|
|
242
|
+
version: cfg.version,
|
|
243
|
+
visibility: cfg.visibility ?? 'public',
|
|
244
|
+
cli_version: pkg.version,
|
|
245
|
+
};
|
|
246
|
+
const result = await publishToApi(token, tarPath, metadata);
|
|
247
|
+
return { content: [jsonText(result)] };
|
|
248
|
+
}
|
|
249
|
+
finally {
|
|
250
|
+
fs_1.default.unlinkSync(tarPath);
|
|
251
|
+
}
|
|
200
252
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
253
|
+
catch (err) {
|
|
254
|
+
return { content: [jsonText({ error: String(err) })], isError: true };
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
// ═══ relay_init — slash command 설치 ═══
|
|
258
|
+
server.tool('relay_init', 'relay slash command를 설치합니다 (/relay-install, /relay-publish 등)', {}, async () => {
|
|
259
|
+
try {
|
|
260
|
+
const { installGlobalUserCommands, hasGlobalUserCommands } = await import('../commands/init.js');
|
|
261
|
+
if (hasGlobalUserCommands()) {
|
|
262
|
+
installGlobalUserCommands(); // 업데이트
|
|
263
|
+
return { content: [jsonText({ status: 'updated', message: 'relay slash command가 업데이트되었습니다.' })] };
|
|
264
|
+
}
|
|
265
|
+
installGlobalUserCommands();
|
|
266
|
+
return { content: [jsonText({ status: 'installed', message: 'relay slash command가 설치되었습니다. /relay-install, /relay-publish 등을 사용할 수 있습니다.' })] };
|
|
267
|
+
}
|
|
268
|
+
catch (err) {
|
|
269
|
+
return { content: [jsonText({ error: String(err) })], isError: true };
|
|
204
270
|
}
|
|
205
|
-
const cfg = js_yaml_1.default.load(fs_1.default.readFileSync(relayYaml, 'utf-8'));
|
|
206
|
-
return { content: [jsonText({ status: 'ready', project_path: projectPath, name: cfg.name, slug: cfg.slug, version: cfg.version, message: '배포 준비 완료. relay-publish 프롬프트로 전체 워크플로우를 실행하세요.' })] };
|
|
207
271
|
});
|
|
208
|
-
// ═══ Prompts ═══
|
|
209
|
-
server.prompt('relay-install', '에이전트 검색 → 설치 가이드 워크플로우', {}, () => ({
|
|
210
|
-
messages: [{
|
|
211
|
-
role: 'user',
|
|
212
|
-
content: { type: 'text', text: `다음 가이드를 따라 에이전트를 설치하세요. relay MCP tool을 사용하여 각 단계를 실행합니다.
|
|
213
|
-
|
|
214
|
-
사용 가능한 tool: relay_status, relay_search, relay_install, relay_list, relay_status
|
|
215
|
-
|
|
216
|
-
## 워크플로우
|
|
217
|
-
|
|
218
|
-
1. relay_status로 로그인 상태 확인. 미인증이면 사용자에게 터미널에서 \`npx relayax-cli login --device\` 실행을 안내.
|
|
219
|
-
2. 사용자에게 어떤 에이전트를 찾는지 물어보기.
|
|
220
|
-
3. relay_search로 검색.
|
|
221
|
-
4. 검색 결과를 보여주고 선택하게 하기.
|
|
222
|
-
5. relay_install로 설치.
|
|
223
|
-
6. 설치 결과와 사용법 안내.` },
|
|
224
|
-
}],
|
|
225
|
-
}));
|
|
226
|
-
server.prompt('relay-publish', '에이전트 배포 가이드 워크플로우', {}, () => ({
|
|
227
|
-
messages: [{
|
|
228
|
-
role: 'user',
|
|
229
|
-
content: { type: 'text', text: `다음 가이드를 따라 에이전트를 배포하세요. relay MCP tool을 사용합니다.
|
|
230
|
-
|
|
231
|
-
사용 가능한 tool: relay_status, relay_scan, relay_status, relay_publish
|
|
232
|
-
|
|
233
|
-
## 워크플로우
|
|
234
|
-
|
|
235
|
-
1. relay_status로 로그인 상태 확인. 미인증이면 터미널에서 \`npx relayax-cli login --device\` 안내.
|
|
236
|
-
2. relay_scan으로 배포 가능한 스킬/에이전트/커맨드 목록 스캔.
|
|
237
|
-
3. 스캔 결과를 보여주고 사용자에게 어떤 항목을 배포할지 선택하게 하기.
|
|
238
|
-
4. relay_status로 프로젝트 상태 확인. .relay/relay.yaml이 없으면 프로젝트 생성 안내.
|
|
239
|
-
5. relay_publish로 배포.
|
|
240
|
-
6. 배포 결과를 사용자에게 보여주기.` },
|
|
241
|
-
}],
|
|
242
|
-
}));
|
|
243
|
-
server.prompt('relay-status', '환경 상태 확인', {}, () => ({
|
|
244
|
-
messages: [{
|
|
245
|
-
role: 'user',
|
|
246
|
-
content: { type: 'text', text: 'relay_status, relay_status, relay_list, relay_scan tool을 사용하여 현재 relay 환경 상태를 확인하고 사용자에게 보여주세요. 로그인 상태, 감지된 AI 도구, 프로젝트 정보, 설치된 에이전트, 배포 가능한 스킬 목록을 포함합니다.' },
|
|
247
|
-
}],
|
|
248
|
-
}));
|
|
249
|
-
server.prompt('relay-uninstall', '에이전트 제거 가이드', {}, () => ({
|
|
250
|
-
messages: [{
|
|
251
|
-
role: 'user',
|
|
252
|
-
content: { type: 'text', text: `다음 워크플로우를 따라 에이전트를 제거하세요:
|
|
253
|
-
|
|
254
|
-
1. relay_list로 설치된 에이전트 목록 표시.
|
|
255
|
-
2. 사용자에게 제거할 에이전트 선택하게 하기.
|
|
256
|
-
3. relay_uninstall로 제거.
|
|
257
|
-
4. 결과 보여주기.` },
|
|
258
|
-
}],
|
|
259
|
-
}));
|
|
260
272
|
return server;
|
|
261
273
|
}
|
|
262
274
|
// ─── Start ───
|
|
@@ -16,17 +16,49 @@ npm install -g relayax-cli 2>/dev/null && echo "install-ok" || echo "sandbox"
|
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
- `install-ok` → **환경 A (터미널)** (`relay init` 실행 후 Step 1로)
|
|
19
|
-
- `sandbox` → **환경 B (샌드박스)** —
|
|
19
|
+
- `sandbox` → **환경 B (샌드박스)** — 아래 MCP 설정으로 진행
|
|
20
|
+
|
|
21
|
+
### 환경 B: MCP Connector 자동 설정 (샌드박스)
|
|
22
|
+
|
|
23
|
+
샌드박스 환경(Cowork 등)에서는 네트워크가 제한되어 CLI로 직접 API 호출이 불가합니다.
|
|
24
|
+
대신 relay MCP 서버를 설정하면, 호스트 머신에서 API를 호출할 수 있습니다.
|
|
25
|
+
|
|
26
|
+
**relay MCP tool(`relay_status` 등)을 사용할 수 있는지 확인하세요.**
|
|
27
|
+
사용할 수 있다면 MCP가 이미 설정되어 있으므로 바로 Step 1로 진행합니다.
|
|
28
|
+
|
|
29
|
+
사용할 수 없다면 아래 절차로 MCP를 설정합니다:
|
|
30
|
+
|
|
31
|
+
1. Claude Desktop 설정 파일을 찾아 읽습니다:
|
|
32
|
+
```bash
|
|
33
|
+
cat ~/Library/Application\ Support/Claude/claude_desktop_config.json 2>/dev/null || echo "{}"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
2. 설정 파일에 아래 relay MCP 서버를 추가합니다 (기존 mcpServers가 있으면 거기에 추가, 없으면 새로 생성):
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"mcpServers": {
|
|
40
|
+
"relay": {
|
|
41
|
+
"command": "npx",
|
|
42
|
+
"args": ["relayax-cli", "mcp"]
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
3. 사용자에게 **Claude Desktop을 재시작**해달라고 안내합니다.
|
|
49
|
+
|
|
50
|
+
4. 재시작 후 `relay_status` MCP tool이 사용 가능한지 확인합니다. 사용 가능하면 Step 1로 진행합니다.
|
|
20
51
|
|
|
21
52
|
### 환경별 실행 방법
|
|
22
53
|
|
|
23
54
|
이후 가이드의 모든 `relay <명령어>`는 감지된 환경에 따라 실행합니다:
|
|
24
55
|
|
|
25
|
-
| 가이드 지시 | A. 터미널 | B. 샌드박스 |
|
|
56
|
+
| 가이드 지시 | A. 터미널 | B. 샌드박스 (MCP) |
|
|
26
57
|
|---|---|---|
|
|
27
|
-
| "relay status" | `relay status` | `
|
|
28
|
-
| "relay install X" | `relay install X` | `
|
|
29
|
-
| "relay publish" | `relay publish` | `
|
|
30
|
-
| "relay login" | `relay login` | `npx relayax-cli login --device` |
|
|
58
|
+
| "relay status" | `relay status` | `relay_status` tool 호출 |
|
|
59
|
+
| "relay install X" | `relay install X` | `relay_install` tool 호출 (`slug: "X"`) |
|
|
60
|
+
| "relay publish" | `relay publish` | `relay_publish` tool 호출 |
|
|
61
|
+
| "relay login" | `relay login` | 사용자에게 터미널에서 `npx relayax-cli login --device` 안내 |
|
|
62
|
+
| "relay scan" | `relay package --init` | `relay_scan` tool 호출 |
|
|
31
63
|
|
|
32
64
|
처음 판별한 환경을 이후 계속 사용합니다.
|