relayax-cli 0.2.40 → 0.3.41
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/dist/commands/diff.d.ts +2 -0
- package/dist/commands/diff.js +72 -0
- package/dist/commands/install.js +73 -205
- package/dist/commands/join.d.ts +3 -2
- package/dist/commands/join.js +18 -69
- package/dist/commands/list.js +18 -21
- package/dist/commands/orgs.d.ts +10 -0
- package/dist/commands/orgs.js +128 -0
- package/dist/commands/package.d.ts +2 -0
- package/dist/commands/package.js +287 -0
- package/dist/commands/publish.js +63 -58
- package/dist/commands/search.js +1 -1
- package/dist/commands/spaces.d.ts +0 -1
- package/dist/commands/versions.d.ts +2 -0
- package/dist/commands/versions.js +44 -0
- package/dist/index.js +8 -2
- package/dist/lib/api.d.ts +7 -6
- package/dist/lib/api.js +14 -29
- package/dist/lib/command-adapter.js +147 -51
- package/dist/lib/config.d.ts +9 -4
- package/dist/lib/config.js +105 -23
- package/dist/lib/guide.d.ts +13 -5
- package/dist/lib/guide.js +142 -50
- package/dist/lib/preamble.js +3 -4
- package/dist/lib/slug.d.ts +0 -1
- package/dist/lib/slug.js +3 -7
- package/dist/types.d.ts +2 -2
- package/package.json +1 -1
package/dist/lib/guide.js
CHANGED
|
@@ -1,52 +1,144 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* GUIDE.html 생성 프롬프트 템플릿.
|
|
4
|
-
* publish slash command에서 Claude Code가 이 프롬프트를 읽고 GUIDE.html을 생성한다.
|
|
5
|
-
*/
|
|
6
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
3
|
+
exports.generateGuide = generateGuide;
|
|
4
|
+
function buildSetupSection(needsLogin) {
|
|
5
|
+
const installStep = `## Step 1. Relay CLI 설치
|
|
6
|
+
|
|
7
|
+
relay CLI가 설치되어 있지 않다면:
|
|
8
|
+
|
|
9
|
+
\`\`\`bash
|
|
10
|
+
npm install -g relayax-cli
|
|
11
|
+
\`\`\`
|
|
12
|
+
|
|
13
|
+
Node.js가 없는 경우:
|
|
14
|
+
- macOS: \`brew install node\`
|
|
15
|
+
- Windows: \`winget install OpenJS.NodeJS.LTS\`
|
|
16
|
+
- Linux: \`curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash && source ~/.bashrc && nvm install --lts\`
|
|
17
|
+
|
|
18
|
+
npm 권한 오류 시:
|
|
19
|
+
\`\`\`bash
|
|
20
|
+
mkdir -p ~/.npm-global && npm config set prefix '~/.npm-global'
|
|
21
|
+
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.zshrc && source ~/.zshrc
|
|
22
|
+
npm install -g relayax-cli
|
|
23
|
+
\`\`\``;
|
|
24
|
+
if (!needsLogin)
|
|
25
|
+
return installStep;
|
|
26
|
+
return `${installStep}
|
|
27
|
+
|
|
28
|
+
## Step 2. 로그인
|
|
29
|
+
|
|
30
|
+
\`\`\`bash
|
|
31
|
+
relay login
|
|
32
|
+
\`\`\`
|
|
33
|
+
|
|
34
|
+
브라우저가 열리면 GitHub 또는 카카오 계정으로 로그인하세요.`;
|
|
35
|
+
}
|
|
36
|
+
function buildRequiresSection(requires) {
|
|
37
|
+
const sections = [];
|
|
38
|
+
if (requires.cli && requires.cli.length > 0) {
|
|
39
|
+
sections.push('### CLI 도구 설치\n');
|
|
40
|
+
for (const cli of requires.cli) {
|
|
41
|
+
const label = cli.required === false ? '(선택)' : '(필수)';
|
|
42
|
+
if (cli.install) {
|
|
43
|
+
sections.push(`- **${cli.name}** ${label}: \`${cli.install}\``);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
sections.push(`- **${cli.name}** ${label}: 설치 후 \`which ${cli.name}\`으로 확인`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
sections.push('');
|
|
50
|
+
}
|
|
51
|
+
if (requires.npm && requires.npm.length > 0) {
|
|
52
|
+
sections.push('### npm 패키지 설치\n');
|
|
53
|
+
sections.push('```bash');
|
|
54
|
+
const pkgNames = requires.npm.map((p) => typeof p === 'string' ? p : p.name);
|
|
55
|
+
sections.push(`npm install ${pkgNames.join(' ')}`);
|
|
56
|
+
sections.push('```\n');
|
|
57
|
+
}
|
|
58
|
+
if (requires.env && requires.env.length > 0) {
|
|
59
|
+
sections.push('### 환경변수 설정\n');
|
|
60
|
+
sections.push('```bash');
|
|
61
|
+
for (const env of requires.env) {
|
|
62
|
+
const label = env.required === false ? '# (선택)' : '# (필수)';
|
|
63
|
+
const desc = env.description ? ` — ${env.description}` : '';
|
|
64
|
+
sections.push(`${env.name}=your_value_here ${label}${desc}`);
|
|
65
|
+
}
|
|
66
|
+
sections.push('```\n');
|
|
67
|
+
}
|
|
68
|
+
if (requires.mcp && requires.mcp.length > 0) {
|
|
69
|
+
sections.push('### MCP 서버 설정\n');
|
|
70
|
+
for (const mcp of requires.mcp) {
|
|
71
|
+
sections.push(`**${mcp.name}:**`);
|
|
72
|
+
if (mcp.package)
|
|
73
|
+
sections.push(`- 패키지: \`${mcp.package}\``);
|
|
74
|
+
if (mcp.config) {
|
|
75
|
+
sections.push(`- 실행: \`${mcp.config.command}${mcp.config.args ? ' ' + mcp.config.args.join(' ') : ''}\``);
|
|
76
|
+
}
|
|
77
|
+
if (mcp.env && mcp.env.length > 0) {
|
|
78
|
+
sections.push(`- 필요한 환경변수: ${mcp.env.map((e) => `\`${e}\``).join(', ')}`);
|
|
79
|
+
}
|
|
80
|
+
sections.push('');
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (requires.teams && requires.teams.length > 0) {
|
|
84
|
+
sections.push('### 의존 팀 설치\n');
|
|
85
|
+
sections.push('```bash');
|
|
86
|
+
for (const team of requires.teams) {
|
|
87
|
+
sections.push(`relay install ${team}`);
|
|
88
|
+
}
|
|
89
|
+
sections.push('```\n');
|
|
90
|
+
}
|
|
91
|
+
if (requires.permissions && requires.permissions.length > 0) {
|
|
92
|
+
sections.push('### 권한 설정\n');
|
|
93
|
+
sections.push('아래 도구 사용을 허용해야 합니다:\n');
|
|
94
|
+
for (const perm of requires.permissions) {
|
|
95
|
+
sections.push(`- \`${perm}\``);
|
|
96
|
+
}
|
|
97
|
+
sections.push('');
|
|
98
|
+
}
|
|
99
|
+
if (sections.length === 0)
|
|
100
|
+
return '';
|
|
101
|
+
return '## Step 4. 환경 구성\n\n' + sections.join('\n');
|
|
102
|
+
}
|
|
103
|
+
function generateGuide(config, commands, requires) {
|
|
104
|
+
const scopedSlug = config.slug.startsWith('@') ? config.slug : `@${config.slug}`;
|
|
105
|
+
const needsLogin = config.visibility === 'private' || config.visibility === 'gated';
|
|
106
|
+
const setupSection = buildSetupSection(needsLogin);
|
|
107
|
+
const installStepNum = needsLogin ? 3 : 2;
|
|
108
|
+
const requiresSection = requires ? buildRequiresSection(requires) : '';
|
|
109
|
+
const requiresSectionFinal = requiresSection
|
|
110
|
+
? requiresSection.replace('## Step 4.', `## Step ${installStepNum + 1}.`)
|
|
111
|
+
: '';
|
|
112
|
+
let usageHint = '';
|
|
113
|
+
if (commands.length > 0) {
|
|
114
|
+
usageHint = `## 사용법
|
|
115
|
+
|
|
116
|
+
설치가 완료되면 아래 커맨드를 사용할 수 있습니다:
|
|
117
|
+
|
|
118
|
+
${commands.map((cmd) => `- \`/${cmd.name}\`: ${cmd.description}`).join('\n')}
|
|
119
|
+
|
|
120
|
+
원하는 작업을 말하거나 위 커맨드를 직접 실행하세요.
|
|
121
|
+
`;
|
|
122
|
+
}
|
|
123
|
+
return `# ${config.name} — 설치 가이드
|
|
124
|
+
|
|
125
|
+
> ${config.description}
|
|
126
|
+
|
|
127
|
+
이 가이드는 [RelayAX](https://relayax.com)에서 자동 생성되었습니다.
|
|
128
|
+
아래 단계를 순서대로 실행하면 Agent 팀이 설치됩니다.
|
|
129
|
+
|
|
130
|
+
${setupSection}
|
|
131
|
+
|
|
132
|
+
## Step ${installStepNum}. 팀 설치
|
|
133
|
+
|
|
134
|
+
\`\`\`bash
|
|
135
|
+
relay install ${scopedSlug}
|
|
136
|
+
\`\`\`
|
|
137
|
+
|
|
138
|
+
설치 후 Agent가 자동으로 의존성을 확인하고 환경을 구성합니다.
|
|
139
|
+
|
|
140
|
+
${requiresSectionFinal}${usageHint}---
|
|
141
|
+
*출처: https://relayax.com — Agent Team Marketplace*
|
|
142
|
+
*설치: \`relay install ${scopedSlug}\`*
|
|
143
|
+
`;
|
|
144
|
+
}
|
package/dist/lib/preamble.js
CHANGED
|
@@ -17,11 +17,10 @@ const PREAMBLE_END = '<!-- RELAY_PREAMBLE_END -->';
|
|
|
17
17
|
* relay CLI가 있으면 사용, 없으면 curl fallback.
|
|
18
18
|
*/
|
|
19
19
|
function generatePreambleScript(slug, apiUrl) {
|
|
20
|
-
// slug format: @
|
|
20
|
+
// slug format: @owner/team → extract team slug for ping
|
|
21
21
|
const stripped = slug.startsWith('@') ? slug.slice(1) : slug;
|
|
22
22
|
const slashIdx = stripped.indexOf('/');
|
|
23
|
-
const
|
|
24
|
-
const teamPart = slashIdx !== -1 ? stripped.slice(slashIdx + 1) : stripped;
|
|
23
|
+
const teamSlug = slashIdx !== -1 ? stripped.slice(slashIdx + 1) : stripped;
|
|
25
24
|
return `#!/usr/bin/env bash
|
|
26
25
|
# relay-preamble.sh — auto-generated by relay publish
|
|
27
26
|
set +e
|
|
@@ -32,7 +31,7 @@ DEVICE_HASH=$(echo "$HOSTNAME:$USER" | shasum -a 256 | cut -d' ' -f1)
|
|
|
32
31
|
if command -v relay &>/dev/null; then
|
|
33
32
|
relay ping "${slug}" --quiet 2>/dev/null &
|
|
34
33
|
else
|
|
35
|
-
curl -sf -X POST "${apiUrl}/api/
|
|
34
|
+
curl -sf -X POST "${apiUrl}/api/teams/${teamSlug}/ping" \\
|
|
36
35
|
-H "Content-Type: application/json" \\
|
|
37
36
|
-d "{\\"device_hash\\":\\"$DEVICE_HASH\\"}" \\
|
|
38
37
|
2>/dev/null &
|
package/dist/lib/slug.d.ts
CHANGED
|
@@ -15,6 +15,5 @@ export declare function isSimpleSlug(input: string): boolean;
|
|
|
15
15
|
/**
|
|
16
16
|
* Scoped 또는 단순 slug를 받아 ParsedSlug를 반환한다.
|
|
17
17
|
* 단순 slug는 서버에 resolve를 요청한다.
|
|
18
|
-
* `@spaces/{spaceSlug}/{teamSlug}` 형식은 `@{spaceSlug}/{teamSlug}`로 정규화된다.
|
|
19
18
|
*/
|
|
20
19
|
export declare function resolveSlug(input: string): Promise<ParsedSlug>;
|
package/dist/lib/slug.js
CHANGED
|
@@ -28,22 +28,18 @@ function isSimpleSlug(input) {
|
|
|
28
28
|
/**
|
|
29
29
|
* Scoped 또는 단순 slug를 받아 ParsedSlug를 반환한다.
|
|
30
30
|
* 단순 slug는 서버에 resolve를 요청한다.
|
|
31
|
-
* `@spaces/{spaceSlug}/{teamSlug}` 형식은 `@{spaceSlug}/{teamSlug}`로 정규화된다.
|
|
32
31
|
*/
|
|
33
32
|
async function resolveSlug(input) {
|
|
34
|
-
// @spaces/{spaceSlug}/{teamSlug} → @{spaceSlug}/{teamSlug} 정규화
|
|
35
|
-
const spacesPrefix = input.match(/^@spaces\/([a-z0-9][a-z0-9-]*)\/([a-z0-9][a-z0-9-]*)$/);
|
|
36
|
-
const normalized = spacesPrefix ? `@${spacesPrefix[1]}/${spacesPrefix[2]}` : input;
|
|
37
33
|
// scoped slug면 바로 파싱
|
|
38
|
-
const parsed = parseSlug(
|
|
34
|
+
const parsed = parseSlug(input);
|
|
39
35
|
if (parsed)
|
|
40
36
|
return parsed;
|
|
41
37
|
// 단순 slug인지 검증
|
|
42
|
-
if (!isSimpleSlug(
|
|
38
|
+
if (!isSimpleSlug(input)) {
|
|
43
39
|
throw new Error(`잘못된 slug 형식입니다: '${input}'. @owner/name 또는 name 형태로 입력하세요.`);
|
|
44
40
|
}
|
|
45
41
|
// 서버에 resolve 요청
|
|
46
|
-
const results = await (0, api_js_1.resolveSlugFromServer)(
|
|
42
|
+
const results = await (0, api_js_1.resolveSlugFromServer)(input);
|
|
47
43
|
if (results.length === 0) {
|
|
48
44
|
throw new Error(`'${input}' 팀을 찾을 수 없습니다.`);
|
|
49
45
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -10,8 +10,8 @@ export interface InstalledTeam {
|
|
|
10
10
|
installed_at: string;
|
|
11
11
|
files: string[];
|
|
12
12
|
type?: 'team' | 'system';
|
|
13
|
-
/**
|
|
14
|
-
|
|
13
|
+
/** Org 소속 팀인 경우 Org slug */
|
|
14
|
+
org_slug?: string;
|
|
15
15
|
/** 배치 범위 — 에이전트가 relay deploy-record로 기록 */
|
|
16
16
|
deploy_scope?: 'global' | 'local';
|
|
17
17
|
/** 배치된 파일 절대경로 목록 — 에이전트가 relay deploy-record로 기록 */
|