relayax-cli 0.2.26 → 0.2.28
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 +2 -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 +348 -228
- package/dist/lib/preamble.d.ts +13 -4
- package/dist/lib/preamble.js +53 -13
- 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
|
*/
|
|
@@ -95,36 +110,71 @@ JSON 결과 예시:
|
|
|
95
110
|
// ─── User Commands (글로벌 설치) ───
|
|
96
111
|
exports.USER_COMMANDS = [
|
|
97
112
|
{
|
|
98
|
-
id: 'relay-
|
|
99
|
-
description: 'relay
|
|
100
|
-
body:
|
|
113
|
+
id: 'relay-install',
|
|
114
|
+
description: 'relay 마켓플레이스에서 에이전트 팀을 설치합니다',
|
|
115
|
+
body: `요청된 에이전트 팀을 relay 마켓플레이스에서 다운로드하고, 현재 에이전트 환경에 맞게 구성합니다.
|
|
116
|
+
인자 없이 호출하면 인터랙티브 탐색 모드로 진입합니다.
|
|
101
117
|
|
|
102
|
-
##
|
|
118
|
+
## 인터랙션 플로우
|
|
103
119
|
|
|
104
|
-
|
|
105
|
-
2. \`relay search <keyword>\` 명령어를 실행합니다 (필요하면 여러 키워드로 반복).
|
|
106
|
-
3. 결과를 현재 프로젝트 맥락과 대조하여 가장 도움될 팀을 추천합니다:
|
|
107
|
-
- 팀 이름과 설명
|
|
108
|
-
- 제공하는 커맨드 목록
|
|
109
|
-
- 왜 이 팀이 지금 프로젝트에 맞는지 설명
|
|
110
|
-
4. 관심 있는 팀이 있다면 \`/relay-install <@author/slug>\`로 바로 설치할 수 있다고 안내합니다.
|
|
120
|
+
이 커맨드는 3단계 인터랙션으로 진행됩니다. 각 단계에서 반드시 AskUserQuestion 도구를 사용하세요.
|
|
111
121
|
|
|
112
|
-
|
|
122
|
+
### Step 1. 공간 선택 & 팀 탐색 (slug가 없을 때만)
|
|
113
123
|
|
|
114
|
-
|
|
115
|
-
→ relay search 콘텐츠 실행
|
|
116
|
-
→ 결과 해석: "contents-team이 카드뉴스, PDF, PPT를 만들 수 있어요"
|
|
117
|
-
→ 프로젝트 맥락 기반 추천
|
|
118
|
-
→ "/relay-install @example/contents-team으로 설치할 수 있어요"`,
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
id: 'relay-install',
|
|
122
|
-
description: 'relay 마켓플레이스에서 에이전트 팀을 설치합니다',
|
|
123
|
-
body: `요청된 에이전트 팀을 relay 마켓플레이스에서 다운로드하고, 현재 에이전트 환경에 맞게 구성합니다.
|
|
124
|
+
slug가 직접 주어지면 (\`/relay-install @alice/doc-writer\`) 이 단계를 건너뛰고 Step 2로 갑니다.
|
|
124
125
|
|
|
125
|
-
|
|
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와 동일 형식).
|
|
126
167
|
|
|
127
|
-
|
|
168
|
+
**AskUserQuestion 호출:**
|
|
169
|
+
- question: "어떤 팀을 설치할까요?"
|
|
170
|
+
- options: \`["1", "2", ..., "돌아가기"]\`
|
|
171
|
+
|
|
172
|
+
"돌아가기" → 1-1로 돌아감
|
|
173
|
+
번호 선택 → 해당 팀의 slug로 설치 진행
|
|
174
|
+
|
|
175
|
+
### Step 2. 설치 & 배치 범위 선택
|
|
176
|
+
|
|
177
|
+
#### 2-1. 패키지 다운로드
|
|
128
178
|
\`relay install <@author/slug> --json\` 명령어를 실행합니다.
|
|
129
179
|
- Public 마켓 팀: \`relay install <@author/slug> --json\`
|
|
130
180
|
- Space 팀: \`relay install @spaces/<space-slug>/<team-slug> --json\`
|
|
@@ -133,36 +183,30 @@ exports.USER_COMMANDS = [
|
|
|
133
183
|
- CLI가 init과 login을 자동으로 처리합니다 (사용자가 별도 실행할 필요 없음).
|
|
134
184
|
- JSON 출력에서 \`install_path\` (패키지 경로)를 확인합니다.
|
|
135
185
|
|
|
136
|
-
|
|
137
|
-
사용자에게 설치 범위를 물어봅니다:
|
|
138
|
-
|
|
139
|
-
- **글로벌** (\`~/.claude/\`): 모든 프로젝트에서 사용 가능
|
|
140
|
-
- **로컬** (현재 프로젝트 \`.claude/\`): 이 프로젝트에서만 사용
|
|
186
|
+
#### 2-2. 배치 범위 선택
|
|
141
187
|
|
|
142
|
-
|
|
143
|
-
-
|
|
144
|
-
-
|
|
145
|
-
- Space 비공개 팀: 로컬 추천
|
|
188
|
+
**AskUserQuestion 호출:**
|
|
189
|
+
- question: "어디에 설치할까요?"
|
|
190
|
+
- options: \`["글로벌 (모든 프로젝트)", "로컬 (이 프로젝트만)"]\`
|
|
146
191
|
|
|
147
|
-
|
|
192
|
+
**응답 처리:**
|
|
193
|
+
- "글로벌" → \`~/.claude/\`에 배치
|
|
194
|
+
- "로컬" → 현재 프로젝트 \`.claude/\`에 배치
|
|
148
195
|
|
|
149
|
-
|
|
196
|
+
#### 2-3. 에이전트 환경에 맞게 배치
|
|
150
197
|
다운로드된 패키지(\`install_path\`)에서 파일을 읽고 선택된 범위에 배치합니다:
|
|
151
|
-
-
|
|
152
|
-
-
|
|
153
|
-
- Claude Code 로컬: \`<install_path>/commands/\` → \`.claude/commands/\`에 복사
|
|
154
|
-
- Claude Code 로컬: \`<install_path>/skills/\` → \`.claude/skills/\`에 복사
|
|
198
|
+
- 글로벌: \`<install_path>/commands/\` → \`~/.claude/commands/\`에 복사, skills/ 동일
|
|
199
|
+
- 로컬: \`<install_path>/commands/\` → \`.claude/commands/\`에 복사, skills/ 동일
|
|
155
200
|
- agents/, rules/ 파일도 같은 방식으로 배치합니다.
|
|
156
201
|
- **충돌 확인**: 같은 이름의 파일이 이미 있으면 사용자에게 덮어쓸지 물어봅니다.
|
|
157
202
|
|
|
158
|
-
|
|
159
|
-
배치 완료 후 반드시 \`relay deploy-record\`를
|
|
203
|
+
#### 2-4. 배치 정보 기록 (필수)
|
|
204
|
+
배치 완료 후 반드시 \`relay deploy-record\`를 실행합니다:
|
|
160
205
|
\`\`\`
|
|
161
206
|
relay deploy-record <slug> --scope <global|local> --files <배치된_파일1> <배치된_파일2> ...
|
|
162
207
|
\`\`\`
|
|
163
|
-
이 정보는 \`relay uninstall\` 시 배치된 파일까지 정리하는 데 사용됩니다.
|
|
164
208
|
|
|
165
|
-
|
|
209
|
+
#### 2-5. Requirements 확인 및 설치
|
|
166
210
|
\`<install_path>/relay.yaml\`의 \`requires\` 섹션을 읽고 처리합니다:
|
|
167
211
|
- **cli**: \`which <name>\`으로 확인 → 없으면 install 명령 실행 또는 안내
|
|
168
212
|
- **npm**: \`npm list <package>\`로 확인 → 없으면 \`npm install\`
|
|
@@ -172,12 +216,14 @@ relay deploy-record <slug> --scope <global|local> --files <배치된_파일1> <
|
|
|
172
216
|
- **teams**: 의존하는 다른 팀 → \`relay install <@author/team>\`으로 재귀 설치
|
|
173
217
|
${LOGIN_JIT_GUIDE}
|
|
174
218
|
|
|
175
|
-
###
|
|
219
|
+
### Step 3. 완료 & 팔로우 제안
|
|
220
|
+
|
|
221
|
+
#### 3-1. 완료 안내
|
|
176
222
|
- 배치된 파일과 활성화된 커맨드 목록을 보여줍니다.
|
|
177
223
|
${BUSINESS_CARD_FORMAT}
|
|
178
|
-
|
|
224
|
+
|
|
225
|
+
#### 3-2. 팔로우 제안 (필수 — 이 단계를 절대 건너뛰지 마세요)
|
|
179
226
|
명함 표시 직후, 빌더의 username이 JSON 결과에 있으면 **반드시** AskUserQuestion 도구를 호출하세요.
|
|
180
|
-
텍스트로 질문하지 말고, **AskUserQuestion 도구를 직접 호출**해야 합니다.
|
|
181
227
|
|
|
182
228
|
**AskUserQuestion 호출:**
|
|
183
229
|
- question: \`@{username}을 팔로우할까요? 새 버전 알림을 받을 수 있습니다.\`
|
|
@@ -187,122 +233,128 @@ ${BUSINESS_CARD_FORMAT}
|
|
|
187
233
|
- "팔로우" → \`relay follow @{username}\` 실행. 로그인이 안 되어 있으면 \`relay login\` 먼저 실행 후 재시도.
|
|
188
234
|
- "건너뛰기" → 다음 단계로 진행
|
|
189
235
|
|
|
190
|
-
|
|
236
|
+
#### 3-3. 사용 제안
|
|
191
237
|
- "바로 사용해볼까요?" 제안
|
|
192
238
|
|
|
193
|
-
|
|
239
|
+
#### 3-4. 업데이트 확인
|
|
194
240
|
- \`relay check-update\` 명령어를 실행합니다.
|
|
195
241
|
- CLI 업데이트가 있으면 안내합니다: "relay v{new} available. Run: npm update -g relayax-cli"
|
|
196
242
|
- 다른 팀 업데이트가 있으면 안내합니다.
|
|
197
243
|
|
|
198
244
|
## 예시
|
|
199
245
|
|
|
200
|
-
|
|
201
|
-
→ relay
|
|
202
|
-
→
|
|
203
|
-
→
|
|
204
|
-
→ relay
|
|
205
|
-
→
|
|
206
|
-
→
|
|
207
|
-
→ AskUserQuestion
|
|
208
|
-
→ "
|
|
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를 사용해볼까요?"`,
|
|
209
267
|
},
|
|
210
268
|
{
|
|
211
|
-
id: 'relay-
|
|
212
|
-
description: '설치된
|
|
213
|
-
body: `현재 설치된 에이전트
|
|
269
|
+
id: 'relay-status',
|
|
270
|
+
description: '설치된 팀과 Space 현황을 확인합니다',
|
|
271
|
+
body: `현재 설치된 에이전트 팀과 소속 Space 현황을 한눈에 보여줍니다.
|
|
214
272
|
|
|
215
273
|
## 실행 방법
|
|
216
274
|
|
|
217
|
-
1.
|
|
218
|
-
2. 결과를 사용자에게 보기 좋게 정리하여 보여줍니다:
|
|
219
|
-
- 팀 이름과 버전
|
|
220
|
-
- 설치 날짜
|
|
221
|
-
- 사용 가능한 커맨드
|
|
222
|
-
3. 설치된 팀이 없으면 \`/relay-explore\`로 팀을 탐색해보라고 안내합니다.
|
|
223
|
-
|
|
224
|
-
### Space 팀 목록 확인
|
|
225
|
-
- 특정 Space에서 사용 가능한 팀 목록을 보려면: \`relay list --space <space-slug> --json\`
|
|
226
|
-
- Space에 가입되어 있어야 합니다.
|
|
275
|
+
### 1. 설치된 팀 목록
|
|
227
276
|
|
|
228
|
-
|
|
277
|
+
\`relay list --json\` 명령어를 실행합니다.
|
|
229
278
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
→ " qa-team v0.5.1 (1주 전 설치) - /qa, /qa-only"
|
|
235
|
-
|
|
236
|
-
사용자: /relay-list --space bobusan
|
|
237
|
-
→ relay list --space bobusan --json 실행
|
|
238
|
-
→ "bobusan Space에서 설치 가능한 팀:"
|
|
239
|
-
→ " pm-bot — 프로젝트 관리 봇"
|
|
240
|
-
→ " cs-bot — 고객 응대 봇"`,
|
|
241
|
-
},
|
|
279
|
+
**JSON 응답 구조:**
|
|
280
|
+
\`\`\`json
|
|
281
|
+
{
|
|
282
|
+
"installed": [
|
|
242
283
|
{
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
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
|
+
\`\`\`
|
|
246
294
|
|
|
247
|
-
|
|
295
|
+
**각 팀을 아래 형식으로 표시:**
|
|
248
296
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
-
|
|
252
|
-
- 업데이트 여부와 관계없이 팀 업데이트를 계속 진행합니다.
|
|
253
|
-
|
|
254
|
-
### 특정 팀 업데이트
|
|
255
|
-
- 사용자가 팀 이름을 지정한 경우: \`relay update <@author/slug> --json\` 실행
|
|
256
|
-
- 업데이트 결과를 보여줍니다 (이전 버전 → 새 버전)
|
|
257
|
-
- **재배치 필요 확인**: JSON 출력에 \`needs_redeploy: true\`가 있으면:
|
|
258
|
-
1. \`previous_deploy_scope\`를 참고하여 같은 범위(글로벌/로컬)로 파일을 다시 배치합니다.
|
|
259
|
-
2. 배치 후 \`relay deploy-record <slug> --scope <scope> --files <...>\`를 실행하여 기록합니다.
|
|
260
|
-
${BUSINESS_CARD_FORMAT}
|
|
297
|
+
| 팀 | 버전 | 배포 | 설치일 |
|
|
298
|
+
|---|---|---|---|
|
|
299
|
+
| @author/team-name | v1.2.0 | 글로벌 | 3/20 |
|
|
261
300
|
|
|
262
|
-
|
|
263
|
-
-
|
|
264
|
-
1. \`relay outdated --json\`으로 업데이트 가능한 팀 목록을 확인합니다.
|
|
265
|
-
2. 업데이트 가능한 팀이 있으면 목록을 보여주고 어떤 팀을 업데이트할지 물어봅니다.
|
|
266
|
-
3. 선택된 팀에 대해 \`relay update <@author/slug> --json\`을 실행합니다.
|
|
267
|
-
4. 모두 최신이면 "모든 팀이 최신 버전입니다"라고 안내합니다.
|
|
301
|
+
- \`deploy_scope\`가 \`"global"\` → 글로벌, \`"local"\` → 로컬, 없으면 → 미배치
|
|
302
|
+
- \`space_slug\`가 있으면 \`[Space: slug]\` 표시
|
|
268
303
|
|
|
269
|
-
|
|
304
|
+
### 2. Space 목록
|
|
270
305
|
|
|
271
|
-
|
|
272
|
-
→ relay outdated --json 실행
|
|
273
|
-
→ "1개 팀 업데이트 가능:"
|
|
274
|
-
→ " @example/contents-team: v1.2.0 → v1.3.0"
|
|
275
|
-
→ "업데이트할까요?"
|
|
276
|
-
→ relay update @example/contents-team --json 실행
|
|
277
|
-
→ needs_redeploy: true → 글로벌로 재배치
|
|
278
|
-
→ relay deploy-record @example/contents-team --scope global --files ...
|
|
279
|
-
→ "✓ @example/contents-team v1.3.0으로 업데이트 완료"`,
|
|
280
|
-
},
|
|
281
|
-
{
|
|
282
|
-
id: 'relay-spaces',
|
|
283
|
-
description: '내 Space 목록을 확인합니다',
|
|
284
|
-
body: `사용자의 Space 목록을 조회하고 보여줍니다.
|
|
306
|
+
\`relay spaces --json\` 명령어를 실행합니다.
|
|
285
307
|
|
|
286
|
-
|
|
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
|
+
\`\`\`
|
|
287
322
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
- 팀 스페이스 (이름, 역할, 설명)
|
|
292
|
-
3. Space가 있으면 관련 활용법을 안내합니다:
|
|
293
|
-
- 팀 목록 보기: \`relay list --space <slug>\`
|
|
294
|
-
- 비공개 팀 설치: \`relay install @spaces/<slug>/<team>\`
|
|
295
|
-
- Space 관리: www.relayax.com/spaces/<slug>
|
|
323
|
+
**표시:**
|
|
324
|
+
- \`is_personal: true\` → 개인 스페이스로 분류
|
|
325
|
+
- \`role\`: owner → 소유자, admin → 관리자, member → 멤버
|
|
296
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>
|
|
297
337
|
|
|
298
338
|
## 예시
|
|
299
339
|
|
|
300
|
-
사용자: /relay-
|
|
301
|
-
→ relay
|
|
302
|
-
→
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
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에서 설치 가능한 팀 목록 추가 표시`,
|
|
306
358
|
},
|
|
307
359
|
{
|
|
308
360
|
id: 'relay-uninstall',
|
|
@@ -321,9 +373,9 @@ ${LOGIN_JIT_GUIDE}
|
|
|
321
373
|
|
|
322
374
|
## 예시
|
|
323
375
|
|
|
324
|
-
사용자: /relay-uninstall @
|
|
325
|
-
→ relay uninstall @
|
|
326
|
-
→ "✓ @
|
|
376
|
+
사용자: /relay-uninstall @alice/doc-writer
|
|
377
|
+
→ relay uninstall @alice/doc-writer --json 실행
|
|
378
|
+
→ "✓ @alice/doc-writer 삭제 완료 (12개 파일 제거)"`,
|
|
327
379
|
},
|
|
328
380
|
];
|
|
329
381
|
// ─── Builder Commands (로컬 설치) ───
|
|
@@ -333,51 +385,92 @@ exports.BUILDER_COMMANDS = [
|
|
|
333
385
|
description: '현재 팀 패키지를 포트폴리오와 함께 relay 마켓플레이스에 배포합니다',
|
|
334
386
|
body: `현재 디렉토리의 에이전트 팀(.relay/)을 분석하고, 보안 점검 및 requirements를 구성한 뒤, 사용가이드와 포트폴리오를 생성하고 relay 마켓플레이스에 배포합니다.
|
|
335
387
|
|
|
336
|
-
##
|
|
388
|
+
## 사전 준비 (자동)
|
|
337
389
|
|
|
338
|
-
### 1. 인증 확인
|
|
390
|
+
### 0-1. 인증 확인
|
|
339
391
|
- \`relay status --json\` 명령어를 실행하여 로그인 상태를 확인합니다.
|
|
340
392
|
- 미인증이면 즉시 \`relay login\`을 실행합니다.
|
|
341
|
-
- 로그인 완료 후 다음 단계로 진행합니다.
|
|
342
393
|
${LOGIN_JIT_GUIDE}
|
|
343
394
|
|
|
344
|
-
### 2. 팀 구조 분석
|
|
395
|
+
### 0-2. 팀 구조 분석
|
|
345
396
|
- .relay/ 디렉토리의 skills/, agents/, rules/, commands/를 탐색합니다.
|
|
346
397
|
- 각 파일의 이름과 description을 추출합니다.
|
|
347
398
|
- .relay/relay.yaml이 있으면 읽고, 없으면 사용자에게 팀 정보(name, slug, description, tags)를 물어보고 생성합니다.
|
|
348
399
|
|
|
349
|
-
|
|
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 이미 설정됨)
|
|
425
|
+
|
|
426
|
+
현재 설정을 확인합니다:
|
|
427
|
+
|
|
428
|
+
**AskUserQuestion 호출:**
|
|
429
|
+
- question: 공개일 때 "현재 **공개** 설정입니다. 마켓플레이스에 노출됩니다. 유지할까요?", 비공개일 때 "현재 **비공개** 설정입니다 (Space: {name}). 유지할까요?"
|
|
430
|
+
- options: \`["유지", "변경"]\`
|
|
431
|
+
|
|
432
|
+
"변경" → 신규 배포와 동일한 플로우
|
|
433
|
+
|
|
434
|
+
### Step 2. 보안 점검 & requires 확인
|
|
350
435
|
|
|
351
|
-
.relay/ 내 모든 파일을
|
|
436
|
+
.relay/ 내 모든 파일을 자동 분석합니다.
|
|
352
437
|
|
|
353
|
-
####
|
|
438
|
+
#### 2-1. 시크릿 스캔 (자동)
|
|
354
439
|
- 하드코딩된 API 키, 토큰, 비밀번호, Private Key 등을 탐색합니다.
|
|
355
440
|
- 예: sk-..., ghp_..., AKIA..., Bearer 토큰, JWT, -----BEGIN PRIVATE KEY----- 등
|
|
356
441
|
- 발견 시 **즉시 사용자에게 경고**하고, 환경변수로 대체하도록 안내합니다.
|
|
357
442
|
- 시크릿이 제거되지 않으면 배포를 진행하지 않습니다.
|
|
358
443
|
|
|
359
|
-
####
|
|
360
|
-
|
|
361
|
-
-
|
|
362
|
-
|
|
363
|
-
- 설명을 추가할 수 있습니다.
|
|
364
|
-
|
|
365
|
-
#### 3-3. 의존성 감지
|
|
366
|
-
아래 카테고리별로 분석하고, 사용자에게 필수/선택 여부를 확인합니다:
|
|
367
|
-
|
|
368
|
-
- **cli**: 파일에서 참조하는 CLI 도구 (playwright, ffmpeg, sharp 등)
|
|
444
|
+
#### 2-2. 환경변수 & 의존성 분석 (자동)
|
|
445
|
+
분석 대상:
|
|
446
|
+
- **env**: 환경변수 참조 (process.env.*, \${VAR}, os.environ 등)
|
|
447
|
+
- **cli**: 참조하는 CLI 도구 (playwright, ffmpeg, sharp 등)
|
|
369
448
|
- **npm**: import/require되는 npm 패키지
|
|
370
|
-
- **mcp**: MCP 서버 설정
|
|
371
|
-
- **runtime**: Node.js/Python 등 최소 버전
|
|
372
|
-
- **permissions**: 필요한 에이전트 권한 (filesystem, network, shell)
|
|
449
|
+
- **mcp**: MCP 서버 설정
|
|
450
|
+
- **runtime**: Node.js/Python 등 최소 버전
|
|
373
451
|
- **teams**: 의존하는 다른 relay 팀
|
|
374
452
|
|
|
375
|
-
|
|
376
|
-
- \`required: true/false\` — 없으면 팀이 동작하지 않는지, 부분 동작인지
|
|
377
|
-
- \`description\` — 왜 필요한지 짧은 설명
|
|
453
|
+
분석 결과를 요약 표시합니다:
|
|
378
454
|
|
|
379
|
-
|
|
380
|
-
|
|
455
|
+
\`\`\`
|
|
456
|
+
requires 분석 결과
|
|
457
|
+
|
|
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
|
+
- "수정" → 사용자와 텍스트 대화로 수정 후 다시 확인
|
|
381
474
|
|
|
382
475
|
\`\`\`yaml
|
|
383
476
|
# .relay/relay.yaml requires 구조
|
|
@@ -404,95 +497,116 @@ requires:
|
|
|
404
497
|
command: "npx"
|
|
405
498
|
args: ["-y", "@supabase/mcp-server"]
|
|
406
499
|
env: [SUPABASE_URL, SUPABASE_SECRET_KEY]
|
|
407
|
-
- name: notion
|
|
408
|
-
package: "@notionhq/mcp-server"
|
|
409
|
-
required: false
|
|
410
|
-
env: [NOTION_API_KEY]
|
|
411
500
|
runtime:
|
|
412
501
|
node: ">=18"
|
|
413
502
|
permissions:
|
|
414
503
|
- filesystem
|
|
415
504
|
- network
|
|
416
505
|
teams:
|
|
417
|
-
- @
|
|
506
|
+
- @alice/doc-writer
|
|
507
|
+
\`\`\`
|
|
508
|
+
|
|
509
|
+
### Step 3. 포트폴리오 선택
|
|
510
|
+
|
|
511
|
+
output/, results/, examples/, portfolio/ 디렉토리를 스캔하여 결과물(PNG, JPG, HTML, PDF)을 찾습니다.
|
|
512
|
+
HTML 파일은 Playwright 스크린샷으로 변환합니다.
|
|
513
|
+
|
|
514
|
+
발견된 파일을 번호 리스트로 보여줍니다:
|
|
515
|
+
|
|
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
|
|
418
523
|
\`\`\`
|
|
419
524
|
|
|
420
|
-
|
|
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
|
+
\`\`\`
|
|
421
547
|
|
|
422
|
-
|
|
423
|
-
- 발견된 결과물(PNG, JPG, HTML, PDF)을 사용자에게 보여줍니다.
|
|
424
|
-
- HTML 파일은 Playwright 스크린샷으로 변환합니다.
|
|
425
|
-
- 사용자가 포트폴리오에 포함할 항목을 선택합니다.
|
|
426
|
-
- 선택된 이미지를 .relay/portfolio/에 저장합니다.
|
|
548
|
+
파일이 하나도 발견되지 않으면 이 단계를 건너뜁니다.
|
|
427
549
|
|
|
428
|
-
###
|
|
550
|
+
### Step 4. GUIDE.html 컨펌
|
|
429
551
|
|
|
430
552
|
설치자가 읽을 수 있는 사용가이드를 HTML로 생성합니다.
|
|
431
553
|
|
|
432
|
-
####
|
|
554
|
+
#### 4-1. 팀 소스 분석 (자동)
|
|
433
555
|
- skills/, agents/, commands/ 디렉토리의 **모든 파일 내용**을 읽습니다.
|
|
434
556
|
- 각 스킬의 SKILL.md, 에이전트 설정, 커맨드 문서를 분석하여 팀의 파이프라인 흐름을 추론합니다.
|
|
435
557
|
|
|
436
|
-
####
|
|
558
|
+
#### 4-2. GUIDE.html 생성 (자동)
|
|
437
559
|
- 팀의 핵심 기능, 시작 방법, 파이프라인 흐름, Q&A를 포함하는 단일 HTML 가이드를 생성합니다.
|
|
438
560
|
- 디자인: 깔끔한 단일 페이지, 시스템 폰트, 최대 1200px 너비, 라이트 테마.
|
|
439
|
-
- 5-1에서 분석한 팀 소스 정보를 기반으로 콘텐츠를 구성합니다.
|
|
440
561
|
- 파이프라인이 없는 단순한 팀은 시작 방법 + 기능 설명 + Q&A만 포함합니다.
|
|
441
562
|
|
|
442
|
-
####
|
|
443
|
-
|
|
444
|
-
- 빌더에게 확인: "사용가이드를 확인해주세요. 이대로 진행할까요?"
|
|
563
|
+
#### 4-3. 미리보기 + 컨펌
|
|
564
|
+
생성된 GUIDE.html을 브라우저에서 열어 빌더에게 미리보기를 보여줍니다.
|
|
445
565
|
|
|
446
|
-
|
|
447
|
-
-
|
|
448
|
-
-
|
|
449
|
-
- 빌더가 컨펌할 때까지 반복합니다.
|
|
566
|
+
**AskUserQuestion 호출:**
|
|
567
|
+
- question: "사용가이드를 확인해주세요. 진행할까요?"
|
|
568
|
+
- options: \`["진행", "수정 요청"]\`
|
|
450
569
|
|
|
451
|
-
|
|
452
|
-
-
|
|
570
|
+
**응답 처리:**
|
|
571
|
+
- "진행" → GUIDE.html을 \`.relay/GUIDE.html\`에 저장
|
|
572
|
+
- "수정 요청" → 사용자와 텍스트 대화로 수정사항 파악 → GUIDE.html 재생성 → 다시 미리보기 → AskUserQuestion 반복
|
|
453
573
|
|
|
454
|
-
####
|
|
455
|
-
- GUIDE.html을 Playwright로 열어 첫 화면(뷰포트 1200x630)을 스크린샷 캡처합니다.
|
|
574
|
+
#### 4-4. GUIDE.html 스크린샷 → gallery 등록 (자동)
|
|
575
|
+
- GUIDE.html을 Playwright로 열어 첫 화면(뷰포트 1200x630)을 스크린샷 캡처합니다.
|
|
456
576
|
- 결과 PNG를 \`./portfolio/guide-preview.png\`에 저장합니다.
|
|
457
577
|
- relay.yaml의 portfolio gallery 첫 번째 항목으로 자동 등록합니다.
|
|
458
578
|
- 이 이미지는 마켓플레이스 카드 및 OG 이미지의 fallback으로 사용됩니다 (demo > gallery 순).
|
|
459
579
|
|
|
460
|
-
###
|
|
580
|
+
### Step 5. 최종 확인 & 배포
|
|
581
|
+
|
|
582
|
+
#### 5-1. 메타데이터 생성 (자동)
|
|
461
583
|
- description: skills 내용 기반으로 자동 생성합니다.
|
|
462
584
|
- long_description: 팀 소개 마크다운을 자동 생성합니다 (README.md가 있으면 활용).
|
|
463
585
|
- tags: 팀 특성에 맞는 태그를 추천합니다.
|
|
464
|
-
- 사용자에게 확인: "이대로 배포할까요?"
|
|
465
586
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
- 설정되어 있지 않으면 빌더에게 반드시 물어봅니다:
|
|
469
|
-
- "공개 (마켓플레이스에 누구나 검색·설치 가능)" vs "비공개 (Space 멤버만 접근)"
|
|
470
|
-
- 선택 결과를 relay.yaml에 저장합니다.
|
|
471
|
-
- 이미 설정되어 있으면 현재 값을 확인합니다:
|
|
472
|
-
- 공개인 경우: "⚠ 이 팀은 **공개**로 설정되어 있어 마켓플레이스에 노출됩니다. 맞나요?"
|
|
473
|
-
- 비공개인 경우: "이 팀은 **비공개**로 설정되어 Space 멤버만 접근 가능합니다."
|
|
474
|
-
- 빌더가 변경을 원하면 relay.yaml을 업데이트합니다.
|
|
587
|
+
#### 5-2. 배포 요약 + 최종 확인
|
|
588
|
+
배포할 내용을 요약 표시합니다:
|
|
475
589
|
|
|
476
|
-
|
|
477
|
-
|
|
590
|
+
\`\`\`
|
|
591
|
+
배포 요약
|
|
478
592
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
gallery: # 선택, 최대 5장
|
|
485
|
-
- path: portfolio/guide-preview.png
|
|
486
|
-
title: "사용가이드 미리보기"
|
|
487
|
-
- path: portfolio/example-1.png
|
|
488
|
-
title: "카드뉴스 예시"
|
|
593
|
+
팀: my-team v1.0.0
|
|
594
|
+
공개: 마켓플레이스 (공개)
|
|
595
|
+
Skills: 3개, Commands: 5개
|
|
596
|
+
포트폴리오: 2장
|
|
597
|
+
requires: env 2개, cli 1개
|
|
489
598
|
\`\`\`
|
|
490
599
|
|
|
491
|
-
|
|
492
|
-
-
|
|
493
|
-
- 배포
|
|
600
|
+
**AskUserQuestion 호출:**
|
|
601
|
+
- question: "이대로 배포할까요?"
|
|
602
|
+
- options: \`["배포", "취소"]\`
|
|
603
|
+
|
|
604
|
+
**응답 처리:**
|
|
605
|
+
- "배포" → \`relay publish\` 실행
|
|
606
|
+
- "취소" → 중단
|
|
494
607
|
|
|
495
|
-
|
|
608
|
+
#### 5-3. 배포 완료 & 온보딩 가이드
|
|
609
|
+
- 배포 결과와 마켓플레이스 URL을 보여줍니다.
|
|
496
610
|
- \`relay publish\` 출력 끝에 코드블록 형태의 온보딩 가이드가 포함됩니다.
|
|
497
611
|
- 이 코드블록을 사용자에게 그대로 보여줍니다.
|
|
498
612
|
- 출력에 코드블록이 없으면 아래 형태로 직접 생성합니다:
|
|
@@ -510,16 +624,22 @@ ${BUSINESS_CARD_FORMAT}
|
|
|
510
624
|
## 예시
|
|
511
625
|
|
|
512
626
|
사용자: /relay-publish
|
|
513
|
-
→ 팀 구조
|
|
514
|
-
→
|
|
515
|
-
→
|
|
516
|
-
→ requires
|
|
517
|
-
→
|
|
518
|
-
→
|
|
519
|
-
→
|
|
520
|
-
→
|
|
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 실행
|
|
521
642
|
→ "배포 완료! URL: https://relayax.com/teams/my-team"
|
|
522
|
-
→ 온보딩 가이드 코드블록
|
|
523
|
-
→ "이 블록을 팀원에게 공유하면 바로 설치할 수 있습니다"`,
|
|
643
|
+
→ 온보딩 가이드 코드블록 표시`,
|
|
524
644
|
},
|
|
525
645
|
];
|