relayax-cli 0.2.25 → 0.2.27
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 +5 -5
- package/dist/commands/create.js +3 -7
- package/dist/commands/init.d.ts +3 -1
- package/dist/commands/init.js +29 -20
- package/dist/commands/install.js +9 -1
- package/dist/commands/ping.d.ts +2 -0
- package/dist/commands/ping.js +39 -0
- package/dist/commands/publish.js +35 -71
- package/dist/index.js +2 -0
- package/dist/lib/ai-tools.d.ts +5 -0
- package/dist/lib/ai-tools.js +10 -0
- package/dist/lib/command-adapter.d.ts +11 -2
- package/dist/lib/command-adapter.js +390 -233
- package/dist/lib/preamble.d.ts +13 -0
- package/dist/lib/preamble.js +64 -1
- package/package.json +1 -1
|
@@ -7,6 +7,8 @@ exports.BUILDER_COMMANDS = exports.USER_COMMANDS = void 0;
|
|
|
7
7
|
exports.createAdapter = createAdapter;
|
|
8
8
|
exports.getGlobalCommandPath = getGlobalCommandPath;
|
|
9
9
|
exports.getGlobalCommandDir = getGlobalCommandDir;
|
|
10
|
+
exports.getGlobalCommandDirForTool = getGlobalCommandDirForTool;
|
|
11
|
+
exports.getGlobalCommandPathForTool = getGlobalCommandPathForTool;
|
|
10
12
|
exports.formatCommandFile = formatCommandFile;
|
|
11
13
|
const os_1 = __importDefault(require("os"));
|
|
12
14
|
const path_1 = __importDefault(require("path"));
|
|
@@ -24,18 +26,31 @@ function createAdapter(tool) {
|
|
|
24
26
|
};
|
|
25
27
|
}
|
|
26
28
|
/**
|
|
27
|
-
* 글로벌 슬래시 커맨드 파일
|
|
29
|
+
* 글로벌 슬래시 커맨드 파일 경로 (Claude Code 기본).
|
|
28
30
|
* ~/.claude/commands/relay/{id}.md
|
|
29
31
|
*/
|
|
30
32
|
function getGlobalCommandPath(commandId) {
|
|
31
33
|
return path_1.default.join(os_1.default.homedir(), '.claude', 'commands', 'relay', `${commandId}.md`);
|
|
32
34
|
}
|
|
33
35
|
/**
|
|
34
|
-
* 글로벌 슬래시 커맨드
|
|
36
|
+
* 글로벌 슬래시 커맨드 디렉토리 (Claude Code 기본).
|
|
35
37
|
*/
|
|
36
38
|
function getGlobalCommandDir() {
|
|
37
39
|
return path_1.default.join(os_1.default.homedir(), '.claude', 'commands', 'relay');
|
|
38
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* 특정 AI 도구의 글로벌 커맨드 디렉토리.
|
|
43
|
+
* ~/{skillsDir}/commands/relay/
|
|
44
|
+
*/
|
|
45
|
+
function getGlobalCommandDirForTool(skillsDir) {
|
|
46
|
+
return path_1.default.join(os_1.default.homedir(), skillsDir, 'commands', 'relay');
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 특정 AI 도구의 글로벌 커맨드 파일 경로.
|
|
50
|
+
*/
|
|
51
|
+
function getGlobalCommandPathForTool(skillsDir, commandId) {
|
|
52
|
+
return path_1.default.join(os_1.default.homedir(), skillsDir, 'commands', 'relay', `${commandId}.md`);
|
|
53
|
+
}
|
|
39
54
|
/**
|
|
40
55
|
* 커맨드 콘텐츠를 파일 형식으로 포맷.
|
|
41
56
|
*/
|
|
@@ -52,54 +67,114 @@ const LOGIN_JIT_GUIDE = `
|
|
|
52
67
|
// ─── 명함 표시 포맷 ───
|
|
53
68
|
const BUSINESS_CARD_FORMAT = `
|
|
54
69
|
### 빌더 명함 표시
|
|
55
|
-
|
|
70
|
+
JSON 결과의 \`author\`, \`welcome\` 필드를 사용하여 명함을 표시합니다.
|
|
56
71
|
불릿 리스트(- 또는 *)로 나열하지 마세요. 반드시 인용 블록(>) 안에 넣어야 합니다.
|
|
57
72
|
|
|
73
|
+
**JSON 결과에서 사용할 필드:**
|
|
74
|
+
- \`author.display_name\` 또는 \`author.username\` → 명함 제목
|
|
75
|
+
- \`welcome\` → 환영 메시지 (💬)
|
|
76
|
+
- \`author.contact_links\` → 연락처 배열 (\`[{type, label, value}]\`)
|
|
77
|
+
- \`author.username\` → 프로필 링크 (👤)
|
|
78
|
+
|
|
58
79
|
**예시 (이 형태를 그대로 따르세요):**
|
|
59
80
|
|
|
60
|
-
|
|
81
|
+
JSON 결과 예시:
|
|
82
|
+
\`\`\`json
|
|
83
|
+
{
|
|
84
|
+
"author": { "username": "alice", "display_name": "Alice Kim", "contact_links": [
|
|
85
|
+
{"type": "email", "label": "이메일", "value": "alice@example.com"},
|
|
86
|
+
{"type": "website", "label": "블로그", "value": "https://alice.dev"},
|
|
87
|
+
{"type": "kakao", "label": "카카오", "value": "https://open.kakao.com/o/abc123"}
|
|
88
|
+
]},
|
|
89
|
+
"welcome": "안녕하세요!\\n에이전트 빌더 Alice입니다.\\n설치해주셔서 감사합니다."
|
|
90
|
+
}
|
|
91
|
+
\`\`\`
|
|
92
|
+
|
|
93
|
+
출력:
|
|
94
|
+
|
|
95
|
+
> **🪪 Alice Kim의 명함**
|
|
61
96
|
>
|
|
62
|
-
> 💬 "안녕하세요!
|
|
97
|
+
> 💬 "안녕하세요!
|
|
98
|
+
> 에이전트 빌더 Alice입니다.
|
|
99
|
+
> 설치해주셔서 감사합니다."
|
|
63
100
|
>
|
|
64
|
-
> 📧
|
|
65
|
-
>
|
|
101
|
+
> 📧 alice@example.com
|
|
102
|
+
> 🔗 블로그: alice.dev
|
|
103
|
+
> 💬 카카오: open.kakao.com/o/abc123
|
|
104
|
+
> 👤 relayax.com/@alice
|
|
66
105
|
|
|
67
|
-
-
|
|
106
|
+
- \`welcome\`이 없으면 💬 줄을 생략합니다.
|
|
107
|
+
- 연락처의 type에 맞는 이모지: 📧 email, 💬 kakao, 🐦 x, 💼 linkedin, 💻 github, 🔗 website/custom
|
|
68
108
|
- 연락처가 여러 개면 각각 한 줄씩 표시합니다.
|
|
69
|
-
-
|
|
109
|
+
- \`author\`가 null이면 명함 블록 전체를 생략합니다.`;
|
|
70
110
|
// ─── User Commands (글로벌 설치) ───
|
|
71
111
|
exports.USER_COMMANDS = [
|
|
72
112
|
{
|
|
73
|
-
id: 'relay-
|
|
74
|
-
description: 'relay
|
|
75
|
-
body:
|
|
113
|
+
id: 'relay-install',
|
|
114
|
+
description: 'relay 마켓플레이스에서 에이전트 팀을 설치합니다',
|
|
115
|
+
body: `요청된 에이전트 팀을 relay 마켓플레이스에서 다운로드하고, 현재 에이전트 환경에 맞게 구성합니다.
|
|
116
|
+
인자 없이 호출하면 인터랙티브 탐색 모드로 진입합니다.
|
|
76
117
|
|
|
77
|
-
##
|
|
118
|
+
## 인터랙션 플로우
|
|
78
119
|
|
|
79
|
-
|
|
80
|
-
2. \`relay search <keyword>\` 명령어를 실행합니다 (필요하면 여러 키워드로 반복).
|
|
81
|
-
3. 결과를 현재 프로젝트 맥락과 대조하여 가장 도움될 팀을 추천합니다:
|
|
82
|
-
- 팀 이름과 설명
|
|
83
|
-
- 제공하는 커맨드 목록
|
|
84
|
-
- 왜 이 팀이 지금 프로젝트에 맞는지 설명
|
|
85
|
-
4. 관심 있는 팀이 있다면 \`/relay-install <@author/slug>\`로 바로 설치할 수 있다고 안내합니다.
|
|
120
|
+
이 커맨드는 3단계 인터랙션으로 진행됩니다. 각 단계에서 반드시 AskUserQuestion 도구를 사용하세요.
|
|
86
121
|
|
|
87
|
-
|
|
122
|
+
### Step 1. 공간 선택 & 팀 탐색 (slug가 없을 때만)
|
|
88
123
|
|
|
89
|
-
|
|
90
|
-
→ relay search 콘텐츠 실행
|
|
91
|
-
→ 결과 해석: "contents-team이 카드뉴스, PDF, PPT를 만들 수 있어요"
|
|
92
|
-
→ 프로젝트 맥락 기반 추천
|
|
93
|
-
→ "/relay-install @example/contents-team으로 설치할 수 있어요"`,
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
id: 'relay-install',
|
|
97
|
-
description: 'relay 마켓플레이스에서 에이전트 팀을 설치합니다',
|
|
98
|
-
body: `요청된 에이전트 팀을 relay 마켓플레이스에서 다운로드하고, 현재 에이전트 환경에 맞게 구성합니다.
|
|
124
|
+
slug가 직접 주어지면 (\`/relay-install @alice/doc-writer\`) 이 단계를 건너뛰고 Step 2로 갑니다.
|
|
99
125
|
|
|
100
|
-
|
|
126
|
+
#### 1-1. 공간 선택
|
|
127
|
+
\`relay spaces --json\` 을 실행하여 사용자의 Space 목록을 가져옵니다.
|
|
128
|
+
|
|
129
|
+
**AskUserQuestion 호출:**
|
|
130
|
+
- question: "어디서 팀을 찾을까요?"
|
|
131
|
+
- options: Space가 있으면 \`["마켓플레이스 (공개)", "<space1_name>", "<space2_name>", ...]\`, 없으면 이 단계를 건너뛰고 바로 마켓 검색으로 진행
|
|
132
|
+
|
|
133
|
+
**응답 처리:**
|
|
134
|
+
- "마켓플레이스 (공개)" → 1-2. 마켓 검색으로 진행
|
|
135
|
+
- Space 이름 선택 → 1-3. Space 팀 목록으로 진행
|
|
136
|
+
|
|
137
|
+
#### 1-2. 마켓 검색
|
|
138
|
+
사용자의 요청에서 키워드를 추출합니다. 명시적 키워드가 없으면 현재 프로젝트를 분석하여 적절한 검색어를 판단합니다.
|
|
139
|
+
\`relay search <keyword>\` 명령어를 실행합니다 (필요하면 여러 키워드로 반복).
|
|
140
|
+
|
|
141
|
+
검색 결과를 번호 리스트로 보여줍니다:
|
|
142
|
+
|
|
143
|
+
\`\`\`
|
|
144
|
+
검색 결과 (3개)
|
|
145
|
+
|
|
146
|
+
1. @alice/doc-writer — 기술 문서 자동화
|
|
147
|
+
/write-doc, /api-doc
|
|
148
|
+
|
|
149
|
+
2. @bob/code-reviewer — PR 리뷰 자동화
|
|
150
|
+
/review, /suggest
|
|
151
|
+
|
|
152
|
+
3. @carol/test-gen — 테스트 코드 생성
|
|
153
|
+
/gen-test, /coverage
|
|
154
|
+
\`\`\`
|
|
155
|
+
|
|
156
|
+
**AskUserQuestion 호출:**
|
|
157
|
+
- question: "어떤 팀을 설치할까요?"
|
|
158
|
+
- options: \`["1", "2", "3", "다시 검색"]\`
|
|
159
|
+
|
|
160
|
+
"다시 검색" → 새 키워드로 1-2 반복
|
|
161
|
+
번호 선택 → 해당 팀의 slug로 설치 진행
|
|
162
|
+
|
|
163
|
+
#### 1-3. Space 팀 목록
|
|
164
|
+
\`relay list --space <space-slug> --json\` 을 실행합니다.
|
|
165
|
+
|
|
166
|
+
팀 목록을 번호 리스트로 보여줍니다 (1-2와 동일 형식).
|
|
167
|
+
|
|
168
|
+
**AskUserQuestion 호출:**
|
|
169
|
+
- question: "어떤 팀을 설치할까요?"
|
|
170
|
+
- options: \`["1", "2", ..., "돌아가기"]\`
|
|
171
|
+
|
|
172
|
+
"돌아가기" → 1-1로 돌아감
|
|
173
|
+
번호 선택 → 해당 팀의 slug로 설치 진행
|
|
174
|
+
|
|
175
|
+
### Step 2. 설치 & 배치 범위 선택
|
|
101
176
|
|
|
102
|
-
|
|
177
|
+
#### 2-1. 패키지 다운로드
|
|
103
178
|
\`relay install <@author/slug> --json\` 명령어를 실행합니다.
|
|
104
179
|
- Public 마켓 팀: \`relay install <@author/slug> --json\`
|
|
105
180
|
- Space 팀: \`relay install @spaces/<space-slug>/<team-slug> --json\`
|
|
@@ -108,36 +183,30 @@ exports.USER_COMMANDS = [
|
|
|
108
183
|
- CLI가 init과 login을 자동으로 처리합니다 (사용자가 별도 실행할 필요 없음).
|
|
109
184
|
- JSON 출력에서 \`install_path\` (패키지 경로)를 확인합니다.
|
|
110
185
|
|
|
111
|
-
|
|
112
|
-
사용자에게 설치 범위를 물어봅니다:
|
|
186
|
+
#### 2-2. 배치 범위 선택
|
|
113
187
|
|
|
114
|
-
|
|
115
|
-
-
|
|
188
|
+
**AskUserQuestion 호출:**
|
|
189
|
+
- question: "어디에 설치할까요?"
|
|
190
|
+
- options: \`["글로벌 (모든 프로젝트)", "로컬 (이 프로젝트만)"]\`
|
|
116
191
|
|
|
117
|
-
|
|
118
|
-
-
|
|
119
|
-
-
|
|
120
|
-
- Space 비공개 팀: 로컬 추천
|
|
192
|
+
**응답 처리:**
|
|
193
|
+
- "글로벌" → \`~/.claude/\`에 배치
|
|
194
|
+
- "로컬" → 현재 프로젝트 \`.claude/\`에 배치
|
|
121
195
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
### 3. 에이전트 환경에 맞게 배치
|
|
196
|
+
#### 2-3. 에이전트 환경에 맞게 배치
|
|
125
197
|
다운로드된 패키지(\`install_path\`)에서 파일을 읽고 선택된 범위에 배치합니다:
|
|
126
|
-
-
|
|
127
|
-
-
|
|
128
|
-
- Claude Code 로컬: \`<install_path>/commands/\` → \`.claude/commands/\`에 복사
|
|
129
|
-
- Claude Code 로컬: \`<install_path>/skills/\` → \`.claude/skills/\`에 복사
|
|
198
|
+
- 글로벌: \`<install_path>/commands/\` → \`~/.claude/commands/\`에 복사, skills/ 동일
|
|
199
|
+
- 로컬: \`<install_path>/commands/\` → \`.claude/commands/\`에 복사, skills/ 동일
|
|
130
200
|
- agents/, rules/ 파일도 같은 방식으로 배치합니다.
|
|
131
201
|
- **충돌 확인**: 같은 이름의 파일이 이미 있으면 사용자에게 덮어쓸지 물어봅니다.
|
|
132
202
|
|
|
133
|
-
|
|
134
|
-
배치 완료 후 반드시 \`relay deploy-record\`를
|
|
203
|
+
#### 2-4. 배치 정보 기록 (필수)
|
|
204
|
+
배치 완료 후 반드시 \`relay deploy-record\`를 실행합니다:
|
|
135
205
|
\`\`\`
|
|
136
206
|
relay deploy-record <slug> --scope <global|local> --files <배치된_파일1> <배치된_파일2> ...
|
|
137
207
|
\`\`\`
|
|
138
|
-
이 정보는 \`relay uninstall\` 시 배치된 파일까지 정리하는 데 사용됩니다.
|
|
139
208
|
|
|
140
|
-
|
|
209
|
+
#### 2-5. Requirements 확인 및 설치
|
|
141
210
|
\`<install_path>/relay.yaml\`의 \`requires\` 섹션을 읽고 처리합니다:
|
|
142
211
|
- **cli**: \`which <name>\`으로 확인 → 없으면 install 명령 실행 또는 안내
|
|
143
212
|
- **npm**: \`npm list <package>\`로 확인 → 없으면 \`npm install\`
|
|
@@ -147,125 +216,145 @@ relay deploy-record <slug> --scope <global|local> --files <배치된_파일1> <
|
|
|
147
216
|
- **teams**: 의존하는 다른 팀 → \`relay install <@author/team>\`으로 재귀 설치
|
|
148
217
|
${LOGIN_JIT_GUIDE}
|
|
149
218
|
|
|
150
|
-
###
|
|
219
|
+
### Step 3. 완료 & 팔로우 제안
|
|
220
|
+
|
|
221
|
+
#### 3-1. 완료 안내
|
|
151
222
|
- 배치된 파일과 활성화된 커맨드 목록을 보여줍니다.
|
|
152
223
|
${BUSINESS_CARD_FORMAT}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
224
|
+
|
|
225
|
+
#### 3-2. 팔로우 제안 (필수 — 이 단계를 절대 건너뛰지 마세요)
|
|
226
|
+
명함 표시 직후, 빌더의 username이 JSON 결과에 있으면 **반드시** AskUserQuestion 도구를 호출하세요.
|
|
227
|
+
|
|
228
|
+
**AskUserQuestion 호출:**
|
|
229
|
+
- question: \`@{username}을 팔로우할까요? 새 버전 알림을 받을 수 있습니다.\`
|
|
230
|
+
- options: \`["팔로우", "건너뛰기"]\`
|
|
231
|
+
|
|
232
|
+
**응답 처리:**
|
|
233
|
+
- "팔로우" → \`relay follow @{username}\` 실행. 로그인이 안 되어 있으면 \`relay login\` 먼저 실행 후 재시도.
|
|
234
|
+
- "건너뛰기" → 다음 단계로 진행
|
|
235
|
+
|
|
236
|
+
#### 3-3. 사용 제안
|
|
156
237
|
- "바로 사용해볼까요?" 제안
|
|
157
238
|
|
|
158
|
-
|
|
239
|
+
#### 3-4. 업데이트 확인
|
|
159
240
|
- \`relay check-update\` 명령어를 실행합니다.
|
|
160
241
|
- CLI 업데이트가 있으면 안내합니다: "relay v{new} available. Run: npm update -g relayax-cli"
|
|
161
242
|
- 다른 팀 업데이트가 있으면 안내합니다.
|
|
162
243
|
|
|
163
244
|
## 예시
|
|
164
245
|
|
|
165
|
-
|
|
166
|
-
→ relay
|
|
167
|
-
→
|
|
168
|
-
→
|
|
169
|
-
→ relay
|
|
170
|
-
→
|
|
171
|
-
→ "
|
|
246
|
+
### 인터랙티브 모드 (/relay-install)
|
|
247
|
+
→ relay spaces --json 실행
|
|
248
|
+
→ AskUserQuestion: "어디서 팀을 찾을까요?" → ["마켓플레이스 (공개)", "Acme Corp"]
|
|
249
|
+
→ "마켓플레이스" 선택 → "어떤 팀을 찾고 계세요?"
|
|
250
|
+
→ relay search "문서" 실행 → 결과 리스트 표시
|
|
251
|
+
→ AskUserQuestion: "어떤 팀을 설치할까요?" → ["1", "2", "3", "다시 검색"]
|
|
252
|
+
→ "1" 선택 (@alice/doc-writer)
|
|
253
|
+
→ AskUserQuestion: "어디에 설치할까요?" → ["글로벌 (모든 프로젝트)", "로컬 (이 프로젝트만)"]
|
|
254
|
+
→ "글로벌" 선택
|
|
255
|
+
→ 설치 + 배치 + deploy-record
|
|
256
|
+
→ 명함 표시
|
|
257
|
+
→ AskUserQuestion: "@alice을 팔로우할까요?" → ["팔로우", "건너뛰기"]
|
|
258
|
+
→ "✓ 설치 완료! /write-doc를 사용해볼까요?"
|
|
259
|
+
|
|
260
|
+
### 다이렉트 모드 (/relay-install @alice/doc-writer)
|
|
261
|
+
→ relay install @alice/doc-writer --json 실행 (Step 1 건너뜀)
|
|
262
|
+
→ AskUserQuestion: "어디에 설치할까요?" → ["글로벌 (모든 프로젝트)", "로컬 (이 프로젝트만)"]
|
|
263
|
+
→ 설치 + 배치 + deploy-record
|
|
264
|
+
→ 명함 표시
|
|
265
|
+
→ AskUserQuestion: "@alice을 팔로우할까요?" → ["팔로우", "건너뛰기"]
|
|
266
|
+
→ "✓ 설치 완료! /write-doc를 사용해볼까요?"`,
|
|
172
267
|
},
|
|
173
268
|
{
|
|
174
|
-
id: 'relay-
|
|
175
|
-
description: '설치된
|
|
176
|
-
body: `현재 설치된 에이전트
|
|
269
|
+
id: 'relay-status',
|
|
270
|
+
description: '설치된 팀과 Space 현황을 확인합니다',
|
|
271
|
+
body: `현재 설치된 에이전트 팀과 소속 Space 현황을 한눈에 보여줍니다.
|
|
177
272
|
|
|
178
273
|
## 실행 방법
|
|
179
274
|
|
|
180
|
-
1.
|
|
181
|
-
2. 결과를 사용자에게 보기 좋게 정리하여 보여줍니다:
|
|
182
|
-
- 팀 이름과 버전
|
|
183
|
-
- 설치 날짜
|
|
184
|
-
- 사용 가능한 커맨드
|
|
185
|
-
3. 설치된 팀이 없으면 \`/relay-explore\`로 팀을 탐색해보라고 안내합니다.
|
|
275
|
+
### 1. 설치된 팀 목록
|
|
186
276
|
|
|
187
|
-
|
|
188
|
-
- 특정 Space에서 사용 가능한 팀 목록을 보려면: \`relay list --space <space-slug> --json\`
|
|
189
|
-
- Space에 가입되어 있어야 합니다.
|
|
277
|
+
\`relay list --json\` 명령어를 실행합니다.
|
|
190
278
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
→ "2개 팀이 설치되어 있어요:"
|
|
196
|
-
→ " @example/contents-team v1.2.0 (2일 전 설치) - /cardnews, /pdf-report"
|
|
197
|
-
→ " qa-team v0.5.1 (1주 전 설치) - /qa, /qa-only"
|
|
198
|
-
|
|
199
|
-
사용자: /relay-list --space bobusan
|
|
200
|
-
→ relay list --space bobusan --json 실행
|
|
201
|
-
→ "bobusan Space에서 설치 가능한 팀:"
|
|
202
|
-
→ " pm-bot — 프로젝트 관리 봇"
|
|
203
|
-
→ " cs-bot — 고객 응대 봇"`,
|
|
204
|
-
},
|
|
279
|
+
**JSON 응답 구조:**
|
|
280
|
+
\`\`\`json
|
|
281
|
+
{
|
|
282
|
+
"installed": [
|
|
205
283
|
{
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
284
|
+
"slug": "@author/team-name",
|
|
285
|
+
"version": "1.2.0",
|
|
286
|
+
"installed_at": "2026-03-20T12:00:00.000Z",
|
|
287
|
+
"scope": "global",
|
|
288
|
+
"deploy_scope": "global",
|
|
289
|
+
"space_slug": null
|
|
290
|
+
}
|
|
291
|
+
]
|
|
292
|
+
}
|
|
293
|
+
\`\`\`
|
|
209
294
|
|
|
210
|
-
|
|
295
|
+
**각 팀을 아래 형식으로 표시:**
|
|
211
296
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
-
|
|
215
|
-
- 업데이트 여부와 관계없이 팀 업데이트를 계속 진행합니다.
|
|
216
|
-
|
|
217
|
-
### 특정 팀 업데이트
|
|
218
|
-
- 사용자가 팀 이름을 지정한 경우: \`relay update <@author/slug> --json\` 실행
|
|
219
|
-
- 업데이트 결과를 보여줍니다 (이전 버전 → 새 버전)
|
|
220
|
-
- **재배치 필요 확인**: JSON 출력에 \`needs_redeploy: true\`가 있으면:
|
|
221
|
-
1. \`previous_deploy_scope\`를 참고하여 같은 범위(글로벌/로컬)로 파일을 다시 배치합니다.
|
|
222
|
-
2. 배치 후 \`relay deploy-record <slug> --scope <scope> --files <...>\`를 실행하여 기록합니다.
|
|
223
|
-
${BUSINESS_CARD_FORMAT}
|
|
297
|
+
| 팀 | 버전 | 배포 | 설치일 |
|
|
298
|
+
|---|---|---|---|
|
|
299
|
+
| @author/team-name | v1.2.0 | 글로벌 | 3/20 |
|
|
224
300
|
|
|
225
|
-
|
|
226
|
-
-
|
|
227
|
-
1. \`relay outdated --json\`으로 업데이트 가능한 팀 목록을 확인합니다.
|
|
228
|
-
2. 업데이트 가능한 팀이 있으면 목록을 보여주고 어떤 팀을 업데이트할지 물어봅니다.
|
|
229
|
-
3. 선택된 팀에 대해 \`relay update <@author/slug> --json\`을 실행합니다.
|
|
230
|
-
4. 모두 최신이면 "모든 팀이 최신 버전입니다"라고 안내합니다.
|
|
301
|
+
- \`deploy_scope\`가 \`"global"\` → 글로벌, \`"local"\` → 로컬, 없으면 → 미배치
|
|
302
|
+
- \`space_slug\`가 있으면 \`[Space: slug]\` 표시
|
|
231
303
|
|
|
232
|
-
|
|
304
|
+
### 2. Space 목록
|
|
233
305
|
|
|
234
|
-
|
|
235
|
-
→ relay outdated --json 실행
|
|
236
|
-
→ "1개 팀 업데이트 가능:"
|
|
237
|
-
→ " @example/contents-team: v1.2.0 → v1.3.0"
|
|
238
|
-
→ "업데이트할까요?"
|
|
239
|
-
→ relay update @example/contents-team --json 실행
|
|
240
|
-
→ needs_redeploy: true → 글로벌로 재배치
|
|
241
|
-
→ relay deploy-record @example/contents-team --scope global --files ...
|
|
242
|
-
→ "✓ @example/contents-team v1.3.0으로 업데이트 완료"`,
|
|
243
|
-
},
|
|
244
|
-
{
|
|
245
|
-
id: 'relay-spaces',
|
|
246
|
-
description: '내 Space 목록을 확인합니다',
|
|
247
|
-
body: `사용자의 Space 목록을 조회하고 보여줍니다.
|
|
306
|
+
\`relay spaces --json\` 명령어를 실행합니다.
|
|
248
307
|
|
|
249
|
-
|
|
308
|
+
**JSON 응답 구조:**
|
|
309
|
+
\`\`\`json
|
|
310
|
+
{
|
|
311
|
+
"spaces": [
|
|
312
|
+
{
|
|
313
|
+
"slug": "my-space",
|
|
314
|
+
"name": "내 스페이스",
|
|
315
|
+
"description": "설명",
|
|
316
|
+
"is_personal": false,
|
|
317
|
+
"role": "owner"
|
|
318
|
+
}
|
|
319
|
+
]
|
|
320
|
+
}
|
|
321
|
+
\`\`\`
|
|
250
322
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
- 팀 스페이스 (이름, 역할, 설명)
|
|
255
|
-
3. Space가 있으면 관련 활용법을 안내합니다:
|
|
256
|
-
- 팀 목록 보기: \`relay list --space <slug>\`
|
|
257
|
-
- 비공개 팀 설치: \`relay install @spaces/<slug>/<team>\`
|
|
258
|
-
- Space 관리: www.relayax.com/spaces/<slug>
|
|
323
|
+
**표시:**
|
|
324
|
+
- \`is_personal: true\` → 개인 스페이스로 분류
|
|
325
|
+
- \`role\`: owner → 소유자, admin → 관리자, member → 멤버
|
|
259
326
|
${LOGIN_JIT_GUIDE}
|
|
327
|
+
- Spaces 조회 실패해도 설치된 팀 목록은 정상 표시합니다 (로컬 데이터).
|
|
328
|
+
|
|
329
|
+
### 3. Space 팀 목록 (옵션)
|
|
330
|
+
- \`--space <slug>\` 인자가 있으면: \`relay list --space <space-slug> --json\`으로 해당 Space에서 설치 가능한 팀 목록도 보여줍니다.
|
|
331
|
+
|
|
332
|
+
### 4. 안내
|
|
333
|
+
- 설치된 팀이 없으면 \`/relay-install\`로 팀을 탐색·설치해보라고 안내합니다.
|
|
334
|
+
- Space가 있으면 활용법을 안내합니다:
|
|
335
|
+
- 비공개 팀 설치: \`relay install @spaces/<slug>/<team>\`
|
|
336
|
+
- Space 관리: www.relayax.com/spaces/<slug>
|
|
260
337
|
|
|
261
338
|
## 예시
|
|
262
339
|
|
|
263
|
-
사용자: /relay-
|
|
264
|
-
→ relay
|
|
265
|
-
→
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
340
|
+
사용자: /relay-status
|
|
341
|
+
→ relay list --json 실행
|
|
342
|
+
→ relay spaces --json 실행 (병렬 가능)
|
|
343
|
+
|
|
344
|
+
**설치된 팀 (2개)**
|
|
345
|
+
|
|
346
|
+
| 팀 | 버전 | 배포 | 설치일 |
|
|
347
|
+
|---|---|---|---|
|
|
348
|
+
| @alice/doc-writer | v1.2.0 | 글로벌 | 3/20 |
|
|
349
|
+
| @bob/code-reviewer | v0.5.1 | 로컬 | 3/15 |
|
|
350
|
+
|
|
351
|
+
**내 Space (2개)**
|
|
352
|
+
- acme-corp — Acme Corp (소유자)
|
|
353
|
+
- dev-guild — Dev Guild (멤버)
|
|
354
|
+
|
|
355
|
+
사용자: /relay-status --space acme-corp
|
|
356
|
+
→ 위 정보 + \`relay list --space acme-corp --json\` 실행
|
|
357
|
+
→ acme-corp Space에서 설치 가능한 팀 목록 추가 표시`,
|
|
269
358
|
},
|
|
270
359
|
{
|
|
271
360
|
id: 'relay-uninstall',
|
|
@@ -284,9 +373,9 @@ ${LOGIN_JIT_GUIDE}
|
|
|
284
373
|
|
|
285
374
|
## 예시
|
|
286
375
|
|
|
287
|
-
사용자: /relay-uninstall @
|
|
288
|
-
→ relay uninstall @
|
|
289
|
-
→ "✓ @
|
|
376
|
+
사용자: /relay-uninstall @alice/doc-writer
|
|
377
|
+
→ relay uninstall @alice/doc-writer --json 실행
|
|
378
|
+
→ "✓ @alice/doc-writer 삭제 완료 (12개 파일 제거)"`,
|
|
290
379
|
},
|
|
291
380
|
];
|
|
292
381
|
// ─── Builder Commands (로컬 설치) ───
|
|
@@ -296,51 +385,92 @@ exports.BUILDER_COMMANDS = [
|
|
|
296
385
|
description: '현재 팀 패키지를 포트폴리오와 함께 relay 마켓플레이스에 배포합니다',
|
|
297
386
|
body: `현재 디렉토리의 에이전트 팀(.relay/)을 분석하고, 보안 점검 및 requirements를 구성한 뒤, 사용가이드와 포트폴리오를 생성하고 relay 마켓플레이스에 배포합니다.
|
|
298
387
|
|
|
299
|
-
##
|
|
388
|
+
## 사전 준비 (자동)
|
|
300
389
|
|
|
301
|
-
### 1. 인증 확인
|
|
390
|
+
### 0-1. 인증 확인
|
|
302
391
|
- \`relay status --json\` 명령어를 실행하여 로그인 상태를 확인합니다.
|
|
303
392
|
- 미인증이면 즉시 \`relay login\`을 실행합니다.
|
|
304
|
-
- 로그인 완료 후 다음 단계로 진행합니다.
|
|
305
393
|
${LOGIN_JIT_GUIDE}
|
|
306
394
|
|
|
307
|
-
### 2. 팀 구조 분석
|
|
395
|
+
### 0-2. 팀 구조 분석
|
|
308
396
|
- .relay/ 디렉토리의 skills/, agents/, rules/, commands/를 탐색합니다.
|
|
309
397
|
- 각 파일의 이름과 description을 추출합니다.
|
|
310
398
|
- .relay/relay.yaml이 있으면 읽고, 없으면 사용자에게 팀 정보(name, slug, description, tags)를 물어보고 생성합니다.
|
|
311
399
|
|
|
312
|
-
|
|
400
|
+
## 인터랙션 플로우
|
|
401
|
+
|
|
402
|
+
이 커맨드는 5단계 인터랙션으로 진행됩니다. 각 단계에서 반드시 AskUserQuestion 도구를 사용하세요.
|
|
403
|
+
|
|
404
|
+
### Step 1. 공개 범위 선택
|
|
405
|
+
|
|
406
|
+
relay.yaml의 \`visibility\` 설정을 확인합니다.
|
|
407
|
+
|
|
408
|
+
#### 신규 배포 (visibility 미설정)
|
|
409
|
+
|
|
410
|
+
**AskUserQuestion 호출:**
|
|
411
|
+
- question: "어디에 배포할까요?"
|
|
412
|
+
- options: \`["공개 (마켓플레이스)", "비공개 (Space 전용)"]\`
|
|
413
|
+
|
|
414
|
+
**응답 처리:**
|
|
415
|
+
- "공개" → relay.yaml에 \`visibility: public\` 저장
|
|
416
|
+
- "비공개" → \`relay spaces --json\` 실행 후 Space 목록 표시
|
|
417
|
+
|
|
418
|
+
**AskUserQuestion 호출:**
|
|
419
|
+
- question: "어떤 Space에 배포할까요?"
|
|
420
|
+
- options: \`["<space1_name>", "<space2_name>", ...]\`
|
|
421
|
+
|
|
422
|
+
→ relay.yaml에 \`visibility: private\`, \`space: <selected_slug>\` 저장
|
|
423
|
+
|
|
424
|
+
#### 재배포 (visibility 이미 설정됨)
|
|
313
425
|
|
|
314
|
-
|
|
426
|
+
현재 설정을 확인합니다:
|
|
315
427
|
|
|
316
|
-
|
|
428
|
+
**AskUserQuestion 호출:**
|
|
429
|
+
- question: 공개일 때 "현재 **공개** 설정입니다. 마켓플레이스에 노출됩니다. 유지할까요?", 비공개일 때 "현재 **비공개** 설정입니다 (Space: {name}). 유지할까요?"
|
|
430
|
+
- options: \`["유지", "변경"]\`
|
|
431
|
+
|
|
432
|
+
"변경" → 신규 배포와 동일한 플로우
|
|
433
|
+
|
|
434
|
+
### Step 2. 보안 점검 & requires 확인
|
|
435
|
+
|
|
436
|
+
.relay/ 내 모든 파일을 자동 분석합니다.
|
|
437
|
+
|
|
438
|
+
#### 2-1. 시크릿 스캔 (자동)
|
|
317
439
|
- 하드코딩된 API 키, 토큰, 비밀번호, Private Key 등을 탐색합니다.
|
|
318
440
|
- 예: sk-..., ghp_..., AKIA..., Bearer 토큰, JWT, -----BEGIN PRIVATE KEY----- 등
|
|
319
441
|
- 발견 시 **즉시 사용자에게 경고**하고, 환경변수로 대체하도록 안내합니다.
|
|
320
442
|
- 시크릿이 제거되지 않으면 배포를 진행하지 않습니다.
|
|
321
443
|
|
|
322
|
-
####
|
|
323
|
-
|
|
324
|
-
-
|
|
325
|
-
|
|
326
|
-
- 설명을 추가할 수 있습니다.
|
|
327
|
-
|
|
328
|
-
#### 3-3. 의존성 감지
|
|
329
|
-
아래 카테고리별로 분석하고, 사용자에게 필수/선택 여부를 확인합니다:
|
|
330
|
-
|
|
331
|
-
- **cli**: 파일에서 참조하는 CLI 도구 (playwright, ffmpeg, sharp 등)
|
|
444
|
+
#### 2-2. 환경변수 & 의존성 분석 (자동)
|
|
445
|
+
분석 대상:
|
|
446
|
+
- **env**: 환경변수 참조 (process.env.*, \${VAR}, os.environ 등)
|
|
447
|
+
- **cli**: 참조하는 CLI 도구 (playwright, ffmpeg, sharp 등)
|
|
332
448
|
- **npm**: import/require되는 npm 패키지
|
|
333
|
-
- **mcp**: MCP 서버 설정
|
|
334
|
-
- **runtime**: Node.js/Python 등 최소 버전
|
|
335
|
-
- **permissions**: 필요한 에이전트 권한 (filesystem, network, shell)
|
|
449
|
+
- **mcp**: MCP 서버 설정
|
|
450
|
+
- **runtime**: Node.js/Python 등 최소 버전
|
|
336
451
|
- **teams**: 의존하는 다른 relay 팀
|
|
337
452
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
453
|
+
분석 결과를 요약 표시합니다:
|
|
454
|
+
|
|
455
|
+
\`\`\`
|
|
456
|
+
requires 분석 결과
|
|
341
457
|
|
|
342
|
-
|
|
343
|
-
|
|
458
|
+
환경변수:
|
|
459
|
+
OPENAI_API_KEY — 필수 (LLM API 호출)
|
|
460
|
+
SLACK_WEBHOOK_URL — 선택 (알림 전송)
|
|
461
|
+
|
|
462
|
+
CLI: playwright (필수)
|
|
463
|
+
npm: sharp (필수)
|
|
464
|
+
MCP: supabase (선택)
|
|
465
|
+
\`\`\`
|
|
466
|
+
|
|
467
|
+
**AskUserQuestion 호출:**
|
|
468
|
+
- question: "requires 설정이 맞나요?"
|
|
469
|
+
- options: \`["확인", "수정"]\`
|
|
470
|
+
|
|
471
|
+
**응답 처리:**
|
|
472
|
+
- "확인" → .relay/relay.yaml에 requires 섹션 저장, 다음 단계로
|
|
473
|
+
- "수정" → 사용자와 텍스트 대화로 수정 후 다시 확인
|
|
344
474
|
|
|
345
475
|
\`\`\`yaml
|
|
346
476
|
# .relay/relay.yaml requires 구조
|
|
@@ -367,95 +497,116 @@ requires:
|
|
|
367
497
|
command: "npx"
|
|
368
498
|
args: ["-y", "@supabase/mcp-server"]
|
|
369
499
|
env: [SUPABASE_URL, SUPABASE_SECRET_KEY]
|
|
370
|
-
- name: notion
|
|
371
|
-
package: "@notionhq/mcp-server"
|
|
372
|
-
required: false
|
|
373
|
-
env: [NOTION_API_KEY]
|
|
374
500
|
runtime:
|
|
375
501
|
node: ">=18"
|
|
376
502
|
permissions:
|
|
377
503
|
- filesystem
|
|
378
504
|
- network
|
|
379
505
|
teams:
|
|
380
|
-
- @
|
|
506
|
+
- @alice/doc-writer
|
|
381
507
|
\`\`\`
|
|
382
508
|
|
|
383
|
-
###
|
|
509
|
+
### Step 3. 포트폴리오 선택
|
|
510
|
+
|
|
511
|
+
output/, results/, examples/, portfolio/ 디렉토리를 스캔하여 결과물(PNG, JPG, HTML, PDF)을 찾습니다.
|
|
512
|
+
HTML 파일은 Playwright 스크린샷으로 변환합니다.
|
|
384
513
|
|
|
385
|
-
|
|
386
|
-
- 발견된 결과물(PNG, JPG, HTML, PDF)을 사용자에게 보여줍니다.
|
|
387
|
-
- HTML 파일은 Playwright 스크린샷으로 변환합니다.
|
|
388
|
-
- 사용자가 포트폴리오에 포함할 항목을 선택합니다.
|
|
389
|
-
- 선택된 이미지를 .relay/portfolio/에 저장합니다.
|
|
514
|
+
발견된 파일을 번호 리스트로 보여줍니다:
|
|
390
515
|
|
|
391
|
-
|
|
516
|
+
\`\`\`
|
|
517
|
+
포트폴리오 후보 (4개)
|
|
518
|
+
|
|
519
|
+
1. output/report-example.png — 리포트 예시
|
|
520
|
+
2. output/dashboard.html → 스크린샷 변환
|
|
521
|
+
3. examples/result-1.png — 결과물 1
|
|
522
|
+
4. examples/result-2.png — 결과물 2
|
|
523
|
+
\`\`\`
|
|
524
|
+
|
|
525
|
+
**AskUserQuestion 호출:**
|
|
526
|
+
- question: "어떤 결과물을 포트폴리오에 포함할까요? (최대 5개)"
|
|
527
|
+
- options: \`["전체 포함", "1", "2", "3", "4", "건너뛰기"]\`
|
|
528
|
+
|
|
529
|
+
**응답 처리:**
|
|
530
|
+
- "전체 포함" → 모든 파일을 .relay/portfolio/에 저장
|
|
531
|
+
- 번호 선택 → 해당 파일만 포함 (여러 번 선택 가능 — 한 번 선택 후 추가 선택 여부를 다시 물어봄)
|
|
532
|
+
- "건너뛰기" → 포트폴리오 없이 진행
|
|
533
|
+
|
|
534
|
+
선택된 이미지를 .relay/portfolio/에 저장하고 relay.yaml의 portfolio.gallery에 등록합니다.
|
|
535
|
+
|
|
536
|
+
\`\`\`yaml
|
|
537
|
+
portfolio:
|
|
538
|
+
demo: # 선택
|
|
539
|
+
type: gif
|
|
540
|
+
path: portfolio/demo.gif
|
|
541
|
+
gallery: # 선택, 최대 5장
|
|
542
|
+
- path: portfolio/guide-preview.png
|
|
543
|
+
title: "사용가이드 미리보기"
|
|
544
|
+
- path: portfolio/report-example.png
|
|
545
|
+
title: "리포트 예시"
|
|
546
|
+
\`\`\`
|
|
547
|
+
|
|
548
|
+
파일이 하나도 발견되지 않으면 이 단계를 건너뜁니다.
|
|
549
|
+
|
|
550
|
+
### Step 4. GUIDE.html 컨펌
|
|
392
551
|
|
|
393
552
|
설치자가 읽을 수 있는 사용가이드를 HTML로 생성합니다.
|
|
394
553
|
|
|
395
|
-
####
|
|
554
|
+
#### 4-1. 팀 소스 분석 (자동)
|
|
396
555
|
- skills/, agents/, commands/ 디렉토리의 **모든 파일 내용**을 읽습니다.
|
|
397
556
|
- 각 스킬의 SKILL.md, 에이전트 설정, 커맨드 문서를 분석하여 팀의 파이프라인 흐름을 추론합니다.
|
|
398
557
|
|
|
399
|
-
####
|
|
558
|
+
#### 4-2. GUIDE.html 생성 (자동)
|
|
400
559
|
- 팀의 핵심 기능, 시작 방법, 파이프라인 흐름, Q&A를 포함하는 단일 HTML 가이드를 생성합니다.
|
|
401
560
|
- 디자인: 깔끔한 단일 페이지, 시스템 폰트, 최대 1200px 너비, 라이트 테마.
|
|
402
|
-
- 5-1에서 분석한 팀 소스 정보를 기반으로 콘텐츠를 구성합니다.
|
|
403
561
|
- 파이프라인이 없는 단순한 팀은 시작 방법 + 기능 설명 + Q&A만 포함합니다.
|
|
404
562
|
|
|
405
|
-
####
|
|
406
|
-
|
|
407
|
-
- 빌더에게 확인: "사용가이드를 확인해주세요. 이대로 진행할까요?"
|
|
563
|
+
#### 4-3. 미리보기 + 컨펌
|
|
564
|
+
생성된 GUIDE.html을 브라우저에서 열어 빌더에게 미리보기를 보여줍니다.
|
|
408
565
|
|
|
409
|
-
|
|
410
|
-
-
|
|
411
|
-
-
|
|
412
|
-
- 빌더가 컨펌할 때까지 반복합니다.
|
|
566
|
+
**AskUserQuestion 호출:**
|
|
567
|
+
- question: "사용가이드를 확인해주세요. 진행할까요?"
|
|
568
|
+
- options: \`["진행", "수정 요청"]\`
|
|
413
569
|
|
|
414
|
-
|
|
415
|
-
-
|
|
570
|
+
**응답 처리:**
|
|
571
|
+
- "진행" → GUIDE.html을 \`.relay/GUIDE.html\`에 저장
|
|
572
|
+
- "수정 요청" → 사용자와 텍스트 대화로 수정사항 파악 → GUIDE.html 재생성 → 다시 미리보기 → AskUserQuestion 반복
|
|
416
573
|
|
|
417
|
-
####
|
|
418
|
-
- GUIDE.html을 Playwright로 열어 첫 화면(뷰포트 1200x630)을 스크린샷 캡처합니다.
|
|
574
|
+
#### 4-4. GUIDE.html 스크린샷 → gallery 등록 (자동)
|
|
575
|
+
- GUIDE.html을 Playwright로 열어 첫 화면(뷰포트 1200x630)을 스크린샷 캡처합니다.
|
|
419
576
|
- 결과 PNG를 \`./portfolio/guide-preview.png\`에 저장합니다.
|
|
420
577
|
- relay.yaml의 portfolio gallery 첫 번째 항목으로 자동 등록합니다.
|
|
421
578
|
- 이 이미지는 마켓플레이스 카드 및 OG 이미지의 fallback으로 사용됩니다 (demo > gallery 순).
|
|
422
579
|
|
|
423
|
-
###
|
|
580
|
+
### Step 5. 최종 확인 & 배포
|
|
581
|
+
|
|
582
|
+
#### 5-1. 메타데이터 생성 (자동)
|
|
424
583
|
- description: skills 내용 기반으로 자동 생성합니다.
|
|
425
584
|
- long_description: 팀 소개 마크다운을 자동 생성합니다 (README.md가 있으면 활용).
|
|
426
585
|
- tags: 팀 특성에 맞는 태그를 추천합니다.
|
|
427
|
-
- 사용자에게 확인: "이대로 배포할까요?"
|
|
428
586
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
- 설정되어 있지 않으면 빌더에게 반드시 물어봅니다:
|
|
432
|
-
- "공개 (마켓플레이스에 누구나 검색·설치 가능)" vs "비공개 (Space 멤버만 접근)"
|
|
433
|
-
- 선택 결과를 relay.yaml에 저장합니다.
|
|
434
|
-
- 이미 설정되어 있으면 현재 값을 확인합니다:
|
|
435
|
-
- 공개인 경우: "⚠ 이 팀은 **공개**로 설정되어 있어 마켓플레이스에 노출됩니다. 맞나요?"
|
|
436
|
-
- 비공개인 경우: "이 팀은 **비공개**로 설정되어 Space 멤버만 접근 가능합니다."
|
|
437
|
-
- 빌더가 변경을 원하면 relay.yaml을 업데이트합니다.
|
|
587
|
+
#### 5-2. 배포 요약 + 최종 확인
|
|
588
|
+
배포할 내용을 요약 표시합니다:
|
|
438
589
|
|
|
439
|
-
|
|
440
|
-
|
|
590
|
+
\`\`\`
|
|
591
|
+
배포 요약
|
|
441
592
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
gallery: # 선택, 최대 5장
|
|
448
|
-
- path: portfolio/guide-preview.png
|
|
449
|
-
title: "사용가이드 미리보기"
|
|
450
|
-
- path: portfolio/example-1.png
|
|
451
|
-
title: "카드뉴스 예시"
|
|
593
|
+
팀: my-team v1.0.0
|
|
594
|
+
공개: 마켓플레이스 (공개)
|
|
595
|
+
Skills: 3개, Commands: 5개
|
|
596
|
+
포트폴리오: 2장
|
|
597
|
+
requires: env 2개, cli 1개
|
|
452
598
|
\`\`\`
|
|
453
599
|
|
|
454
|
-
|
|
455
|
-
-
|
|
456
|
-
- 배포
|
|
600
|
+
**AskUserQuestion 호출:**
|
|
601
|
+
- question: "이대로 배포할까요?"
|
|
602
|
+
- options: \`["배포", "취소"]\`
|
|
603
|
+
|
|
604
|
+
**응답 처리:**
|
|
605
|
+
- "배포" → \`relay publish\` 실행
|
|
606
|
+
- "취소" → 중단
|
|
457
607
|
|
|
458
|
-
|
|
608
|
+
#### 5-3. 배포 완료 & 온보딩 가이드
|
|
609
|
+
- 배포 결과와 마켓플레이스 URL을 보여줍니다.
|
|
459
610
|
- \`relay publish\` 출력 끝에 코드블록 형태의 온보딩 가이드가 포함됩니다.
|
|
460
611
|
- 이 코드블록을 사용자에게 그대로 보여줍니다.
|
|
461
612
|
- 출력에 코드블록이 없으면 아래 형태로 직접 생성합니다:
|
|
@@ -473,16 +624,22 @@ ${BUSINESS_CARD_FORMAT}
|
|
|
473
624
|
## 예시
|
|
474
625
|
|
|
475
626
|
사용자: /relay-publish
|
|
476
|
-
→ 팀 구조
|
|
477
|
-
→
|
|
478
|
-
→
|
|
479
|
-
→ requires
|
|
480
|
-
→
|
|
481
|
-
→
|
|
482
|
-
→
|
|
483
|
-
→
|
|
627
|
+
→ 인증 확인 ✓, 팀 구조 분석 (skills 3개, commands 5개)
|
|
628
|
+
→ AskUserQuestion: "어디에 배포할까요?" → ["공개 (마켓플레이스)", "비공개 (Space 전용)"]
|
|
629
|
+
→ "공개" 선택
|
|
630
|
+
→ 보안 스캔 ✓ 시크릿 없음 → requires 분석 결과 표시
|
|
631
|
+
→ AskUserQuestion: "requires 설정이 맞나요?" → ["확인", "수정"]
|
|
632
|
+
→ "확인"
|
|
633
|
+
→ 포트폴리오 후보 스캔 → 리스트 표시
|
|
634
|
+
→ AskUserQuestion: "어떤 결과물을 포함할까요?" → ["전체 포함", "1", "2", "건너뛰기"]
|
|
635
|
+
→ "1" 선택
|
|
636
|
+
→ GUIDE.html 생성 → 브라우저 미리보기
|
|
637
|
+
→ AskUserQuestion: "사용가이드 진행할까요?" → ["진행", "수정 요청"]
|
|
638
|
+
→ "진행"
|
|
639
|
+
→ 배포 요약 표시
|
|
640
|
+
→ AskUserQuestion: "이대로 배포할까요?" → ["배포", "취소"]
|
|
641
|
+
→ "배포" → relay publish 실행
|
|
484
642
|
→ "배포 완료! URL: https://relayax.com/teams/my-team"
|
|
485
|
-
→ 온보딩 가이드 코드블록
|
|
486
|
-
→ "이 블록을 팀원에게 공유하면 바로 설치할 수 있습니다"`,
|
|
643
|
+
→ 온보딩 가이드 코드블록 표시`,
|
|
487
644
|
},
|
|
488
645
|
];
|