binary-agents 1.0.2 → 1.0.3

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 CHANGED
@@ -1,10 +1,10 @@
1
1
  # Binary Agents
2
2
 
3
- Claude Code 서브에이전트 컬렉션 동기화 도구
3
+ Claude Code 서브에이전트 및 슬래시 명령어 컬렉션 + 동기화 도구
4
4
 
5
5
  ## 소개
6
6
 
7
- `binary-agents`는 Claude Code의 강력한 서브에이전트들을 모아놓은 모노레포입니다. 코드 리뷰, 리팩토링 분석, 주니어 개발자 친화성 체크 등 다양한 서브에이전트와 이를 프로젝트에 쉽게 설치할 수 있는 CLI 도구를 제공합니다.
7
+ `binary-agents`는 Claude Code의 강력한 서브에이전트와 슬래시 명령어를 모아놓은 모노레포입니다. 코드 리뷰, 리팩토링 분석, 주니어 개발자 친화성 체크 등 다양한 서브에이전트와 자동 커밋 등의 슬래시 명령어를 제공하며, 이를 프로젝트에 쉽게 설치할 수 있는 CLI 도구를 포함합니다.
8
8
 
9
9
  ## 설치
10
10
 
@@ -32,39 +32,48 @@ npx binary-agents sync
32
32
 
33
33
  ## 사용법
34
34
 
35
- ### 로컬 프로젝트에 설치 (기본)
35
+ ### 기본 동기화
36
36
 
37
- 현재 프로젝트의 `.claude/agents/` 디렉토리에 설치:
37
+ 현재 프로젝트의 `.claude/` 디렉토리에 agents와 commands 모두 설치:
38
38
 
39
39
  ```bash
40
- # 모든 서브에이전트 동기화
41
40
  npx binary-agents sync
41
+ ```
42
+
43
+ ### 선택적 동기화
44
+
45
+ ```bash
46
+ # 서브에이전트만 동기화
47
+ npx binary-agents sync --agents
42
48
 
43
- # 기본 버전만 (Haiku 모델)
44
- npx binary-agents sync --basic
49
+ # 슬래시 명령어만 동기화
50
+ npx binary-agents sync --commands
45
51
 
46
- # 고급 버전만 (Sonnet 모델)
47
- npx binary-agents sync --advanced
52
+ # 기본 서브에이전트만 (Haiku 모델)
53
+ npx binary-agents sync --agents --basic
54
+
55
+ # 고급 서브에이전트만 (Opus 모델)
56
+ npx binary-agents sync --agents --advanced
48
57
  ```
49
58
 
50
59
  ### 전역 설치
51
60
 
52
- 홈 디렉토리의 `~/.claude/agents/`에 설치 (모든 프로젝트에서 사용 가능):
61
+ 홈 디렉토리의 `~/.claude/`에 설치 (모든 프로젝트에서 사용 가능):
53
62
 
54
63
  ```bash
55
- # 전역으로 모든 서브에이전트 설치
64
+ # 전역으로 모두 설치
56
65
  npx binary-agents sync --global
57
66
  # 또는
58
67
  npx binary-agents sync -g
59
68
 
60
- # 전역 + 기본 버전만
61
- npx binary-agents sync --global --basic
69
+ # 전역 + 서브에이전트만
70
+ npx binary-agents sync -g --agents
62
71
 
63
- # 전역 + 고급 버전만
64
- npx binary-agents sync --global --advanced
72
+ # 전역 + 슬래시 명령어만
73
+ npx binary-agents sync -g --commands
65
74
  ```
66
75
 
67
- ### 사용 가능한 서브에이전트 목록 보기
76
+ ### 목록 보기
68
77
 
69
78
  ```bash
70
79
  npx binary-agents list
@@ -73,17 +82,43 @@ npx binary-agents list
73
82
  ## 서브에이전트 종류
74
83
 
75
84
  ### 기본 버전 (Haiku 모델)
76
- - `code-reviewer.md` - 코드 리뷰어
77
- - `refactor-analyzer.md` - 리팩토링 분석기
78
- - `junior-friendly-checker.md` - 주니어 친화성 체커
85
+ | 이름 | 설명 |
86
+ |------|------|
87
+ | `code-reviewer` | 코드 리뷰어 |
88
+ | `refactor-analyzer` | 리팩토링 분석기 |
89
+ | `junior-friendly-checker` | 주니어 친화성 체커 |
79
90
 
80
91
  ### 고급 버전 (Opus 모델)
81
- - `advanced-code-reviewer.md` - 고급 코드 리뷰어
82
- - `advanced-refactor-analyzer.md` - 고급 리팩토링 분석기
83
- - `advanced-junior-checker.md` - 고급 주니어 친화성 체커
84
- - `react-performance-optimizer.md` - React 성능 최적화
85
- - `toss-cohesion-analyzer.md` - Toss 응집도 분석기
86
- - `subagent-builder.md` - 서브에이전트 빌더
92
+ | 이름 | 설명 |
93
+ |------|------|
94
+ | `advanced-code-reviewer` | 고급 코드 리뷰어 (웹 검색 포함) |
95
+ | `advanced-refactor-analyzer` | 고급 리팩토링 분석기 (웹 검색 포함) |
96
+ | `advanced-junior-checker` | 고급 주니어 친화성 체커 (웹 검색 포함) |
97
+ | `react-performance-optimizer` | React 성능 최적화 |
98
+ | `toss-cohesion-analyzer` | Toss 팀 원칙 기반 응집도 분석기 |
99
+ | `subagent-builder` | 커스텀 서브에이전트 빌더 |
100
+
101
+ ## 슬래시 명령어
102
+
103
+ | 명령어 | 설명 |
104
+ |--------|------|
105
+ | `/commit` | git log 분석 후 컨벤션에 맞는 커밋 메시지 자동 생성 및 커밋 |
106
+
107
+ ### /commit 사용법
108
+
109
+ ```bash
110
+ # 1. 변경 사항 스테이징
111
+ git add .
112
+
113
+ # 2. Claude Code에서 /commit 실행
114
+ /commit
115
+ ```
116
+
117
+ Claude가 자동으로:
118
+ 1. 최근 커밋 로그에서 컨벤션 분석
119
+ 2. staged changes 확인
120
+ 3. 컨벤션에 맞는 커밋 메시지 생성
121
+ 4. 커밋 실행
87
122
 
88
123
  ## 저장소 구조
89
124
 
@@ -99,6 +134,8 @@ binary-agents/
99
134
  │ ├── toss-cohesion-analyzer.md
100
135
  │ ├── react-performance-optimizer.md
101
136
  │ └── subagent-builder.md
137
+ ├── commands/ # 슬래시 명령어 MD 파일들
138
+ │ └── commit.md
102
139
  ├── bin/ # CLI 실행 파일
103
140
  ├── src/ # CLI 소스 코드
104
141
  ├── docs/ # 문서
@@ -110,9 +147,9 @@ binary-agents/
110
147
 
111
148
  ## 작동 원리
112
149
 
113
- 1. 로컬 `agents/` 디렉토리에서 서브에이전트 파일 목록 읽기
150
+ 1. 로컬 `agents/`, `commands/` 디렉토리에서 파일 목록 읽기
114
151
  2. YAML frontmatter 검증
115
- 3. 사용자 프로젝트의 `.claude/agents/` 디렉토리로 복사
152
+ 3. 사용자 프로젝트의 `.claude/agents/`, `.claude/commands/` 디렉토리로 복사
116
153
 
117
154
  ## 요구사항
118
155
 
@@ -126,23 +163,24 @@ MIT
126
163
 
127
164
  이슈 및 PR을 환영합니다!
128
165
 
129
- ## 서브에이전트 직접 사용하기
166
+ ## 직접 사용하기
167
+
168
+ NPM 패키지를 설치하지 않고 이 저장소의 파일을 직접 사용할 수도 있습니다:
130
169
 
131
- NPM 패키지를 설치하지 않고 이 저장소의 서브에이전트를 직접 사용할 수도 있습니다:
170
+ ```bash
171
+ # 저장소 클론
172
+ git clone https://github.com/01-binary/binary-agents.git
132
173
 
133
- 1. 저장소 클론:
134
- ```bash
135
- git clone https://github.com/01-binary/binary-agents.git
136
- ```
174
+ # 서브에이전트 복사
175
+ cp binary-agents/agents/*.md your-project/.claude/agents/
137
176
 
138
- 2. 원하는 서브에이전트 파일을 프로젝트의 `.claude/agents/` 디렉토리로 복사:
139
- ```bash
140
- cp binary-agents/agents/*.md your-project/.claude/agents/
141
- ```
177
+ # 슬래시 명령어 복사
178
+ cp binary-agents/commands/*.md your-project/.claude/commands/
179
+ ```
142
180
 
143
181
  ## 관련 링크
144
182
 
145
- - [Claude Code Documentation](https://docs.claude.com/en/docs/claude-code)
183
+ - [Claude Code Documentation](https://docs.anthropic.com/en/docs/claude-code)
146
184
  - [서브에이전트 상세 가이드](docs/SUBAGENTS.md)
147
185
  - [Basic vs Advanced 비교](docs/COMPARISON.md)
148
186
  - [커스텀 서브에이전트 제작](docs/BUILDER_GUIDE.md)
package/bin/cli.js CHANGED
@@ -13,10 +13,12 @@ program
13
13
 
14
14
  program
15
15
  .command('sync')
16
- .description('Sync subagent files to .claude/agents/ (local) or ~/.claude/agents (global)')
16
+ .description('Sync agents and commands to .claude/ (local) or ~/.claude/ (global)')
17
17
  .option('--basic', 'Sync only basic (Haiku) subagents')
18
- .option('--advanced', 'Sync only advanced (Sonnet) subagents')
19
- .option('-g, --global', 'Install to ~/.claude/agents instead of current directory')
18
+ .option('--advanced', 'Sync only advanced (Opus) subagents')
19
+ .option('-g, --global', 'Install to ~/.claude/ instead of current directory')
20
+ .option('--agents', 'Sync only agents (subagents)')
21
+ .option('--commands', 'Sync only commands (slash commands)')
20
22
  .action(async (options) => {
21
23
  let filter = null;
22
24
 
@@ -26,9 +28,15 @@ program
26
28
  filter = 'advanced';
27
29
  }
28
30
 
31
+ // --agents 또는 --commands가 명시되지 않으면 둘 다 동기화
32
+ const syncAgents = options.agents || (!options.agents && !options.commands);
33
+ const syncCommands = options.commands || (!options.agents && !options.commands);
34
+
29
35
  const result = await syncSubagents({
30
36
  filter,
31
- global: options.global || false
37
+ global: options.global || false,
38
+ agents: syncAgents,
39
+ commands: syncCommands
32
40
  });
33
41
 
34
42
  if (!result.success) {
@@ -38,7 +46,7 @@ program
38
46
 
39
47
  program
40
48
  .command('list')
41
- .description('List available subagents')
49
+ .description('List available agents and commands')
42
50
  .action(async () => {
43
51
  await listSubagents();
44
52
  });
@@ -0,0 +1,53 @@
1
+ ---
2
+ description: Analyze staged changes and recent commits to generate a conventional commit
3
+ allowed-tools: Bash(git status:*), Bash(git diff:*), Bash(git log:*), Bash(git commit:*)
4
+ ---
5
+
6
+ # Auto Commit Generator
7
+
8
+ You are a commit message generator that analyzes the project's commit conventions and staged changes to create appropriate commit messages.
9
+
10
+ ## Context Information
11
+
12
+ **Recent commit history (for convention analysis):**
13
+ !`git log --oneline -20`
14
+
15
+ **Staged changes summary:**
16
+ !`git diff --cached --stat`
17
+
18
+ **Staged changes detail:**
19
+ !`git diff --cached`
20
+
21
+ **Unstaged files (for reference):**
22
+ !`git status --short`
23
+
24
+ ## Your Task
25
+
26
+ 1. **Analyze the commit convention** from the recent commit history above
27
+ - Identify the pattern (e.g., `type: message`, `type(scope): message`, `[type] message`, emoji usage, etc.)
28
+ - Note the language used (English/Korean/etc.)
29
+ - Observe the message style (imperative, past tense, etc.)
30
+
31
+ 2. **Understand the staged changes**
32
+ - What files were modified/added/deleted?
33
+ - What is the main purpose of these changes?
34
+ - Are there multiple logical changes that should be separate commits?
35
+
36
+ 3. **Generate the commit message**
37
+ - Follow the detected convention exactly
38
+ - Keep the subject line concise (50 chars recommended, 72 max)
39
+ - If the changes are complex, suggest a body with bullet points
40
+
41
+ 4. **Execute the commit**
42
+ - Run `git commit -m "message"` with the generated message
43
+ - If a body is needed, use the multi-line format
44
+
45
+ ## Output Format
46
+
47
+ First, briefly explain:
48
+ - Detected convention pattern
49
+ - Summary of changes
50
+
51
+ Then execute the commit command directly.
52
+
53
+ If there are no staged changes, inform the user and suggest using `git add` first.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "binary-agents",
3
- "version": "1.0.2",
4
- "description": "Claude Code subagents collection with sync CLI tool",
3
+ "version": "1.0.3",
4
+ "description": "Claude Code subagents and slash commands collection with sync CLI tool",
5
5
  "type": "module",
6
6
  "main": "src/sync.js",
7
7
  "bin": {
@@ -16,6 +16,7 @@
16
16
  "claude",
17
17
  "claude-code",
18
18
  "subagents",
19
+ "slash-commands",
19
20
  "sync",
20
21
  "cli",
21
22
  "code-review",
@@ -29,6 +30,7 @@
29
30
  },
30
31
  "files": [
31
32
  "agents",
33
+ "commands",
32
34
  "bin",
33
35
  "src",
34
36
  "docs",
package/src/sync.js CHANGED
@@ -7,8 +7,9 @@ import ora from 'ora';
7
7
  const __filename = fileURLToPath(import.meta.url);
8
8
  const __dirname = path.dirname(__filename);
9
9
 
10
- // 모노레포의 agents 디렉토리 경로
10
+ // 모노레포의 agents, commands 디렉토리 경로
11
11
  const REPO_AGENTS_DIR = path.join(__dirname, '..', 'agents');
12
+ const REPO_COMMANDS_DIR = path.join(__dirname, '..', 'commands');
12
13
 
13
14
  /**
14
15
  * 로컬 agents 디렉토리에서 서브에이전트 파일 목록 가져오기
@@ -29,6 +30,22 @@ async function fetchSubagentFiles() {
29
30
  }
30
31
  }
31
32
 
33
+ /**
34
+ * 로컬 commands 디렉토리에서 슬래시 명령어 파일 목록 가져오기
35
+ */
36
+ async function fetchCommandFiles() {
37
+ try {
38
+ const files = await fs.readdir(REPO_COMMANDS_DIR);
39
+
40
+ // .md 파일만 필터링
41
+ const commandFiles = files.filter(file => file.endsWith('.md'));
42
+
43
+ return commandFiles;
44
+ } catch (error) {
45
+ throw new Error(`Failed to read commands directory: ${error.message}`);
46
+ }
47
+ }
48
+
32
49
  /**
33
50
  * YAML frontmatter가 있는지 검증
34
51
  */
@@ -38,7 +55,7 @@ function validateYamlFrontmatter(content) {
38
55
  }
39
56
 
40
57
  /**
41
- * 로컬에서 파일 읽기
58
+ * 로컬에서 에이전트 파일 읽기
42
59
  */
43
60
  async function readAgentFile(filename) {
44
61
  const filePath = path.join(REPO_AGENTS_DIR, filename);
@@ -53,28 +70,44 @@ async function readAgentFile(filename) {
53
70
  }
54
71
 
55
72
  /**
56
- * .claude/agents 디렉토리 생성
57
- * @param {boolean} isGlobal - true면 ~/.claude/agents, false면 현재 디렉토리의 .claude/agents
73
+ * 로컬에서 커맨드 파일 읽기
58
74
  */
59
- async function ensureAgentsDirectory(isGlobal = false) {
60
- let agentsDir;
75
+ async function readCommandFile(filename) {
76
+ const filePath = path.join(REPO_COMMANDS_DIR, filename);
77
+ const content = await fs.readFile(filePath, 'utf-8');
78
+
79
+ // YAML frontmatter 검증
80
+ if (!validateYamlFrontmatter(content)) {
81
+ throw new Error(`Invalid YAML frontmatter in ${filename}`);
82
+ }
83
+
84
+ return content;
85
+ }
86
+
87
+ /**
88
+ * .claude 하위 디렉토리 생성
89
+ * @param {string} subdir - 하위 디렉토리 이름 ('agents' 또는 'commands')
90
+ * @param {boolean} isGlobal - true면 ~/.claude/{subdir}, false면 현재 디렉토리의 .claude/{subdir}
91
+ */
92
+ async function ensureClaudeDirectory(subdir, isGlobal = false) {
93
+ let targetDir;
61
94
 
62
95
  if (isGlobal) {
63
- // 전역 설치: ~/.claude/agents
96
+ // 전역 설치: ~/.claude/{subdir}
64
97
  const homeDir = process.env.HOME || process.env.USERPROFILE;
65
- agentsDir = path.join(homeDir, '.claude', 'agents');
98
+ targetDir = path.join(homeDir, '.claude', subdir);
66
99
  } else {
67
- // 로컬 설치: 현재 디렉토리의 .claude/agents
68
- agentsDir = path.join(process.cwd(), '.claude', 'agents');
100
+ // 로컬 설치: 현재 디렉토리의 .claude/{subdir}
101
+ targetDir = path.join(process.cwd(), '.claude', subdir);
69
102
  }
70
103
 
71
104
  try {
72
- await fs.access(agentsDir);
105
+ await fs.access(targetDir);
73
106
  } catch {
74
- await fs.mkdir(agentsDir, { recursive: true });
107
+ await fs.mkdir(targetDir, { recursive: true });
75
108
  }
76
109
 
77
- return agentsDir;
110
+ return targetDir;
78
111
  }
79
112
 
80
113
  /**
@@ -87,19 +120,15 @@ async function saveFile(agentsDir, filename, content) {
87
120
  }
88
121
 
89
122
  /**
90
- * 서브에이전트 동기화 메인 함수
123
+ * 서브에이전트 동기화
91
124
  */
92
- export async function syncSubagents(options = {}) {
93
- const { filter = null, global = false } = options;
125
+ async function syncAgentsOnly(options = {}) {
126
+ const { filter = null, global: isGlobal = false } = options;
94
127
 
95
- console.log(chalk.blue.bold('\n🤖 Binary Agents Sync\n'));
96
-
97
- if (global) {
98
- console.log(chalk.cyan('📍 Global mode: Installing to ~/.claude/agents\n'));
99
- }
128
+ console.log(chalk.yellow.bold('\n📦 Syncing Agents...\n'));
100
129
 
101
130
  // 로컬 agents 디렉토리에서 파일 목록 가져오기
102
- const fetchSpinner = ora('Reading subagent files from local repository...').start();
131
+ const fetchSpinner = ora('Reading subagent files...').start();
103
132
  let allFiles;
104
133
 
105
134
  try {
@@ -107,7 +136,7 @@ export async function syncSubagents(options = {}) {
107
136
  fetchSpinner.succeed(chalk.green(`Found ${allFiles.length} subagent files`));
108
137
  } catch (error) {
109
138
  fetchSpinner.fail(chalk.red(`Failed to read file list: ${error.message}`));
110
- return { success: false, error: error.message };
139
+ return { success: false, error: error.message, type: 'agents' };
111
140
  }
112
141
 
113
142
  // 필터링된 파일 목록
@@ -122,17 +151,17 @@ export async function syncSubagents(options = {}) {
122
151
  }
123
152
 
124
153
  // .claude/agents 디렉토리 생성
125
- const dirMessage = global ? 'Creating ~/.claude/agents directory...' : 'Creating .claude/agents directory...';
154
+ const dirMessage = isGlobal ? 'Creating ~/.claude/agents directory...' : 'Creating .claude/agents directory...';
126
155
  const dirSpinner = ora(dirMessage).start();
127
156
  let agentsDir;
128
157
 
129
158
  try {
130
- agentsDir = await ensureAgentsDirectory(global);
131
- const successMessage = global ? 'Created ~/.claude/agents directory' : 'Created .claude/agents directory';
159
+ agentsDir = await ensureClaudeDirectory('agents', isGlobal);
160
+ const successMessage = isGlobal ? 'Created ~/.claude/agents directory' : 'Created .claude/agents directory';
132
161
  dirSpinner.succeed(chalk.green(successMessage));
133
162
  } catch (error) {
134
163
  dirSpinner.fail(chalk.red(`Failed to create directory: ${error.message}`));
135
- return { success: false, error: error.message };
164
+ return { success: false, error: error.message, type: 'agents' };
136
165
  }
137
166
 
138
167
  // 각 파일 복사
@@ -145,12 +174,71 @@ export async function syncSubagents(options = {}) {
145
174
  const fileSpinner = ora(`Copying ${filename}...`).start();
146
175
 
147
176
  try {
148
- // 로컬 파일 읽기
149
177
  const content = await readAgentFile(filename);
178
+ await saveFile(agentsDir, filename, content);
179
+ fileSpinner.succeed(chalk.green(`✓ ${filename}`));
180
+ results.success.push(filename);
181
+ } catch (error) {
182
+ fileSpinner.fail(chalk.red(`✗ ${filename}: ${error.message}`));
183
+ results.failed.push({ filename, error: error.message });
184
+ }
185
+ }
186
+
187
+ return {
188
+ success: results.failed.length === 0,
189
+ results,
190
+ type: 'agents',
191
+ dir: agentsDir,
192
+ total: filesToSync.length
193
+ };
194
+ }
195
+
196
+ /**
197
+ * 슬래시 명령어 동기화
198
+ */
199
+ async function syncCommandsOnly(options = {}) {
200
+ const { global: isGlobal = false } = options;
201
+
202
+ console.log(chalk.yellow.bold('\n⚡ Syncing Commands...\n'));
203
+
204
+ // 로컬 commands 디렉토리에서 파일 목록 가져오기
205
+ const fetchSpinner = ora('Reading command files...').start();
206
+ let allFiles;
207
+
208
+ try {
209
+ allFiles = await fetchCommandFiles();
210
+ fetchSpinner.succeed(chalk.green(`Found ${allFiles.length} command files`));
211
+ } catch (error) {
212
+ fetchSpinner.fail(chalk.red(`Failed to read file list: ${error.message}`));
213
+ return { success: false, error: error.message, type: 'commands' };
214
+ }
150
215
 
151
- // 저장
152
- const filePath = await saveFile(agentsDir, filename, content);
216
+ // .claude/commands 디렉토리 생성
217
+ const dirMessage = isGlobal ? 'Creating ~/.claude/commands directory...' : 'Creating .claude/commands directory...';
218
+ const dirSpinner = ora(dirMessage).start();
219
+ let commandsDir;
220
+
221
+ try {
222
+ commandsDir = await ensureClaudeDirectory('commands', isGlobal);
223
+ const successMessage = isGlobal ? 'Created ~/.claude/commands directory' : 'Created .claude/commands directory';
224
+ dirSpinner.succeed(chalk.green(successMessage));
225
+ } catch (error) {
226
+ dirSpinner.fail(chalk.red(`Failed to create directory: ${error.message}`));
227
+ return { success: false, error: error.message, type: 'commands' };
228
+ }
153
229
 
230
+ // 각 파일 복사
231
+ const results = {
232
+ success: [],
233
+ failed: []
234
+ };
235
+
236
+ for (const filename of allFiles) {
237
+ const fileSpinner = ora(`Copying ${filename}...`).start();
238
+
239
+ try {
240
+ const content = await readCommandFile(filename);
241
+ await saveFile(commandsDir, filename, content);
154
242
  fileSpinner.succeed(chalk.green(`✓ ${filename}`));
155
243
  results.success.push(filename);
156
244
  } catch (error) {
@@ -159,49 +247,108 @@ export async function syncSubagents(options = {}) {
159
247
  }
160
248
  }
161
249
 
250
+ return {
251
+ success: results.failed.length === 0,
252
+ results,
253
+ type: 'commands',
254
+ dir: commandsDir,
255
+ total: allFiles.length
256
+ };
257
+ }
258
+
259
+ /**
260
+ * 메인 동기화 함수
261
+ */
262
+ export async function syncSubagents(options = {}) {
263
+ const { filter = null, global: isGlobal = false, agents = true, commands = true } = options;
264
+
265
+ console.log(chalk.blue.bold('\n🤖 Binary Agents Sync\n'));
266
+
267
+ if (isGlobal) {
268
+ console.log(chalk.cyan('📍 Global mode: Installing to ~/.claude/\n'));
269
+ }
270
+
271
+ const syncResults = [];
272
+
273
+ // Agents 동기화
274
+ if (agents) {
275
+ const agentResult = await syncAgentsOnly({ filter, global: isGlobal });
276
+ syncResults.push(agentResult);
277
+ }
278
+
279
+ // Commands 동기화
280
+ if (commands) {
281
+ const commandResult = await syncCommandsOnly({ global: isGlobal });
282
+ syncResults.push(commandResult);
283
+ }
284
+
162
285
  // 결과 요약
163
286
  console.log(chalk.blue.bold('\n📊 Sync Summary\n'));
164
- console.log(chalk.green(`✓ Successful: ${results.success.length}/${filesToSync.length}`));
165
287
 
166
- if (results.failed.length > 0) {
167
- console.log(chalk.red(`✗ Failed: ${results.failed.length}/${filesToSync.length}`));
168
- console.log(chalk.red('\nFailed files:'));
169
- results.failed.forEach(({ filename, error }) => {
170
- console.log(chalk.red(` - ${filename}: ${error}`));
171
- });
288
+ for (const result of syncResults) {
289
+ if (result.error) {
290
+ console.log(chalk.red(`✗ ${result.type}: Failed - ${result.error}`));
291
+ } else {
292
+ const icon = result.type === 'agents' ? '🤖' : '⚡';
293
+ console.log(chalk.green(`${icon} ${result.type}: ${result.results.success.length}/${result.total} successful`));
294
+
295
+ if (result.results.failed.length > 0) {
296
+ console.log(chalk.red(` Failed files:`));
297
+ result.results.failed.forEach(({ filename, error }) => {
298
+ console.log(chalk.red(` - ${filename}: ${error}`));
299
+ });
300
+ }
301
+
302
+ console.log(chalk.cyan(` 📁 Location: ${result.dir}`));
303
+ }
172
304
  }
173
305
 
174
- console.log(chalk.cyan(`\n📁 Location: ${agentsDir}\n`));
306
+ console.log('');
175
307
 
308
+ const allSuccess = syncResults.every(r => r.success);
176
309
  return {
177
- success: results.failed.length === 0,
178
- results
310
+ success: allSuccess,
311
+ results: syncResults
179
312
  };
180
313
  }
181
314
 
182
315
  /**
183
- * 사용 가능한 서브에이전트 목록 표시
316
+ * 사용 가능한 서브에이전트 및 명령어 목록 표시
184
317
  */
185
318
  export async function listSubagents() {
186
- console.log(chalk.blue.bold('\n🤖 Available Subagents\n'));
319
+ console.log(chalk.blue.bold('\n🤖 Binary Agents - Available Items\n'));
187
320
 
188
- const spinner = ora('Reading subagent files from local repository...').start();
321
+ // Agents 목록
322
+ const agentSpinner = ora('Reading subagent files...').start();
189
323
 
190
324
  try {
191
- const files = await fetchSubagentFiles();
192
- spinner.succeed(chalk.green('Found subagent files'));
325
+ const agentFiles = await fetchSubagentFiles();
326
+ agentSpinner.succeed(chalk.green(`Found ${agentFiles.length} subagent files`));
193
327
 
194
- const basic = files.filter(f => !f.startsWith('advanced-'));
195
- const advanced = files.filter(f => f.startsWith('advanced-'));
328
+ const basic = agentFiles.filter(f => !f.startsWith('advanced-'));
329
+ const advanced = agentFiles.filter(f => f.startsWith('advanced-'));
196
330
 
197
- console.log(chalk.yellow('\nBasic (Haiku model):'));
198
- basic.forEach(f => console.log(chalk.white(` • ${f}`)));
331
+ console.log(chalk.yellow('\n📦 Agents - Basic (Haiku model):'));
332
+ basic.forEach(f => console.log(chalk.white(` • ${f.replace('.md', '')}`)));
199
333
 
200
- console.log(chalk.yellow('\nAdvanced (Sonnet model):'));
201
- advanced.forEach(f => console.log(chalk.white(` • ${f}`)));
334
+ console.log(chalk.yellow('\n📦 Agents - Advanced (Opus model):'));
335
+ advanced.forEach(f => console.log(chalk.white(` • ${f.replace('.md', '')}`)));
336
+ } catch (error) {
337
+ agentSpinner.fail(chalk.red(`Failed to read agents: ${error.message}`));
338
+ }
339
+
340
+ // Commands 목록
341
+ const commandSpinner = ora('Reading command files...').start();
202
342
 
203
- console.log(chalk.cyan(`\nTotal: ${files.length} subagents\n`));
343
+ try {
344
+ const commandFiles = await fetchCommandFiles();
345
+ commandSpinner.succeed(chalk.green(`Found ${commandFiles.length} command files`));
346
+
347
+ console.log(chalk.yellow('\n⚡ Commands (Slash commands):'));
348
+ commandFiles.forEach(f => console.log(chalk.white(` • /${f.replace('.md', '')}`)));
204
349
  } catch (error) {
205
- spinner.fail(chalk.red(`Failed to read file list: ${error.message}`));
350
+ commandSpinner.fail(chalk.red(`Failed to read commands: ${error.message}`));
206
351
  }
352
+
353
+ console.log('');
207
354
  }