@getsolaris/copse 1.0.0

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.ko.md ADDED
@@ -0,0 +1,985 @@
1
+ <p align="center">
2
+ <img src="./banner.png" alt="copse" />
3
+ </p>
4
+
5
+ # ๐ŸŒฒ copse
6
+
7
+ [English](./README.md) | **ํ•œ๊ตญ์–ด**
8
+
9
+ > Git worktree ๋งค๋‹ˆ์ € โ€” ํ„ฐ๋ฏธ๋„ UI
10
+
11
+ Git worktree๋ฅผ ์‰ฝ๊ฒŒ ๊ด€๋ฆฌํ•˜์„ธ์š”. ์„ค์ • ๊ธฐ๋ฐ˜ ์ž๋™ํ™”, ๋ชจ๋…ธ๋ ˆํฌ ์ง€์›, ํ—ฌ์Šค ์ฒดํฌ๋กœ worktree๋ฅผ ์ƒ์„ฑ, ์ „ํ™˜, ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
12
+
13
+ ## ์ฃผ์š” ๊ธฐ๋Šฅ
14
+
15
+ - **TUI ๋ชจ๋“œ** โ€” ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ ํ„ฐ๋ฏธ๋„ UI (`cop`)
16
+ - **CLI ๋ชจ๋“œ** โ€” ์Šคํฌ๋ฆฝํŠธ์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ปค๋งจ๋“œ (`cop add`, `cop list` ๋“ฑ)
17
+ - **์„ค์ • ๊ธฐ๋ฐ˜** โ€” ๋ ˆํฌ๋ณ„ ํ›…, ํŒŒ์ผ ๋ณต์‚ฌ, ์‹ฌ๋ณผ๋ฆญ ๋งํฌ
18
+ - **๋ชจ๋…ธ๋ ˆํฌ ์ง€์›** โ€” ํŒจํ‚ค์ง€ ์ž๋™ ๊ฐ์ง€, ํŒจํ‚ค์ง€๋ณ„ ํ›…, ํฌ์ปค์Šค ์ถ”์ 
19
+ - **ํ—ฌ์Šค ์ฒดํฌ** โ€” `cop doctor`๋กœ worktree ๋ฌธ์ œ ์ง„๋‹จ
20
+ - **์ค‘์•™ ์ง‘์ค‘์‹ worktree** โ€” ๊ธฐ๋ณธ์ ์œผ๋กœ `~/.copse/worktrees/`์— ๋ชจ๋“  worktree ๊ด€๋ฆฌ
21
+ - **์Šค๋งˆํŠธ ์ •๋ฆฌ** โ€” ๋จธ์ง€๋œ worktree ์ž๋™ ๊ฐ์ง€ ๋ฐ ์ œ๊ฑฐ
22
+ - **ํ…Œ๋งˆ** โ€” 9๊ฐ€์ง€ ๋‚ด์žฅ ์ปฌ๋Ÿฌ ํ…Œ๋งˆ (OpenCode, Tokyo Night, Dracula, Nord, Catppuccin, GitHub Dark, One Dark, Monokai, GitHub Light)
23
+ - **ํ…œํ”Œ๋ฆฟ** โ€” ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ worktree ํ”„๋ฆฌ์…‹ (`cop add --template review`)
24
+ - **ํฌ๋กœ์Šค worktree ์‹คํ–‰** โ€” ๋ชจ๋“  worktree์—์„œ ๋ช…๋ น ์‹คํ–‰ (`cop exec "bun test"`)
25
+ - **GitHub PR ์—ฐ๋™** โ€” PR์—์„œ worktree ์ƒ์„ฑ (`cop add --pr 123`)
26
+ - **ํผ์ง€ ๋ธŒ๋žœ์น˜ ํ”ผ์ปค** โ€” TUI์—์„œ ํƒ€์ดํ•‘ํ•˜๋ฉด ๋ธŒ๋žœ์น˜ ์ž๋™์™„์„ฑ
27
+ - **๋ผ์ดํ”„์‚ฌ์ดํด ๊ด€๋ฆฌ** โ€” ๋น„ํ™œ์„ฑ/๋จธ์ง€๋œ worktree ์ž๋™ ๊ฐ์ง€, ์ œํ•œ ์„ค์ •
28
+ - **์˜์กด์„ฑ ๊ณต์œ ** โ€” `node_modules` ๋“ฑ์„ ํ•˜๋“œ๋งํฌ/์‹ฌ๋ณผ๋ฆญ์œผ๋กœ ๋””์Šคํฌ ์ ˆ์•ฝ
29
+ - **Worktree ๋น„๊ต** โ€” worktree ๊ฐ„ ๋ณ€๊ฒฝ์‚ฌํ•ญ ๋น„๊ต (`cop diff feature/a feature/b`)
30
+ - **ํ•€ ๋ณดํ˜ธ** โ€” worktree๋ฅผ ์ž๋™ ์ •๋ฆฌ์—์„œ ๋ณดํ˜ธ (`cop pin`)
31
+ - **ํ™œ๋™ ๋กœ๊ทธ** โ€” ์ƒ์„ฑ/์‚ญ์ œ/์ „ํ™˜/๋ฆฌ๋„ค์ž„/์•„์นด์ด๋ธŒ/์ž„ํฌํŠธ ์ด๋ฒคํŠธ ์ถ”์  (`cop log`)
32
+ - **์•„์นด์ด๋ธŒ** โ€” ์ œ๊ฑฐ ์ „ worktree ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ํŒจ์น˜๋กœ ๋ณด์กด (`cop archive`)
33
+ - **๋ธŒ๋žœ์น˜ ๋ฆฌ๋„ค์ž„** โ€” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜๊ณผ ํ•จ๊ป˜ worktree ๋ธŒ๋žœ์น˜ ์ด๋ฆ„ ๋ณ€๊ฒฝ (`cop rename`)
34
+ - **ํด๋ก  ๋ฐ ์ดˆ๊ธฐํ™”** โ€” cop ์„ค์ •๊ณผ ํ•จ๊ป˜ ๋ ˆํฌ ํด๋ก  (`cop clone`)
35
+ - **Worktree ์ž„ํฌํŠธ** โ€” ์ˆ˜๋™ ์ƒ์„ฑ๋œ worktree ์ฑ„ํƒ (`cop import`)
36
+ - **์ƒ์„ธ ๋ทฐ** โ€” ์ปค๋ฐ‹ ํžˆ์Šคํ† ๋ฆฌ, diff ํ†ต๊ณ„, upstream ์ƒํƒœ ํ™•์ธ (TUI)
37
+ - **์ผ๊ด„ ์ž‘์—…** โ€” ๋‹ค์ค‘ ์„ ํƒ ๋ฐ ๋ฐฐ์น˜ ์ž‘์—… (TUI)
38
+ - **ํ† ์ŠคํŠธ ์•Œ๋ฆผ** โ€” ๋น„๋™๊ธฐ ์ž‘์—… ๊ฒฐ๊ณผ ์•Œ๋ฆผ (TUI)
39
+ - **์…ธ ์ž๋™์™„์„ฑ** โ€” bash/zsh/fish ํƒญ ์ž๋™์™„์„ฑ (`cop shell-init --completions`)
40
+ - **์„ค์ • ํ”„๋กœํ•„** โ€” ์„ค์ • ์„ธํŠธ ์ „ํ™˜ (`cop config --profiles`)
41
+ - **Tmux ์„ธ์…˜** โ€” worktree๋ณ„ tmux ์„ธ์…˜ ์ž๋™ ์ƒ์„ฑ/์ข…๋ฃŒ, ๋ ˆ์ด์•„์›ƒ ํ…œํ”Œ๋ฆฟ (`cop session`)
42
+ - **์›Œํฌ์ŠคํŽ˜์ด์Šค** โ€” ๋ถ€๋ชจ ๋””๋ ‰ํ† ๋ฆฌ ์•„๋ž˜์˜ git repo๋ฅผ ์ž๋™ ๋ฐœ๊ฒฌํ•˜๊ณ  ์›Œํฌ์ŠคํŽ˜์ด์Šค๋ณ„ defaults ์ ์šฉ (`workspaces` ์„ค์ •)
43
+ - **AI ์—์ด์ „ํŠธ ์ดˆ๊ธฐํ™”** โ€” ๊ธฐ๋ณธ ์„ค์ • ํŒŒ์ผ ์ƒ์„ฑ ๋˜๋Š” Claude Code, Codex, OpenCode์šฉ ์Šคํ‚ฌ ์„ค์น˜ (`cop init`, `cop init --skill`)
44
+
45
+ ## ์š”๊ตฌ์‚ฌํ•ญ
46
+
47
+ - [Bun](https://bun.sh) ๋Ÿฐํƒ€์ž„
48
+ - git 2.17+
49
+ - macOS ๋˜๋Š” Linux
50
+ - [gh CLI](https://cli.github.com) (์„ ํƒ์‚ฌํ•ญ, `--pr` ํ”Œ๋ž˜๊ทธ์šฉ)
51
+ - [tmux](https://github.com/tmux/tmux) (์„ ํƒ์‚ฌํ•ญ, `cop session`์šฉ)
52
+
53
+ ## ์„ค์น˜
54
+
55
+ ### Homebrew (macOS/Linux)
56
+
57
+ ```bash
58
+ brew install getsolaris/tap/copse
59
+ ```
60
+
61
+ ### curl (์›๋ผ์ด๋„ˆ)
62
+
63
+ ```bash
64
+ curl -fsSL https://raw.githubusercontent.com/getsolaris/copse/main/install.sh | bash
65
+ ```
66
+
67
+ ### npm / bun
68
+
69
+ ```bash
70
+ bun install -g @getsolaris/copse
71
+ # or
72
+ npm install -g @getsolaris/copse
73
+ ```
74
+
75
+ ## ๋น ๋ฅธ ์‹œ์ž‘
76
+
77
+ ```bash
78
+ # TUI ์‹คํ–‰
79
+ cop
80
+
81
+ # worktree ๋ชฉ๋ก
82
+ cop list
83
+
84
+ # ์ƒˆ worktree ์ƒ์„ฑ
85
+ cop add feature/my-feature
86
+
87
+ # ๋ชจ๋…ธ๋ ˆํฌ ํฌ์ปค์Šค์™€ ํ•จ๊ป˜ ์ƒ์„ฑ
88
+ cop add feature/my-feature --focus apps/web,apps/api
89
+
90
+ # GitHub PR์—์„œ ์ƒ์„ฑ
91
+ cop add --pr 123
92
+
93
+ # ํ…œํ”Œ๋ฆฟ ์‚ฌ์šฉ
94
+ cop add feature/login --template review
95
+
96
+ # ๋ชจ๋“  worktree์—์„œ ๋ช…๋ น ์‹คํ–‰
97
+ cop exec "bun test"
98
+
99
+ # ๋‘ worktree ๋น„๊ต
100
+ cop diff feature/a feature/b --stat
101
+
102
+ # ํ—ฌ์Šค ์ฒดํฌ
103
+ cop doctor
104
+
105
+ # worktree ์ „ํ™˜ (์…ธ ํ†ตํ•ฉ ํ•„์š”)
106
+ cop switch feature/my-feature
107
+
108
+ # worktree ์ œ๊ฑฐ
109
+ cop remove feature/my-feature --yes
110
+
111
+ # ๋จธ์ง€๋œ worktree ์ •๋ฆฌ
112
+ cop clean --dry-run
113
+
114
+ # worktree ํ•€ ์„ค์ • (์ •๋ฆฌ์—์„œ ๋ณดํ˜ธ)
115
+ cop pin feature/important --reason "active sprint"
116
+
117
+ # ํ™œ๋™ ๋กœ๊ทธ ๋ณด๊ธฐ
118
+ cop log
119
+
120
+ # worktree ์•„์นด์ด๋ธŒ ํ›„ ์ œ๊ฑฐ
121
+ cop archive feature/done --yes
122
+
123
+ # worktree ๋ธŒ๋žœ์น˜ ๋ฆฌ๋„ค์ž„
124
+ cop rename old-name new-name
125
+
126
+ # ๋ ˆํฌ ํด๋ก  ๋ฐ cop ์ดˆ๊ธฐํ™”
127
+ cop clone https://github.com/user/repo.git
128
+
129
+ # ๊ธฐ์กด worktree ์ž„ํฌํŠธ
130
+ cop import /path/to/worktree
131
+
132
+ # worktree์˜ tmux ์„ธ์…˜ ์—ด๊ธฐ/์—ฐ๊ฒฐ
133
+ cop session feature/my-feature
134
+
135
+ # tmux ์„ธ์…˜๊ณผ ํ•จ๊ป˜ worktree ์ƒ์„ฑ
136
+ cop add feature/new --session
137
+
138
+ # ์„ค์ • ํŒŒ์ผ ์ดˆ๊ธฐํ™”
139
+ cop init
140
+
141
+ # AI ์—์ด์ „ํŠธ ์Šคํ‚ฌ ํŒŒ์ผ ์ƒ์„ฑ
142
+ cop init --skill claude-code
143
+ ```
144
+
145
+ ## TUI ์‚ฌ์šฉ๋ฒ•
146
+
147
+ `cop` (์ธ์ž ์—†์ด)๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
148
+
149
+ ### ํ‚ค๋ณด๋“œ ๋‹จ์ถ•ํ‚ค
150
+
151
+ | ํ‚ค | ๋™์ž‘ |
152
+ |----|------|
153
+ | `j` / `k` | worktree ๋ชฉ๋ก ํƒ์ƒ‰ |
154
+ | `a` | worktree ์ถ”๊ฐ€ |
155
+ | `d` | worktree ์‚ญ์ œ |
156
+ | `o` | ์—๋””ํ„ฐ๋กœ ์—ด๊ธฐ (focus ์ธ์‹) |
157
+ | `h` | Doctor (ํ—ฌ์Šค ์ฒดํฌ) |
158
+ | `r` | ๋ชฉ๋ก ์ƒˆ๋กœ๊ณ ์นจ |
159
+ | `Ctrl+P` | ์ปค๋งจ๋“œ ํŒ”๋ ˆํŠธ |
160
+ | `Enter` | ์ƒ์„ธ ๋ทฐ ์—ด๊ธฐ |
161
+ | `Escape` | ์ƒ์„ธ ๋ทฐ / ํ”ผ์ปค ๋‹ซ๊ธฐ |
162
+ | `Space` | worktree ์„ ํƒ ํ† ๊ธ€ |
163
+ | `Ctrl+A` | ๋ชจ๋“  worktree ์„ ํƒ |
164
+ | `x` | ์ผ๊ด„ ์ž‘์—… ๋ฉ”๋‰ด |
165
+ | `?` | ๋„์›€๋ง |
166
+ | `q` | ์ข…๋ฃŒ |
167
+
168
+ #### `o` โ€” Focus๋ฅผ ์ธ์‹ํ•˜๋Š” ์—๋””ํ„ฐ ์—ด๊ธฐ
169
+
170
+ `o`๋ฅผ ๋ˆ„๋ฅด๋ฉด ์„ ํƒ๋œ worktree๋ฅผ `$VISUAL` / `$EDITOR`๋กœ ์—ฝ๋‹ˆ๋‹ค:
171
+
172
+ - **focus ๊ฒฝ๋กœ ์—†์Œ** โ†’ worktree ๋ฃจํŠธ๋ฅผ ์—ฝ๋‹ˆ๋‹ค.
173
+ - **focus ๊ฒฝ๋กœ 1๊ฐœ** โ†’ `<worktree>/<focus>`๋ฅผ ๋ฐ”๋กœ ์—ฝ๋‹ˆ๋‹ค.
174
+ - **focus ๊ฒฝ๋กœ 2๊ฐœ ์ด์ƒ** โ†’ ํ”ผ์ปค๊ฐ€ ๋– ์„œ ์–ด๋–ค focus ๊ฒฝ๋กœ(๋˜๋Š” worktree ๋ฃจํŠธ)๋ฅผ ์—ด์ง€ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
175
+
176
+ ํ”ผ์ปค๋Š” `j`/`k` ๋˜๋Š” `โ†‘`/`โ†“`๋กœ ํƒ์ƒ‰, `Enter`๋กœ ์—ด๊ธฐ, `Esc`๋กœ ์ทจ์†Œํ•ฉ๋‹ˆ๋‹ค.
177
+
178
+ ### ์ปค๋งจ๋“œ ํŒ”๋ ˆํŠธ (`Ctrl+P`)
179
+
180
+ ๊ฒ€์ƒ‰ ๊ฐ€๋Šฅํ•œ ์ปค๋งจ๋“œ ๋ฉ”๋‰ด:
181
+ - worktree ์ถ”๊ฐ€ / ์‚ญ์ œ / ์ƒˆ๋กœ๊ณ ์นจ
182
+ - Doctor ์‹คํ–‰
183
+ - ์„ค์ • ์—ด๊ธฐ
184
+ - ํ…Œ๋งˆ ๋ณ€๊ฒฝ
185
+ - ์ข…๋ฃŒ
186
+
187
+ ํƒ€์ดํ•‘์œผ๋กœ ํ•„ํ„ฐ, `โ†‘โ†“`์œผ๋กœ ํƒ์ƒ‰, `Enter`๋กœ ์‹คํ–‰, `Esc`๋กœ ๋‹ซ๊ธฐ.
188
+
189
+ ### Worktree ์ƒ์„ฑ ํ๋ฆ„
190
+
191
+ 1. `a`๋ฅผ ๋ˆŒ๋Ÿฌ ์ƒ์„ฑ ๋ทฐ ์—ด๊ธฐ
192
+ 2. ๋ธŒ๋žœ์น˜๋ช… ์ž…๋ ฅ ์‹œ์ž‘ โ€” ํƒ€์ดํ•‘ํ•˜๋ฉด ๋งค์นญ๋˜๋Š” ๋ธŒ๋žœ์น˜๊ฐ€ ํ‘œ์‹œ๋จ
193
+ 3. `โ†‘โ†“`์œผ๋กœ ์ถ”์ฒœ ๋ธŒ๋žœ์น˜ ์„ ํƒ, ๋˜๋Š” ๊ณ„์† ์ž…๋ ฅํ•˜์—ฌ ์ƒˆ ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ
194
+ 4. `Tab`์œผ๋กœ Focus ํ•„๋“œ ์ „ํ™˜ (์„ ํƒ์‚ฌํ•ญ)
195
+ 5. ํฌ์ปค์Šค ๊ฒฝ๋กœ ์ž…๋ ฅ (์˜ˆ: `apps/web,apps/api`)
196
+ 6. `Enter`๋กœ ๋ฏธ๋ฆฌ๋ณด๊ธฐ
197
+ 7. `Enter`๋กœ ํ™•์ธ
198
+
199
+ ํผ์ง€ ๋ธŒ๋žœ์น˜ ํ”ผ์ปค๋Š” ๋กœ์ปฌ/๋ฆฌ๋ชจํŠธ ๋ธŒ๋žœ์น˜๋ฅผ ๋งˆ์ง€๋ง‰ ์ปค๋ฐ‹ ๋‚ ์งœ ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜์—ฌ ์‹ค์‹œ๊ฐ„ ํ•„ํ„ฐ๋งํ•ฉ๋‹ˆ๋‹ค.
200
+
201
+ ์ƒ์„ฑ ํ›„ ์„ค์ •๋œ `copyFiles`, `linkFiles`, `postCreate` ํ›…, ๋ชจ๋…ธ๋ ˆํฌ ํ›…์ด ์ž๋™์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
202
+
203
+ ### Doctor ๋ทฐ
204
+
205
+ `h`๋ฅผ ๋ˆŒ๋Ÿฌ Doctor ํƒญ์„ ์—ฝ๋‹ˆ๋‹ค. ํ—ฌ์Šค ์ฒดํฌ ๊ฒฐ๊ณผ ํ‘œ์‹œ:
206
+ - โœ“ Git ๋ฒ„์ „ ํ™•์ธ
207
+ - โœ“ ์„ค์ • ์œ ํšจ์„ฑ ๊ฒ€์ฆ
208
+ - โœ“ ๋น„ํ™œ์„ฑ worktree ๊ฐ์ง€
209
+ - โœ“ ๊ณ ์•„ ๋””๋ ‰ํ† ๋ฆฌ ๊ฐ์ง€
210
+ - โœ“ ์ž ๊ธˆ ์ƒํƒœ ํ™•์ธ
211
+ - โœ“ ๋”ํ‹ฐ worktree ๊ฐ์ง€
212
+
213
+ `r`๋กœ ์žฌํ™•์ธ, `Esc`๋กœ ๋Œ์•„๊ฐ€๊ธฐ.
214
+
215
+ ### Config ๋ทฐ
216
+
217
+ `Ctrl+P` โ†’ `Open Config`๋กœ ์—ฝ๋‹ˆ๋‹ค. Config ํƒญ์€ `~/.config/copse/config.json`์˜ ์ „์ฒด ๋‚ด์šฉ์„ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค:
218
+
219
+ - ์ตœ์ƒ์œ„: `version`, `theme`, `activeProfile`
220
+ - `defaults` (`postRemove`, `autoUpstream`, `sharedDeps` ํฌํ•จ)
221
+ - ๋ชจ๋“  ๋ ˆํฌ๋ณ„ ์˜ค๋ฒ„๋ผ์ด๋“œ
222
+ - ์ „์ฒด `monorepo` ํŠธ๋ฆฌ โ€” `autoDetect`, `extraPatterns`, ๊ฐ `hooks[]` ํ•ญ๋ชฉ๊ณผ `glob` / `copyFiles` / `linkFiles` / `postCreate` / `postRemove`
223
+ - `templates`, `lifecycle`, `sessions`, `profiles`
224
+
225
+ ๋Œ€๋ถ€๋ถ„์˜ ์Šค์นผ๋ผ/๋ฌธ์ž์—ด ๋ฐฐ์—ด ํ•„๋“œ๋Š” ์ธ๋ผ์ธ์œผ๋กœ ์ˆ˜์ • ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ํ—ค๋” ์นด์šดํ„ฐ(`1/20`)๋Š” ํ˜„์žฌ ์„ ํƒ๋œ ํ•„๋“œ ์œ„์น˜๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
226
+
227
+ | ํ‚ค | ๋™์ž‘ |
228
+ | --- | --- |
229
+ | `j` / `k` | ์ˆ˜์ • ๊ฐ€๋Šฅํ•œ ํ•„๋“œ ์ด๋™ |
230
+ | `g` / `G` | ์ฒซ ๋ฒˆ์งธ / ๋งˆ์ง€๋ง‰ ํ•„๋“œ๋กœ ์ด๋™ |
231
+ | `Enter` | ์„ ํƒ๋œ ํ•„๋“œ ํŽธ์ง‘ ์‹œ์ž‘ |
232
+ | `Tab` | ํ”„๋ฆฌ์…‹ ๊ฐ’ ์ˆœํ™˜ (ํŽธ์ง‘ ๋ชจ๋“œ) |
233
+ | `Space` / `โ†โ†’` | ๋ถˆ๋ฆฌ์–ธ ํ† ๊ธ€ / ํ…Œ๋งˆ ๋ณ€๊ฒฝ (ํŽธ์ง‘ ๋ชจ๋“œ) |
234
+ | `Enter` | ํŽธ์ง‘ ์ปค๋ฐ‹ (๋””์Šคํฌ์— ์ €์žฅ ํ›„ ์žฌ๋กœ๋“œ) |
235
+ | `Esc` | ํŽธ์ง‘ ์ทจ์†Œ |
236
+ | `e` | `$EDITOR`๋กœ config ํŒŒ์ผ ์—ด๊ธฐ |
237
+ | `r` | ๋””์Šคํฌ์—์„œ ํŒŒ์ผ ์žฌ๋กœ๋“œ |
238
+ | `i` | ์„ค์ • ํŒŒ์ผ ์ดˆ๊ธฐํ™” |
239
+
240
+ ์ธ๋ผ์ธ ํŽธ์ง‘์€ ๋‹ค์„ฏ ์ข…๋ฅ˜์˜ ํ•„๋“œ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค:
241
+
242
+ - **๋ฌธ์ž์—ด** โ€” ์ผ๋ฐ˜ ํ…์ŠคํŠธ ์ž…๋ ฅ (์˜ˆ: `worktreeDir`, ํ›… `glob`, `sessions.prefix`). `Tab`์œผ๋กœ ์ž์ฃผ ์“ฐ์ด๋Š” ํ”„๋ฆฌ์…‹ ์ˆœํ™˜
243
+ - **๋ฌธ์ž์—ด ๋ฐฐ์—ด** โ€” `[".env", ".env.local"]` ๊ฐ™์€ JSON ์ž…๋ ฅ. ๋นˆ ์ž…๋ ฅ์€ `[]`๋กœ ์ฒ˜๋ฆฌ. `Tab`์œผ๋กœ ํ”„๋ฆฌ์…‹ ์ˆœํ™˜ (`[]` ๋นˆ ๋ฐฐ์—ด๋„ ์ฒซ ํ”„๋ฆฌ์…‹์œผ๋กœ ํฌํ•จ)
244
+ - **๋ถˆ๋ฆฌ์–ธ** โ€” `Space`, `Tab`, `โ†โ†’`๋กœ ํ† ๊ธ€, `Enter`๋กœ ์ปค๋ฐ‹
245
+ - **ํ…Œ๋งˆ** โ€” `Tab` ๋˜๋Š” `โ†โ†’`๋กœ ์ˆœํ™˜, `Enter`๋กœ ์ปค๋ฐ‹. ์ƒˆ ํ…Œ๋งˆ๋Š” ์ฆ‰์‹œ ์ ์šฉ๋จ
246
+ - **Enum** โ€” ์œ ํšจํ•œ ๊ฐ’์ด ๊ณ ์ •๋œ ํ•„๋“œ (์˜ˆ: `sharedDeps.strategy` = `hardlink` / `symlink` / `copy`). `Tab` ๋˜๋Š” `โ†โ†’`๋กœ ์ˆœํ™˜, `Enter`๋กœ ์ปค๋ฐ‹
247
+
248
+ ํ‘ธํ„ฐ์— ํ˜„์žฌ ํ”„๋ฆฌ์…‹ ์œ„์น˜๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค (์˜ˆ: `Tab:preset (2/4)`). ์ˆœํ™˜์€ ํ˜„์žฌ ๊ฐ’๊ณผ ์ผ์น˜ํ•˜๋Š” ์œ„์น˜์—์„œ ์‹œ์ž‘ํ•˜๋ฏ€๋กœ, ์ฒซ `Tab` ์ž…๋ ฅ์€ ํ•ญ์ƒ ๋‹ค๋ฅธ ๊ฐ’์œผ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
249
+
250
+ ์ปค๋ฐ‹ ์‹œ `validateConfig`๋กœ ์œ ํšจ์„ฑ ๊ฒ€์ฆ ํ›„ ํŒŒ์ผ์— ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ์œ ํšจํ•˜์ง€ ์•Š์€ ์ž…๋ ฅ์€ ์ธ๋ผ์ธ ์—๋Ÿฌ๋กœ ํ‘œ์‹œ๋˜๋ฉฐ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ํŽธ์ง‘ ๋ชจ๋“œ๊ฐ€ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. ๋ณต์žกํ•œ ํ•„๋“œ(`sessions.layouts`, `templates`, `profiles`)๋Š” `e`๋กœ `$EDITOR`๋ฅผ ์—ด์–ด ํŽธ์ง‘ํ•˜์„ธ์š”.
251
+
252
+ ## CLI ์ปค๋งจ๋“œ
253
+
254
+ | ์ปค๋งจ๋“œ | ์„ค๋ช… |
255
+ |--------|------|
256
+ | `cop` | TUI ์‹คํ–‰ |
257
+ | `cop list` | ๋ชจ๋“  worktree ๋ชฉ๋ก (ํฌ์ปค์Šค ์ •๋ณด ํฌํ•จ) |
258
+ | `cop add <branch>` | worktree ์ƒ์„ฑ |
259
+ | `cop remove <branch>` | worktree ์ œ๊ฑฐ |
260
+ | `cop switch <branch>` | worktree ์ „ํ™˜ |
261
+ | `cop clean` | ๋จธ์ง€๋œ worktree ์ œ๊ฑฐ |
262
+ | `cop doctor` | worktree ํ—ฌ์Šค ์ฒดํฌ |
263
+ | `cop config` | ์„ค์ • ๊ด€๋ฆฌ |
264
+ | `cop exec <command>` | ๊ฐ worktree์—์„œ ๋ช…๋ น ์‹คํ–‰ |
265
+ | `cop diff <ref1> [ref2]` | worktree/๋ธŒ๋žœ์น˜ ๊ฐ„ diff |
266
+ | `cop pin <branch>` | worktree ํ•€/์–ธํ•€ (์ •๋ฆฌ์—์„œ ๋ณดํ˜ธ) |
267
+ | `cop log` | worktree ํ™œ๋™ ๋กœ๊ทธ ๋ณด๊ธฐ |
268
+ | `cop archive <branch>` | ๋ณ€๊ฒฝ์‚ฌํ•ญ ์•„์นด์ด๋ธŒ ํ›„ ์„ ํƒ์  ์ œ๊ฑฐ |
269
+ | `cop rename <old> <new>` | worktree ๋ธŒ๋žœ์น˜ ๋ฆฌ๋„ค์ž„ |
270
+ | `cop clone <url>` | ๋ ˆํฌ ํด๋ก  ๋ฐ cop ์ดˆ๊ธฐํ™” |
271
+ | `cop import <path>` | cop ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋กœ worktree ์ฑ„ํƒ |
272
+ | `cop session [branch]` | worktree์˜ tmux ์„ธ์…˜ ๊ด€๋ฆฌ |
273
+ | `cop open [branch]` | worktree๋ฅผ ์—๋””ํ„ฐ๋กœ ์—ด๊ธฐ (focus ์ธ์‹) |
274
+ | `cop init` | ์„ค์ • ์ดˆ๊ธฐํ™” ๋˜๋Š” AI ์—์ด์ „ํŠธ ์Šคํ‚ฌ ์„ค์น˜ |
275
+
276
+ ### `cop add`
277
+
278
+ ```bash
279
+ cop add feature/login # ํ•„์š”ํ•˜๋ฉด ๋ธŒ๋žœ์น˜๋ฅผ ๋งŒ๋“ค๊ณ  worktree ์ƒ์„ฑ
280
+ cop add feature/login --base main # ์ƒˆ ๋ธŒ๋žœ์น˜๋Š” main์—์„œ ์‹œ์ž‘
281
+ cop add existing-branch # ๊ธฐ์กด ๋ธŒ๋žœ์น˜๋กœ worktree ์ƒ์„ฑ
282
+
283
+ # ๋ชจ๋…ธ๋ ˆํฌ: ํฌ์ปค์Šค ํŒจํ‚ค์ง€์™€ ํ•จ๊ป˜ ์ƒ์„ฑ
284
+ cop add feature/login --focus apps/web,apps/api
285
+ cop add feature/login --focus apps/web --focus apps/api
286
+
287
+ # ํ…œํ”Œ๋ฆฟ ์‚ฌ์šฉ
288
+ cop add feature/login --template review
289
+
290
+ # GitHub PR์—์„œ ์ƒ์„ฑ (gh CLI ํ•„์š”)
291
+ cop add --pr 123
292
+ cop add --pr 456 --template review
293
+ ```
294
+
295
+ ### `cop doctor`
296
+
297
+ ```bash
298
+ cop doctor # ์‚ฌ๋žŒ์ด ์ฝ๊ธฐ ์‰ฌ์šด ์ถœ๋ ฅ
299
+ cop doctor --json # ์Šคํฌ๋ฆฝํŒ…์šฉ JSON ์ถœ๋ ฅ
300
+ ```
301
+
302
+ ์ข…๋ฃŒ ์ฝ”๋“œ: ์ •์ƒ์ด๋ฉด `0`, ๊ฒฝ๊ณ  ๋˜๋Š” ์—๋Ÿฌ๊ฐ€ ์žˆ์œผ๋ฉด `1`.
303
+
304
+ ```
305
+ copse doctor
306
+
307
+ โœ“ Git version: 2.39.0 (>= 2.17 required)
308
+ โœ“ Configuration: valid
309
+ โœ“ Stale worktrees: none
310
+ โœ“ Orphaned directories: none
311
+ โœ“ Worktree locks: all clear
312
+ โœ“ Dirty worktrees: none
313
+
314
+ All checks passed.
315
+ ```
316
+
317
+ ### `cop list`
318
+
319
+ ```bash
320
+ cop list # Focus ์ปฌ๋Ÿผ์ด ํฌํ•จ๋œ ํ…Œ์ด๋ธ”
321
+ cop list --json # ํฌ์ปค์Šค ๋ฐฐ์—ด์ด ํฌํ•จ๋œ JSON
322
+ cop list --porcelain # ๋จธ์‹  ํŒ๋… ๊ฐ€๋Šฅ ํ˜•์‹
323
+ ```
324
+
325
+ ๋ชจ๋…ธ๋ ˆํฌ worktree๋ณ„ ํฌ์ปค์Šค ๊ฒฝ๋กœ๋ฅผ `Focus` ์ปฌ๋Ÿผ์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
326
+
327
+ ### `cop remove`
328
+
329
+ ```bash
330
+ cop remove feature/login # ๋ธŒ๋žœ์น˜๋ช…์œผ๋กœ ์ œ๊ฑฐ
331
+ cop remove feature/login --force # ๊ฐ•์ œ ์ œ๊ฑฐ (๋”ํ‹ฐ worktree)
332
+ cop remove feature/login --yes # ํ™•์ธ ๊ฑด๋„ˆ๋›ฐ๊ธฐ
333
+ ```
334
+
335
+ ### `cop clean`
336
+
337
+ ```bash
338
+ cop clean --dry-run # ์ œ๊ฑฐ๋  ํ•ญ๋ชฉ ๋ฏธ๋ฆฌ๋ณด๊ธฐ
339
+ cop clean # ๋จธ์ง€๋œ worktree ๋ชจ๋‘ ์ œ๊ฑฐ
340
+ cop clean --stale # ๋น„ํ™œ์„ฑ worktree๋„ ํ‘œ์‹œ (lifecycle ์„ค์ • ์‚ฌ์šฉ)
341
+ ```
342
+
343
+ ### `cop exec`
344
+
345
+ ๋ชจ๋“  ๋น„-๋ฉ”์ธ worktree์—์„œ ์…ธ ์ปค๋งจ๋“œ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
346
+
347
+ ```bash
348
+ cop exec "bun test" # ๋ชจ๋“  worktree์—์„œ ์‹คํ–‰ (์ˆœ์ฐจ)
349
+ cop exec "bun test" --parallel # ๋ณ‘๋ ฌ ์‹คํ–‰
350
+ cop exec "git pull" --all # ๋ชจ๋“  ์„ค์ •๋œ ๋ ˆํฌ์—์„œ ์‹คํ–‰
351
+ cop exec "bun install" --dirty # ๋”ํ‹ฐ worktree๋งŒ
352
+ cop exec "git rebase main" --behind # upstream๋ณด๋‹ค ๋’ค์ฒ˜์ง„ ๊ฒƒ๋งŒ
353
+ cop exec "bun test" --json # JSON ์ถœ๋ ฅ
354
+ ```
355
+
356
+ | ํ”Œ๋ž˜๊ทธ | ์„ค๋ช… |
357
+ |--------|------|
358
+ | `--parallel` / `-p` | ๋ณ‘๋ ฌ ์‹คํ–‰ |
359
+ | `--all` / `-a` | ๋ชจ๋“  ์„ค์ •๋œ ๋ ˆํฌ ํฌํ•จ |
360
+ | `--dirty` | ๋”ํ‹ฐ worktree์—์„œ๋งŒ ์‹คํ–‰ |
361
+ | `--clean` | ํด๋ฆฐ worktree์—์„œ๋งŒ ์‹คํ–‰ |
362
+ | `--behind` | upstream๋ณด๋‹ค ๋’ค์ฒ˜์ง„ worktree์—์„œ๋งŒ ์‹คํ–‰ |
363
+ | `--json` / `-j` | ๊ฒฐ๊ณผ๋ฅผ JSON์œผ๋กœ ์ถœ๋ ฅ |
364
+
365
+ ์ปค๋งจ๋“œ์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํ™˜๊ฒฝ๋ณ€์ˆ˜: `COP_BRANCH`, `COP_WORKTREE_PATH`, `COP_REPO_PATH`.
366
+
367
+ ### `cop diff`
368
+
369
+ ๋‘ worktree ๋ธŒ๋žœ์น˜ ๊ฐ„ diff๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.
370
+
371
+ ```bash
372
+ cop diff feature/a feature/b # ์ „์ฒด diff
373
+ cop diff feature/a feature/b --stat # diffstat ์š”์•ฝ
374
+ cop diff feature/a --name-only # ๋ณ€๊ฒฝ๋œ ํŒŒ์ผ๋ช…๋งŒ
375
+ cop diff feature/a # ํ˜„์žฌ HEAD์™€ ๋น„๊ต
376
+ ```
377
+
378
+ ### `cop pin`
379
+
380
+ ```bash
381
+ cop pin feature/auth --reason "active sprint" # ์‚ฌ์œ ์™€ ํ•จ๊ป˜ ํ•€
382
+ cop pin --list # ํ•€๋œ worktree ๋ชฉ๋ก
383
+ cop pin --list --json # JSON ์ถœ๋ ฅ
384
+ cop unpin feature/auth # ์–ธํ•€
385
+ ```
386
+
387
+ ํ•€๋œ worktree๋Š” `cop clean` ๋ฐ ๋ผ์ดํ”„์‚ฌ์ดํด ์ž๋™ ์ •๋ฆฌ์—์„œ ์ œ์™ธ๋ฉ๋‹ˆ๋‹ค.
388
+
389
+ ### `cop log`
390
+
391
+ ```bash
392
+ cop log # ์ตœ๊ทผ 20๊ฐœ ์ด๋ฒคํŠธ ํ‘œ์‹œ
393
+ cop log --limit 50 # ์ตœ๊ทผ 50๊ฐœ ์ด๋ฒคํŠธ ํ‘œ์‹œ
394
+ cop log --json # JSON ์ถœ๋ ฅ
395
+ cop log --clear # ํ™œ๋™ ๋กœ๊ทธ ์ดˆ๊ธฐํ™”
396
+ ```
397
+
398
+ ์ด๋ฒคํŠธ๋Š” ์ƒ‰์ƒ์œผ๋กœ ๊ตฌ๋ถ„: ์ƒ์„ฑ(์ดˆ๋ก), ์‚ญ์ œ(๋นจ๊ฐ•), ์ „ํ™˜(ํŒŒ๋ž‘), ๋ฆฌ๋„ค์ž„(๋…ธ๋ž‘), ์•„์นด์ด๋ธŒ(์žํ™), ์ž„ํฌํŠธ(์‹œ์•ˆ).
399
+
400
+ ### `cop archive`
401
+
402
+ ```bash
403
+ cop archive feature/done --yes # ์•„์นด์ด๋ธŒ ํ›„ ์ œ๊ฑฐ
404
+ cop archive feature/wip --keep # ์ œ๊ฑฐ ์—†์ด ์•„์นด์ด๋ธŒ๋งŒ
405
+ cop archive --list # ๋ชจ๋“  ์•„์นด์ด๋ธŒ ๋ชฉ๋ก
406
+ cop archive --list --json # JSON ์ถœ๋ ฅ
407
+ ```
408
+
409
+ ์•„์นด์ด๋ธŒ๋Š” `~/.copse/archives/`์— ํŒจ์น˜ ํŒŒ์ผ๋กœ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.
410
+
411
+ ### `cop rename`
412
+
413
+ ```bash
414
+ cop rename old-branch new-branch # ๋ธŒ๋žœ์น˜ ๋ฆฌ๋„ค์ž„
415
+ cop rename old-branch new-branch --move-path # worktree ๋””๋ ‰ํ† ๋ฆฌ๋„ ์ด๋™
416
+ ```
417
+
418
+ ### `cop clone`
419
+
420
+ ```bash
421
+ cop clone https://github.com/user/repo.git # ํด๋ก  ๋ฐ ์ดˆ๊ธฐํ™”
422
+ cop clone https://github.com/user/repo.git ./my-dir # ์ปค์Šคํ…€ ๋Œ€์ƒ ๊ฒฝ๋กœ
423
+ cop clone https://github.com/user/repo.git --template review # ํ…œํ”Œ๋ฆฟ ์ ์šฉ
424
+ cop clone https://github.com/user/repo.git --no-init-config # ์„ค์ • ์ดˆ๊ธฐํ™” ๊ฑด๋„ˆ๋›ฐ๊ธฐ
425
+ ```
426
+
427
+ ### `cop import`
428
+
429
+ ```bash
430
+ cop import /path/to/worktree # worktree ์ฑ„ํƒ
431
+ cop import /path/to/worktree --focus apps/web,apps/api # ํฌ์ปค์Šค์™€ ํ•จ๊ป˜
432
+ cop import /path/to/worktree --pin # ์ฆ‰์‹œ ํ•€ ์„ค์ •
433
+ ```
434
+
435
+ ### `cop session`
436
+
437
+ worktree์˜ tmux ์„ธ์…˜์„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. tmux๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
438
+
439
+ ```bash
440
+ cop session feature/auth # ์„ธ์…˜ ์—ด๊ธฐ/์—ฐ๊ฒฐ (์—†์œผ๋ฉด ์ƒ์„ฑ)
441
+ cop session feature/auth --layout api # ์„ค์ •์˜ ๋ ˆ์ด์•„์›ƒ ์‚ฌ์šฉ
442
+ cop session --list # ํ™œ์„ฑ cop ์„ธ์…˜ ๋ชฉ๋ก
443
+ cop session --list --json # JSON ์ถœ๋ ฅ
444
+ cop session feature/auth --kill # worktree ์„ธ์…˜ ์ข…๋ฃŒ
445
+ cop session --kill-all # ๋ชจ๋“  cop ์„ธ์…˜ ์ข…๋ฃŒ
446
+ ```
447
+
448
+ ์„ค์ •์—์„œ `sessions.autoCreate` / `sessions.autoKill`์„ ํ™œ์„ฑํ™”ํ•˜๋ฉด ์„ธ์…˜์ด ์ž๋™ ์ƒ์„ฑ/์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค.
449
+
450
+ ```bash
451
+ # tmux ์„ธ์…˜๊ณผ ํ•จ๊ป˜ worktree ์ƒ์„ฑ
452
+ cop add feature/login --session
453
+ cop add feature/login --session --layout api
454
+ ```
455
+
456
+ `sessions.enabled`๊ฐ€ `true`์ด๊ณ  tmux ์•ˆ์— ์žˆ์œผ๋ฉด, `cop switch`๊ฐ€ ๋Œ€์ƒ worktree์˜ tmux ์„ธ์…˜์œผ๋กœ ์ž๋™ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
457
+
458
+ ### `cop open`
459
+
460
+ worktree๋ฅผ ์—๋””ํ„ฐ/IDE๋กœ ์—ฝ๋‹ˆ๋‹ค. `$VISUAL` / `$EDITOR`๋ฅผ ์ž๋™ ๊ฐ์ง€ํ•˜๊ณ , ์—†์œผ๋ฉด ์•Œ๋ ค์ง„ ์—๋””ํ„ฐ ๋ชฉ๋ก(`code`, `cursor`, `vim`, `nvim`, `emacs`, `nano`, `subl`, `zed`, `idea`, `webstorm`)์—์„œ ์ฐพ์Šต๋‹ˆ๋‹ค.
461
+
462
+ ```bash
463
+ cop open # ํ˜„์žฌ worktree ์—ด๊ธฐ
464
+ cop open feature/auth # ํŠน์ • worktree ์—ด๊ธฐ
465
+ cop open feature/auth -e nvim # ์—๋””ํ„ฐ ๊ฐ•์ œ ์ง€์ •
466
+
467
+ # Focus ์ธ์‹ ๋™์ž‘ (--focus๋กœ ์ƒ์„ฑ๋œ worktree์—์„œ)
468
+ cop open feature/auth # focus 1๊ฐœ โ†’ ํ•ด๋‹น focus ๊ฒฝ๋กœ๋กœ ์—ด๋ฆผ
469
+ # focus 2๊ฐœ+ โ†’ ์—๋Ÿฌ + ํžŒํŠธ ์ถœ๋ ฅ
470
+ cop open feature/auth --focus apps/web # ํŠน์ • focus ๊ฒฝ๋กœ ์„ ํƒ
471
+ cop open feature/auth -f apps/api # ์งง์€ ๋ณ„์นญ
472
+ cop open feature/auth --root # focus ๋ฌด์‹œํ•˜๊ณ  worktree ๋ฃจํŠธ ๊ฐ•์ œ
473
+
474
+ cop open --list-editors # ๊ฐ์ง€๋œ ์—๋””ํ„ฐ ๋ชฉ๋ก
475
+ ```
476
+
477
+ | ํ”Œ๋ž˜๊ทธ | ๋ณ„์นญ | ์„ค๋ช… |
478
+ | ------ | ---- | ---- |
479
+ | `--editor` | `-e` | ์‚ฌ์šฉํ•  ์—๋””ํ„ฐ (`$VISUAL`/`$EDITOR` ๋ฌด์‹œ) |
480
+ | `--focus` | `-f` | ํŠน์ • focus ๊ฒฝ๋กœ ์—ด๊ธฐ (worktree์— ์„ค์ •๋œ focus ํ•ญ๋ชฉ๊ณผ ์ผ์น˜ํ•ด์•ผ ํ•จ) |
481
+ | `--root` | | focus๋ฅผ ๋ฌด์‹œํ•˜๊ณ  worktree ๋ฃจํŠธ ๊ฐ•์ œ ์—ด๊ธฐ |
482
+ | `--list-editors` | | ๊ฐ์ง€๋œ ์—๋””ํ„ฐ ๋ชฉ๋ก |
483
+
484
+ **Focus ํ•ด์„ ๊ทœ์น™:**
485
+
486
+ - focus ๊ฒฝ๋กœ ์—†์Œ โ†’ worktree ๋ฃจํŠธ๋ฅผ ์—ฝ๋‹ˆ๋‹ค.
487
+ - focus ๊ฒฝ๋กœ 1๊ฐœ โ†’ `<worktree>/<focus>`๋ฅผ ์ž๋™์œผ๋กœ ์—ฝ๋‹ˆ๋‹ค.
488
+ - focus ๊ฒฝ๋กœ 2๊ฐœ ์ด์ƒ โ†’ ์—๋Ÿฌ๋ฅผ ๋‚ด๊ณ  `--focus <path>` ๋˜๋Š” `--root`๋ฅผ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค (TUI์—์„œ๋Š” ๋Œ€์‹  ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ ํ”ผ์ปค๋ฅผ ๋„์›๋‹ˆ๋‹ค).
489
+
490
+ ### `cop init`
491
+
492
+ ๊ธฐ๋ณธ์ ์œผ๋กœ cop ์„ค์ • ํŒŒ์ผ์„ ์ดˆ๊ธฐํ™”ํ•˜๊ณ , ํ•„์š”ํ•˜๋ฉด AI ์ฝ”๋”ฉ ์—์ด์ „ํŠธ์šฉ ์Šคํ‚ฌ๋„ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.
493
+
494
+ ```bash
495
+ cop init # โ†’ ~/.config/copse/config.json
496
+ cop init --skill claude-code # โ†’ ~/.claude/skills/cop/
497
+ cop init --skill codex # โ†’ ~/.agents/skills/cop/
498
+ cop init --skill opencode # โ†’ ~/.config/opencode/skill/cop/
499
+ ```
500
+
501
+ | ํ”Œ๋žซํผ | ์Šคํ‚ฌ ๊ฒฝ๋กœ |
502
+ |--------|----------|
503
+ | `claude-code` | `~/.claude/skills/cop/` |
504
+ | `codex` | `~/.agents/skills/cop/` |
505
+ | `opencode` | `~/.config/opencode/skill/cop/` |
506
+
507
+ ๊ฐ ์Šคํ‚ฌ ๋””๋ ‰ํ† ๋ฆฌ์—๋Š” ๋‹ค์Œ์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค:
508
+ - `SKILL.md` โ€” ๊ฐœ์š”์™€ ๊ณตํ†ต ์›Œํฌํ”Œ๋กœ์šฐ
509
+ - `references/` โ€” ๋ช…๋ น๋ณ„ ์ƒ์„ธ ๋ฌธ์„œ (21๊ฐœ ํŒŒ์ผ)
510
+
511
+ `--skill` ์—†์ด ์‹คํ–‰ํ•˜๋ฉด ๊ธฐ์กด ์„ค์ • ์ดˆ๊ธฐํ™” ๋กœ์ง์„ ์žฌ์‚ฌ์šฉํ•˜์—ฌ `config.json`๋งŒ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
512
+ ๋ฉฑ๋“ฑ์„ฑ โ€” ๋‹ค์‹œ ์‹คํ–‰ํ•˜๋ฉด ์Šคํ‚ฌ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
513
+
514
+ #### ์ฒซ ์‹คํ–‰ ์‹œ ์ž๋™ ์ดˆ๊ธฐํ™”
515
+
516
+ `cop init`์„ ์ง์ ‘ ์‹คํ–‰ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์ฒ˜์Œ์œผ๋กœ `cop` ๋ช…๋ น์–ด(๋˜๋Š” TUI)๋ฅผ ์‹คํ–‰ํ•  ๋•Œ `~/.config/copse/config.json`์ด ์—†์œผ๋ฉด, cop๊ฐ€ ๊ธฐ๋ณธ ์„ค์ •์œผ๋กœ ์ž๋™ ์ƒ์„ฑํ•˜๊ณ  stderr์— ํ•œ ์ค„์งœ๋ฆฌ ์•Œ๋ฆผ์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค:
517
+
518
+ ```
519
+ cop: created default config at /Users/you/.config/copse/config.json
520
+ ```
521
+
522
+ ์ด ์•Œ๋ฆผ์€ stdout์ด TTY๊ฐ€ ์•„๋‹ ๋•Œ(ํŒŒ์ดํ”„, ์Šคํฌ๋ฆฝํŠธ, CI ํ™˜๊ฒฝ)์™€ `cop init`์„ ๋ช…์‹œ์ ์œผ๋กœ ์‹คํ–‰ํ•  ๋•Œ(์ค‘๋ณต ๋ฉ”์‹œ์ง€ ๋ฐฉ์ง€)๋Š” ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ž๋™ ์ดˆ๊ธฐํ™”๋Š” ๋ฉฑ๋“ฑ์„ฑ์„ ๊ฐ€์ง€๋ฏ€๋กœ ์ดํ›„ ์‹คํ–‰์—์„œ๋Š” ์•„๋ฌด ๋™์ž‘๋„ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
523
+
524
+ ## ์„ค์ •
525
+
526
+ ์„ค์ • ํŒŒ์ผ: `~/.config/copse/config.json`
527
+
528
+ ์ดˆ๊ธฐํ™”: `cop config --init` (๋˜๋Š” ์•„๋ฌด `cop` ๋ช…๋ น์–ด ์‹คํ–‰ โ€” [์ฒซ ์‹คํ–‰ ์‹œ ์ž๋™ ์ดˆ๊ธฐํ™”](#์ฒซ-์‹คํ–‰-์‹œ-์ž๋™-์ดˆ๊ธฐํ™”) ์ฐธ์กฐ)
529
+
530
+ ### ์ „์ฒด ์˜ˆ์‹œ
531
+
532
+ ```json
533
+ {
534
+ "$schema": "https://raw.githubusercontent.com/getsolaris/copse/main/schema.json",
535
+ "version": 1,
536
+ "theme": "dracula",
537
+ "defaults": {
538
+ "worktreeDir": "~/.copse/worktrees/{repo}-{branch}",
539
+ "copyFiles": [".env"],
540
+ "linkFiles": ["node_modules"],
541
+ "postCreate": ["bun install"],
542
+ "postRemove": [],
543
+ "sharedDeps": {
544
+ "strategy": "hardlink",
545
+ "paths": ["node_modules"],
546
+ "invalidateOn": ["package.json", "bun.lockb"]
547
+ }
548
+ },
549
+ "templates": {
550
+ "review": {
551
+ "copyFiles": [".env.local"],
552
+ "postCreate": ["bun install", "bun run build"],
553
+ "autoUpstream": true
554
+ },
555
+ "hotfix": {
556
+ "base": "main",
557
+ "copyFiles": [".env.production"],
558
+ "postCreate": ["bun install"]
559
+ },
560
+ "experiment": {
561
+ "worktreeDir": "~/tmp/experiments/{branch}",
562
+ "postRemove": []
563
+ }
564
+ },
565
+ "lifecycle": {
566
+ "autoCleanMerged": true,
567
+ "staleAfterDays": 14,
568
+ "maxWorktrees": 10
569
+ },
570
+ "sessions": {
571
+ "enabled": true,
572
+ "autoCreate": false,
573
+ "autoKill": true,
574
+ "prefix": "cop",
575
+ "defaultLayout": "dev",
576
+ "layouts": {
577
+ "dev": {
578
+ "windows": [
579
+ { "name": "editor", "command": "$EDITOR ." },
580
+ { "name": "dev", "command": "bun dev" },
581
+ { "name": "test", "command": "bun test --watch" }
582
+ ]
583
+ },
584
+ "minimal": {
585
+ "windows": [
586
+ { "name": "shell" }
587
+ ]
588
+ }
589
+ }
590
+ },
591
+ "workspaces": [
592
+ {
593
+ "path": "~/Desktop/work",
594
+ "depth": 1,
595
+ "exclude": ["node_modules", ".cache", "archived"],
596
+ "defaults": {
597
+ "copyFiles": [".env", ".env.local"],
598
+ "linkFiles": ["node_modules"],
599
+ "postCreate": ["bun install"],
600
+ "autoUpstream": true
601
+ }
602
+ }
603
+ ],
604
+ "repos": [
605
+ {
606
+ "path": "/Users/me/dev/frontend",
607
+ "copyFiles": [".env", ".env.local"],
608
+ "linkFiles": ["node_modules", ".next"],
609
+ "postCreate": ["bun install", "bun run build"]
610
+ },
611
+ {
612
+ "path": "/Users/me/dev/backend",
613
+ "copyFiles": [".env"],
614
+ "postCreate": ["pip install -r requirements.txt"]
615
+ },
616
+ {
617
+ "path": "/Users/me/dev/monorepo",
618
+ "copyFiles": [".env"],
619
+ "postCreate": ["pnpm install"],
620
+ "monorepo": {
621
+ "autoDetect": true,
622
+ "extraPatterns": ["apps/*/*"],
623
+ "hooks": [
624
+ {
625
+ "glob": "apps/web",
626
+ "copyFiles": [".env"],
627
+ "postCreate": ["cd {packagePath} && pnpm install"]
628
+ },
629
+ {
630
+ "glob": "apps/api",
631
+ "copyFiles": [".env"],
632
+ "linkFiles": ["node_modules"],
633
+ "postCreate": ["cd {packagePath} && pnpm install && pnpm build"]
634
+ }
635
+ ]
636
+ }
637
+ }
638
+ ]
639
+ }
640
+ ```
641
+
642
+ ### ์„ค์ • ํ•„๋“œ
643
+
644
+ #### `defaults`
645
+
646
+ ๋ชจ๋“  ๋ ˆํฌ๊ฐ€ ์ด ์„ค์ •์„ ์ƒ์†ํ•ฉ๋‹ˆ๋‹ค (๋ ˆํฌ๋ณ„ ์˜ค๋ฒ„๋ผ์ด๋“œ ๊ฐ€๋Šฅ).
647
+
648
+ | ํ•„๋“œ | ํƒ€์ž… | ๊ธฐ๋ณธ๊ฐ’ | ์„ค๋ช… |
649
+ |------|------|--------|------|
650
+ | `worktreeDir` | `string` | `~/.copse/worktrees/{repo}-{branch}` | worktree ๋””๋ ‰ํ† ๋ฆฌ ํŒจํ„ด |
651
+ | `copyFiles` | `string[]` | `[]` | ๋ฉ”์ธ ๋ ˆํฌ์—์„œ ๋ณต์‚ฌํ•  ํŒŒ์ผ |
652
+ | `linkFiles` | `string[]` | `[]` | ์‹ฌ๋ณผ๋ฆญ ๋งํฌํ•  ํŒŒ์ผ/๋””๋ ‰ํ† ๋ฆฌ (๋””์Šคํฌ ์ ˆ์•ฝ) |
653
+ | `postCreate` | `string[]` | `[]` | worktree ์ƒ์„ฑ ํ›„ ์‹คํ–‰ํ•  ์ปค๋งจ๋“œ |
654
+ | `postRemove` | `string[]` | `[]` | worktree ์ œ๊ฑฐ ์ „ ์‹คํ–‰ํ•  ์ปค๋งจ๋“œ |
655
+
656
+ #### `repos[]`
657
+
658
+ ๋ ˆํฌ๋ณ„ ์˜ค๋ฒ„๋ผ์ด๋“œ. ๊ฐ ํ•ญ๋ชฉ์€ `path`๊ฐ€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.
659
+
660
+ | ํ•„๋“œ | ํƒ€์ž… | ํ•„์ˆ˜ | ์„ค๋ช… |
661
+ |------|------|------|------|
662
+ | `path` | `string` | ์˜ˆ | ๋ ˆํฌ์˜ ์ ˆ๋Œ€ ๊ฒฝ๋กœ |
663
+ | `worktreeDir` | `string` | ์•„๋‹ˆ์˜ค | ๊ธฐ๋ณธ worktree ๋””๋ ‰ํ† ๋ฆฌ ์˜ค๋ฒ„๋ผ์ด๋“œ |
664
+ | `copyFiles` | `string[]` | ์•„๋‹ˆ์˜ค | ๊ธฐ๋ณธ ๋ณต์‚ฌ ํŒŒ์ผ ์˜ค๋ฒ„๋ผ์ด๋“œ |
665
+ | `linkFiles` | `string[]` | ์•„๋‹ˆ์˜ค | ๊ธฐ๋ณธ ๋งํฌ ํŒŒ์ผ ์˜ค๋ฒ„๋ผ์ด๋“œ |
666
+ | `postCreate` | `string[]` | ์•„๋‹ˆ์˜ค | ๊ธฐ๋ณธ postCreate ํ›… ์˜ค๋ฒ„๋ผ์ด๋“œ |
667
+ | `postRemove` | `string[]` | ์•„๋‹ˆ์˜ค | ๊ธฐ๋ณธ postRemove ํ›… ์˜ค๋ฒ„๋ผ์ด๋“œ |
668
+ | `monorepo` | `object` | ์•„๋‹ˆ์˜ค | ๋ชจ๋…ธ๋ ˆํฌ ์ง€์› ์„ค์ • |
669
+
670
+ #### `workspaces[]`
671
+
672
+ ๋ถ€๋ชจ ๋””๋ ‰ํ† ๋ฆฌ ์•„๋ž˜์˜ git ๋ ˆํฌ๋ฅผ ์ž๋™์œผ๋กœ ๋ฐœ๊ฒฌํ•ฉ๋‹ˆ๋‹ค. ๋ฐœ๊ฒฌ๋œ ๊ฐ ๋ ˆํฌ๋Š” ๋กœ๋“œ ์‹œ์ ์— `repos[]`์— ๋ณ‘ํ•ฉ๋˜๋ฉฐ, ์›Œํฌ์ŠคํŽ˜์ด์Šค์˜ `defaults`๊ฐ€ ๋ ˆํฌ ์˜ค๋ฒ„๋ผ์ด๋“œ ๋ ˆ์ด์–ด๋กœ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.
673
+
674
+ ```json
675
+ {
676
+ "workspaces": [
677
+ {
678
+ "path": "~/Desktop/work",
679
+ "depth": 1,
680
+ "exclude": ["node_modules", ".cache", "archived"],
681
+ "defaults": {
682
+ "copyFiles": [".env", ".env.local"],
683
+ "linkFiles": ["node_modules"],
684
+ "postCreate": ["bun install"],
685
+ "autoUpstream": true
686
+ }
687
+ }
688
+ ]
689
+ }
690
+ ```
691
+
692
+ | ํ•„๋“œ | ํƒ€์ž… | ํ•„์ˆ˜ | ๊ธฐ๋ณธ๊ฐ’ | ์„ค๋ช… |
693
+ |------|------|------|--------|------|
694
+ | `path` | `string` | ์˜ˆ | โ€” | ์Šค์บ”ํ•  ๋ถ€๋ชจ ๋””๋ ‰ํ† ๋ฆฌ. `~` ํ™•์žฅ ์ง€์›. |
695
+ | `depth` | `integer` | ์•„๋‹ˆ์˜ค | `1` | ์Šค์บ” ๊นŠ์ด (1โ€“3). `1`์€ ์ง๊ณ„ ์ž์‹๋งŒ ์Šค์บ”. |
696
+ | `exclude` | `string[]` | ์•„๋‹ˆ์˜ค | `[]` | ๋””๋ ‰ํ† ๋ฆฌ ์ด๋ฆ„์— ๋งค์นญ๋˜๋Š” ๊ธ€๋กญ ํŒจํ„ด์œผ๋กœ ์ œ์™ธ (์˜ˆ: `node_modules`). |
697
+ | `defaults` | `object` | ์•„๋‹ˆ์˜ค | โ€” | ๋ฐœ๊ฒฌ๋œ ๋ชจ๋“  ๋ ˆํฌ์— ์ ์šฉํ•  ๊ธฐ๋ณธ๊ฐ’. `defaults`์™€ ๋™์ผํ•œ ํ•„๋“œ. |
698
+
699
+ **๋ฐœ๊ฒฌ ๊ทœ์น™:**
700
+
701
+ - `.git`์ด **๋””๋ ‰ํ† ๋ฆฌ**์ธ ๊ฒฝ์šฐ์—๋งŒ ๋ ˆํฌ๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค. `.git`์ด ํŒŒ์ผ์ด๋ฉด (linked worktree ๋˜๋Š” submodule) ์ œ์™ธ๋ฉ๋‹ˆ๋‹ค.
702
+ - ๋ฐœ๊ฒฌ๋œ ๋ ˆํฌ์˜ ํ•˜์œ„๋Š” ๋” ์ด์ƒ ์Šค์บ”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค (๋ ˆํฌ ์•ˆ์œผ๋กœ ์žฌ๊ท€ํ•˜์ง€ ์•Š์Œ).
703
+ - ์‹ฌ๋ณผ๋ฆญ ๋งํฌ๋Š” ๋”ฐ๋ผ๊ฐ€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
704
+ - ๋ฐœ๊ฒฌ์€ `loadConfig()` ํ˜ธ์ถœ๋งˆ๋‹ค ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์บ์‹œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
705
+
706
+ **์šฐ์„ ์ˆœ์œ„ (๋†’์Œ โ†’ ๋‚ฎ์Œ):**
707
+
708
+ 1. ๋™์ผํ•œ resolved path๋ฅผ ๊ฐ€์ง„ ๋ช…์‹œ์  `repos[]` ์—”ํŠธ๋ฆฌ โ€” ์ „์ฒด ์Šน๋ฆฌ.
709
+ 2. `workspaces[].defaults` โ€” ๋ ˆํฌ ๋ ˆ๋ฒจ ์˜ค๋ฒ„๋ผ์ด๋“œ ๋ ˆ์ด์–ด.
710
+ 3. ์ „์—ญ `defaults`.
711
+ 4. ๋‚ด์žฅ ๊ธฐ๋ณธ๊ฐ’.
712
+
713
+ **`workspaces[].defaults`๋Š” `monorepo` ํ•„๋“œ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.** ๋ฐœ๊ฒฌ๋œ ๋ ˆํฌ์— monorepo ํ›…์ด ํ•„์š”ํ•˜๋ฉด ๋ช…์‹œ์  `repos[]` ์—”ํŠธ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”.
714
+
715
+ **TUI ํ‘œ์‹œ:** Config ๋ทฐ(Ctrl+P โ†’ Open Config)๋Š” ํŒŒ์ผ์— *์ž‘์„ฑ๋œ ๊ทธ๋Œ€๋กœ* ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์›Œํฌ์ŠคํŽ˜์ด์Šค์—์„œ ์ž๋™ ๋ฐœ๊ฒฌ๋œ ๋ ˆํฌ๋Š” `Repos (N)`๊ฐ€ ์•„๋‹Œ ๋ณ„๋„์˜ `Workspaces (N)` ์„น์…˜์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ `Repos` ์นด์šดํŠธ๋Š” ์›Œํฌ์ŠคํŽ˜์ด์Šค ์ž๋™ ๋ฐœ๊ฒฌ๊ณผ ๋ฌด๊ด€ํ•˜๊ฒŒ ๋ช…์‹œ์ ์ธ `repos[]` ์—”ํŠธ๋ฆฌ๋งŒ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค. Config ๋ทฐ์—์„œ ์–ด๋–ค ํ•„๋“œ๋ฅผ ํŽธ์ง‘ํ•˜๋“  ์‚ฌ์šฉ์ž๊ฐ€ ์ž‘์„ฑํ•œ ์›๋ณธ ํ˜•ํƒœ๊ฐ€ ๋””์Šคํฌ์— ์ €์žฅ๋˜๋ฏ€๋กœ, ์ž๋™ ๋ฐœ๊ฒฌ๋œ ๋ ˆํฌ๊ฐ€ `repos[]`๋กœ ์˜๊ตฌํ™”๋˜๋Š” ์ผ์€ ์—†์Šต๋‹ˆ๋‹ค.
716
+
717
+ #### `monorepo`
718
+
719
+ ๋ฒ”์šฉ ๋ชจ๋…ธ๋ ˆํฌ ์ง€์›. ์›Œํฌ์ŠคํŽ˜์ด์Šค ์„ค์ • ํŒŒ์ผ์—์„œ ํŒจํ‚ค์ง€๋ฅผ ์ž๋™ ๊ฐ์ง€ํ•˜๊ณ  ํŒจํ‚ค์ง€๋ณ„ ํ›…์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
720
+
721
+ ```json
722
+ {
723
+ "monorepo": {
724
+ "autoDetect": true,
725
+ "extraPatterns": ["apps/*/*"],
726
+ "hooks": [
727
+ {
728
+ "glob": "apps/mobile/*",
729
+ "copyFiles": [".env"],
730
+ "linkFiles": ["node_modules"],
731
+ "postCreate": ["cd {packagePath} && pnpm install"]
732
+ }
733
+ ]
734
+ }
735
+ }
736
+ ```
737
+
738
+ | ํ•„๋“œ | ํƒ€์ž… | ๊ธฐ๋ณธ๊ฐ’ | ์„ค๋ช… |
739
+ |------|------|--------|------|
740
+ | `autoDetect` | `boolean` | `true` | ๋ชจ๋…ธ๋ ˆํฌ ๋„๊ตฌ ์ž๋™ ๊ฐ์ง€ |
741
+ | `extraPatterns` | `string[]` | `[]` | ํŒจํ‚ค์ง€ ํƒ์ƒ‰์šฉ ์ถ”๊ฐ€ glob ํŒจํ„ด |
742
+ | `hooks` | `array` | `[]` | ํŒจํ‚ค์ง€๋ณ„ ํ›… ์ •์˜ |
743
+
744
+ **์ž๋™ ๊ฐ์ง€** ์ง€์›: pnpm workspaces, Turborepo, Nx, Lerna, npm/yarn workspaces.
745
+
746
+ **`extraPatterns`**๋Š” ์ž๋™ ๊ฐ์ง€์—์„œ ๋ˆ„๋ฝ๋œ ํŒจํ‚ค์ง€๋ฅผ ์žก์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, `pnpm-workspace.yaml`์ด `packages/*`๋งŒ ์ปค๋ฒ„ํ•˜๋Š”๋ฐ `apps/frontend/dashboard`์—๋„ ์•ฑ์ด ์žˆ๋‹ค๋ฉด `extraPatterns: ["apps/*/*"]`๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.
747
+
748
+ #### `monorepo.hooks[]`
749
+
750
+ ํฌ์ปค์Šค ๊ฒฝ๋กœ์— ๋Œ€ํ•ด glob ํŒจํ„ด์œผ๋กœ ๋งค์นญ๋˜๋Š” ํŒจํ‚ค์ง€๋ณ„ ํ›….
751
+
752
+ | ํ•„๋“œ | ํƒ€์ž… | ํ•„์ˆ˜ | ์„ค๋ช… |
753
+ |------|------|------|------|
754
+ | `glob` | `string` | ์˜ˆ | ํฌ์ปค์Šค ๊ฒฝ๋กœ ๋งค์นญ์šฉ glob (์˜ˆ: `apps/*`, `apps/mobile/*`) |
755
+ | `copyFiles` | `string[]` | ์•„๋‹ˆ์˜ค | ๋งค์นญ๋œ ํŒจํ‚ค์ง€ ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด์—์„œ ๋ณต์‚ฌํ•  ํŒŒ์ผ |
756
+ | `linkFiles` | `string[]` | ์•„๋‹ˆ์˜ค | ๋งค์นญ๋œ ํŒจํ‚ค์ง€ ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด์—์„œ ์‹ฌ๋ณผ๋ฆญ ๋งํฌํ•  ํŒŒ์ผ/๋””๋ ‰ํ† ๋ฆฌ |
757
+ | `postCreate` | `string[]` | ์•„๋‹ˆ์˜ค | ์ƒ์„ฑ ํ›„ ์‹คํ–‰ํ•  ์ปค๋งจ๋“œ. `{packagePath}`, `{repo}`, `{branch}` ์ง€์› |
758
+ | `postRemove` | `string[]` | ์•„๋‹ˆ์˜ค | ์ œ๊ฑฐ ์ „ ์‹คํ–‰ํ•  ์ปค๋งจ๋“œ |
759
+
760
+ ํ›…์€ ์„ ์–ธ ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰๋˜๋ฉฐ, ๋ ˆํฌ ๋ ˆ๋ฒจ `postCreate`/`postRemove` ์ดํ›„์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
761
+
762
+ **ํ›… ๋‚ด `copyFiles`/`linkFiles`**๋Š” ๋ ˆํฌ ๋ฃจํŠธ๊ฐ€ ์•„๋‹Œ **ํŒจํ‚ค์ง€ ์„œ๋ธŒ๋””๋ ‰ํ† ๋ฆฌ**์—์„œ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, `glob: "apps/mobile/*"`์ด๊ณ  `copyFiles: [".env"]`์ด๋ฉด, `.env` ํŒŒ์ผ์€ `<๋ฉ”์ธ-๋ ˆํฌ>/apps/mobile/ios/.env`์—์„œ `<worktree>/apps/mobile/ios/.env`๋กœ ๋ณต์‚ฌ๋ฉ๋‹ˆ๋‹ค.
763
+
764
+ #### `templates`
765
+
766
+ worktree ์ƒ์„ฑ์„ ์œ„ํ•œ ์ด๋ฆ„์ด ๋ถ™์€ ํ”„๋ฆฌ์…‹. ๊ฐ ํ…œํ”Œ๋ฆฟ์€ ๊ธฐ๋ณธ๊ฐ’ ํ•„๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
767
+
768
+ ```json
769
+ {
770
+ "templates": {
771
+ "review": {
772
+ "copyFiles": [".env.local"],
773
+ "postCreate": ["bun install", "bun run build"],
774
+ "autoUpstream": true
775
+ },
776
+ "hotfix": {
777
+ "base": "main",
778
+ "copyFiles": [".env.production"],
779
+ "postCreate": ["bun install"]
780
+ }
781
+ }
782
+ }
783
+ ```
784
+
785
+ | ํ•„๋“œ | ํƒ€์ž… | ์„ค๋ช… |
786
+ |------|------|------|
787
+ | `worktreeDir` | `string` | worktree ๋””๋ ‰ํ† ๋ฆฌ ์˜ค๋ฒ„๋ผ์ด๋“œ |
788
+ | `copyFiles` | `string[]` | ๋ณต์‚ฌํ•  ํŒŒ์ผ ์˜ค๋ฒ„๋ผ์ด๋“œ |
789
+ | `linkFiles` | `string[]` | ์‹ฌ๋ณผ๋ฆญ ๋งํฌํ•  ํŒŒ์ผ ์˜ค๋ฒ„๋ผ์ด๋“œ |
790
+ | `postCreate` | `string[]` | postCreate ํ›… ์˜ค๋ฒ„๋ผ์ด๋“œ |
791
+ | `postRemove` | `string[]` | postRemove ํ›… ์˜ค๋ฒ„๋ผ์ด๋“œ |
792
+ | `autoUpstream` | `boolean` | upstream ์ถ”์  ์˜ค๋ฒ„๋ผ์ด๋“œ |
793
+ | `base` | `string` | ์ƒˆ๋กœ ์ƒ์„ฑ๋˜๋Š” ๋ธŒ๋žœ์น˜์˜ ๊ธฐ๋ณธ ๋ฒ ์ด์Šค ๋ธŒ๋žœ์น˜ |
794
+
795
+ ์‚ฌ์šฉ๋ฒ•: `cop add feature/login --template review`
796
+
797
+ ํ…œํ”Œ๋ฆฟ ๊ฐ’์€ ๋ฆฌ์กธ๋ธŒ๋œ ๋ ˆํฌ ์„ค์ •์„ ์˜ค๋ฒ„๋ผ์ด๋“œํ•ฉ๋‹ˆ๋‹ค. `base` ํ•„๋“œ๋Š” `--base`๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ์ œ๊ณต๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๊ธฐ๋ณธ๊ฐ’์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
798
+
799
+ #### `lifecycle`
800
+
801
+ ์ž๋™ worktree ๋ผ์ดํ”„์‚ฌ์ดํด ๊ด€๋ฆฌ. `cop clean --stale`์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
802
+
803
+ ```json
804
+ {
805
+ "lifecycle": {
806
+ "autoCleanMerged": true,
807
+ "staleAfterDays": 14,
808
+ "maxWorktrees": 10
809
+ }
810
+ }
811
+ ```
812
+
813
+ | ํ•„๋“œ | ํƒ€์ž… | ๊ธฐ๋ณธ๊ฐ’ | ์„ค๋ช… |
814
+ |------|------|--------|------|
815
+ | `autoCleanMerged` | `boolean` | `false` | ๋จธ์ง€๋œ worktree๋ฅผ ์ •๋ฆฌ ๋Œ€์ƒ์œผ๋กœ ํ‘œ์‹œ |
816
+ | `staleAfterDays` | `number` | โ€” | ๋น„ํ™œ์„ฑ์œผ๋กœ ํ‘œ์‹œํ•˜๊ธฐ๊นŒ์ง€ ์ผ์ˆ˜ |
817
+ | `maxWorktrees` | `number` | โ€” | ์ด ์ˆ˜๋ฅผ ์ดˆ๊ณผํ•˜๋ฉด ๊ฒฝ๊ณ  |
818
+
819
+ #### `sessions`
820
+
821
+ worktree๋ณ„ tmux ์„ธ์…˜ ๊ด€๋ฆฌ.
822
+
823
+ ```json
824
+ {
825
+ "sessions": {
826
+ "enabled": true,
827
+ "autoCreate": true,
828
+ "autoKill": true,
829
+ "prefix": "cop",
830
+ "defaultLayout": "dev",
831
+ "layouts": {
832
+ "dev": {
833
+ "windows": [
834
+ { "name": "editor", "command": "$EDITOR ." },
835
+ { "name": "dev", "command": "bun dev" },
836
+ { "name": "test", "command": "bun test --watch" }
837
+ ]
838
+ }
839
+ }
840
+ }
841
+ }
842
+ ```
843
+
844
+ | ํ•„๋“œ | ํƒ€์ž… | ๊ธฐ๋ณธ๊ฐ’ | ์„ค๋ช… |
845
+ |------|------|--------|------|
846
+ | `enabled` | `boolean` | `false` | ์„ธ์…˜ ์—ฐ๋™ ํ™œ์„ฑํ™” (tmux ๋‚ด ์ž๋™ ์ „ํ™˜) |
847
+ | `autoCreate` | `boolean` | `false` | `cop add` ์‹œ tmux ์„ธ์…˜ ์ž๋™ ์ƒ์„ฑ |
848
+ | `autoKill` | `boolean` | `false` | `cop remove` ์‹œ tmux ์„ธ์…˜ ์ž๋™ ์ข…๋ฃŒ |
849
+ | `prefix` | `string` | `"cop"` | tmux ์„ธ์…˜ ์ด๋ฆ„ ์ ‘๋‘์‚ฌ |
850
+ | `defaultLayout` | `string` | โ€” | ์ƒˆ ์„ธ์…˜์˜ ๊ธฐ๋ณธ ๋ ˆ์ด์•„์›ƒ ์ด๋ฆ„ |
851
+ | `layouts` | `object` | `{}` | ์œˆ๋„์šฐ ์ •์˜๊ฐ€ ํฌํ•จ๋œ ์ด๋ฆ„ ์žˆ๋Š” ๋ ˆ์ด์•„์›ƒ |
852
+
853
+ **๋ ˆ์ด์•„์›ƒ ์œˆ๋„์šฐ:**
854
+
855
+ | ํ•„๋“œ | ํƒ€์ž… | ํ•„์ˆ˜ | ์„ค๋ช… |
856
+ |------|------|------|------|
857
+ | `name` | `string` | ์˜ˆ | ์œˆ๋„์šฐ ์ด๋ฆ„ |
858
+ | `command` | `string` | ์•„๋‹ˆ์˜ค | ์œˆ๋„์šฐ์—์„œ ์‹คํ–‰ํ•  ์ปค๋งจ๋“œ |
859
+
860
+ ์„ธ์…˜ ์ด๋ฆ„ ๊ทœ์น™: ๋ธŒ๋žœ์น˜ `feat/auth-token` โ†’ tmux ์„ธ์…˜ `cop_feat-auth-token`.
861
+
862
+ #### `sharedDeps`
863
+
864
+ ๋ฉ”์ธ ๋ ˆํฌ์™€ worktree ๊ฐ„ ์˜์กด์„ฑ์„ ๊ณต์œ ํ•˜์—ฌ ๋””์Šคํฌ ๊ณต๊ฐ„์„ ์ ˆ์•ฝํ•ฉ๋‹ˆ๋‹ค. `defaults` ๋˜๋Š” ๋ ˆํฌ๋ณ„๋กœ ์„ค์ • ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
865
+
866
+ ```json
867
+ {
868
+ "defaults": {
869
+ "sharedDeps": {
870
+ "strategy": "hardlink",
871
+ "paths": ["node_modules"],
872
+ "invalidateOn": ["package.json", "bun.lockb"]
873
+ }
874
+ }
875
+ }
876
+ ```
877
+
878
+ | ํ•„๋“œ | ํƒ€์ž… | ๊ธฐ๋ณธ๊ฐ’ | ์„ค๋ช… |
879
+ |------|------|--------|------|
880
+ | `strategy` | `string` | `"symlink"` | `"hardlink"`, `"symlink"`, ๋˜๋Š” `"copy"` |
881
+ | `paths` | `string[]` | `[]` | ๊ณต์œ ํ•  ๋””๋ ‰ํ† ๋ฆฌ/ํŒŒ์ผ |
882
+ | `invalidateOn` | `string[]` | `[]` | ๋ณ€๊ฒฝ ์‹œ ์žฌ๊ณต์œ ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜๋Š” ํŒŒ์ผ |
883
+
884
+ **์ „๋žต:**
885
+ - `hardlink` โ€” ๊ฐ ํŒŒ์ผ์— ํ•˜๋“œ ๋งํฌ ์ƒ์„ฑ (๋””์Šคํฌ ์ ˆ์•ฝ, ๋‹ค์‹œ ์“ฐ์—ฌ์ง€๋Š” ํŒŒ์ผ์€ worktree๋งˆ๋‹ค ๋…๋ฆฝ์ ์œผ๋กœ ์ˆ˜์ • ๊ฐ€๋Šฅ)
886
+ - `symlink` โ€” ์†Œ์Šค ๋””๋ ‰ํ† ๋ฆฌ์— ์‹ฌ๋ณผ๋ฆญ ๋งํฌ ์ƒ์„ฑ (์ตœ๋Œ€ ๋””์Šคํฌ ์ ˆ์•ฝ, ์ƒํƒœ ๊ณต์œ )
887
+ - `copy` โ€” ์ผ๋ฐ˜ ๋ณต์‚ฌ๋กœ ํด๋ฐฑ
888
+
889
+ ### `--focus` ํ”Œ๋ž˜๊ทธ
890
+
891
+ worktree๊ฐ€ ์ž‘์—… ์ค‘์ธ ๋ชจ๋…ธ๋ ˆํฌ ํŒจํ‚ค์ง€๋ฅผ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค.
892
+
893
+ ```bash
894
+ cop add feature/login --focus apps/web,apps/api
895
+ ```
896
+
897
+ - ์‰ผํ‘œ, ๊ณต๋ฐฑ, ๋˜๋Š” ์—ฌ๋Ÿฌ `--focus` ํ”Œ๋ž˜๊ทธ ์ง€์›
898
+ - ํฌ์ปค์Šค ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋Š” git ๋‚ด๋ถ€์— ์ €์žฅ (worktree ๋ฃจํŠธ๊ฐ€ ์•„๋‹˜)
899
+ - `cop list`์—์„œ worktree๋ณ„ ํฌ์ปค์Šค ๊ฒฝ๋กœ ํ‘œ์‹œ
900
+ - ๋ชจ๋…ธ๋ ˆํฌ ํ›…์€ ๋งค์นญ๋˜๋Š” ํฌ์ปค์Šค ๊ฒฝ๋กœ์— ๋Œ€ํ•ด์„œ๋งŒ ์‹คํ–‰
901
+ - ํฌ์ปค์Šค๋Š” ์„ ํƒ์‚ฌํ•ญ โ€” ์ƒ๋žตํ•˜๋ฉด ์ผ๋ฐ˜ worktree ์ƒ์„ฑ
902
+
903
+ ### ํ…œํ”Œ๋ฆฟ ๋ณ€์ˆ˜
904
+
905
+ `worktreeDir` ๋ฐ ๋ชจ๋…ธ๋ ˆํฌ ํ›… ์ปค๋งจ๋“œ์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ:
906
+
907
+ | ๋ณ€์ˆ˜ | ์„ค๋ช… | ์˜ˆ์‹œ |
908
+ |------|------|------|
909
+ | `{repo}` | ๋ ˆํฌ ๋””๋ ‰ํ† ๋ฆฌ ์ด๋ฆ„ | `my-app` |
910
+ | `{branch}` | ๋ธŒ๋žœ์น˜ ์ด๋ฆ„ (`/`๋Š” `-`๋กœ ๋Œ€์ฒด) | `feature-auth` |
911
+ | `{packagePath}` | ๋งค์นญ๋œ ํŒจํ‚ค์ง€ ๊ฒฝ๋กœ (๋ชจ๋…ธ๋ ˆํฌ ํ›… ์ „์šฉ) | `apps/web` |
912
+ | `~` | ํ™ˆ ๋””๋ ‰ํ† ๋ฆฌ (๊ฒฝ๋กœ ์‹œ์ž‘ ์œ„์น˜์—์„œ๋งŒ) | `/Users/me` |
913
+
914
+ ### ์šฐ์„ ์ˆœ์œ„
915
+
916
+ ๋ ˆํฌ๋ณ„ ์„ค์ •์€ ๊ธฐ๋ณธ๊ฐ’์„ ์™„์ „ํžˆ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค (๋จธ์ง€ ์—†์Œ):
917
+
918
+ ```
919
+ repos[].copyFiles ์กด์žฌ? โ†’ repos[].copyFiles ์‚ฌ์šฉ
920
+ repos[].copyFiles ์—†์Œ? โ†’ defaults.copyFiles ์‚ฌ์šฉ
921
+ defaults.copyFiles ์—†์Œ? โ†’ [] (๋นˆ ๋ฐฐ์—ด) ์‚ฌ์šฉ
922
+ ```
923
+
924
+ ### ํ…Œ๋งˆ
925
+
926
+ ์„ค์ • ํŒŒ์ผ ๋˜๋Š” ์ปค๋งจ๋“œ ํŒ”๋ ˆํŠธ (`Ctrl+P`)์—์„œ ์„ค์ •:
927
+
928
+ ```json
929
+ { "theme": "tokyo-night" }
930
+ ```
931
+
932
+ ์‚ฌ์šฉ ๊ฐ€๋Šฅ: `opencode`, `tokyo-night`, `dracula`, `nord`, `catppuccin`, `github-dark`, `one-dark`, `monokai`, `github-light`
933
+
934
+ ## ์…ธ ํ†ตํ•ฉ
935
+
936
+ `cop shell-init`์œผ๋กœ `cop switch`์šฉ ์…ธ ํ†ตํ•ฉ์„ ์„ค์น˜ํ•˜์„ธ์š”.
937
+
938
+ ### ์…ธ ์ž๋™์™„์„ฑ
939
+
940
+ ```bash
941
+ # ์ž๋™์™„์„ฑ ์ถ”๊ฐ€ (bash)
942
+ eval "$(cop shell-init --completions bash)"
943
+
944
+ # ์ž๋™์™„์„ฑ ์ถ”๊ฐ€ (zsh)
945
+ eval "$(cop shell-init --completions zsh)"
946
+
947
+ # ์ž๋™์™„์„ฑ ์ถ”๊ฐ€ (fish)
948
+ cop shell-init --completions fish | source
949
+ ```
950
+
951
+ ### ์˜ˆ์‹œ
952
+
953
+ ```bash
954
+ # zsh
955
+ echo 'eval "$(cop shell-init zsh)"' >> ~/.zshrc
956
+ source ~/.zshrc
957
+
958
+ # bash
959
+ echo 'eval "$(cop shell-init bash)"' >> ~/.bashrc
960
+ source ~/.bashrc
961
+
962
+ # fish
963
+ cop shell-init fish >> ~/.config/fish/config.fish
964
+ source ~/.config/fish/config.fish
965
+ ```
966
+
967
+ ์„ค์ • ์ €์žฅ ์ „ ์ƒ์„ฑ๋  ๋ž˜ํผ๋ฅผ ๋ฏธ๋ฆฌ ๋ณผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:
968
+
969
+ ```bash
970
+ cop shell-init zsh
971
+ ```
972
+
973
+ ## ์„ค์ • ํ”„๋กœํ•„
974
+
975
+ ์„œ๋กœ ๋‹ค๋ฅธ ์„ค์ • ์„ธํŠธ ๊ฐ„ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
976
+
977
+ ```bash
978
+ cop config --profiles # ํ”„๋กœํ•„ ๋ชฉ๋ก
979
+ cop config --profile work --activate # ํ”„๋กœํ•„ ํ™œ์„ฑํ™”
980
+ cop config --profile personal --delete # ํ”„๋กœํ•„ ์‚ญ์ œ
981
+ ```
982
+
983
+ ## ๋ผ์ด์„ ์Šค
984
+
985
+ MIT ยฉ getsolaris