commitgate 0.2.1 โ†’ 0.3.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.md CHANGED
@@ -1,238 +1,332 @@
1
- # CommitGate
2
-
3
- ๐ŸŒ **ํ•œ๊ตญ์–ด** ยท [English](./README.en.md)
4
-
5
- **AI ์ฝ”๋”ฉ ๋ณ€๊ฒฝ์„ Codex ๋ฆฌ๋ทฐ ์Šน์ธ ์—†์ด๋Š” ์ปค๋ฐ‹ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ๋ง‰๋Š” ์ปค๋ฐ‹ ๊ฒŒ์ดํŠธ์ž…๋‹ˆ๋‹ค.**
6
-
7
- AI ์—์ด์ „ํŠธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ๋น ๋ฅด๊ฒŒ ๋งŒ๋“ค๋”๋ผ๋„, ๋ฆฌ๋ทฐ ์—†์ด ๋ฐ”๋กœ ์ปค๋ฐ‹๋˜๋ฉด ์œ„ํ—˜ํ•ฉ๋‹ˆ๋‹ค. CommitGate๋Š” ๋ณ€๊ฒฝ์„ ํ‹ฐ์ผ“ ๋‹จ์œ„๋กœ ๋ฌถ๊ณ , Codex๊ฐ€ ์Šน์ธํ•œ staged tree๋งŒ ์ปค๋ฐ‹๋˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ์Šน์ธ ํ›„ ์ฝ”๋“œ๊ฐ€ ๋ฐ”๋€Œ๊ฑฐ๋‚˜ ์ฆ๊ฑฐ๊ฐ€ ๋ถ€์กฑํ•˜๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ง‰์Šต๋‹ˆ๋‹ค.
8
-
9
- [![CI](https://github.com/sol5288/commitgate/actions/workflows/ci.yml/badge.svg)](https://github.com/sol5288/commitgate/actions/workflows/ci.yml)
10
- [![npm version](https://img.shields.io/npm/v/commitgate.svg)](https://www.npmjs.com/package/commitgate)
11
- [![license](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
12
-
13
- ---
14
-
15
- ## Quick Start
16
-
17
- ์•„๋ž˜๋Š” ๊ฐ€์žฅ ์งง์€ ์‚ฌ์šฉ ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ๋Š” **git ์ €์žฅ์†Œ์ด๊ณ  `package.json`์ด ์žˆ๋Š” ํด๋”**์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
18
-
19
- ```sh
20
- npx commitgate
21
- npm install
22
- codex --version
23
- codex login status
24
- ```
25
-
26
- ๊ทธ๋‹ค์Œ AI ์ฝ”๋”ฉ ์—์ด์ „ํŠธ์—๊ฒŒ ์•„๋ž˜ ํ”„๋กฌํ”„ํŠธ๋ฅผ ๋ถ™์—ฌ๋„ฃ์Šต๋‹ˆ๋‹ค.
27
-
28
- ```text
29
- ์ด ์š”์ฒญ์€ ์ผ๋ฐ˜ ๊ตฌํ˜„์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์ง€ ๋ง๊ณ , ์ด ํ”„๋กœ์ ํŠธ์— ์„ค์น˜๋œ CommitGate๋ฅผ ์‚ฌ์šฉํ•ด๋ผ.
30
-
31
- ์ƒˆ REQ ํ‹ฐ์ผ“์„ ๋งŒ๋“ค๊ณ  ๋‹ค์Œ ํ๋ฆ„์„ ๋๊นŒ์ง€ ์ง„ํ–‰ํ•ด๋ผ:
32
- req:new โ†’ ์„ค๊ณ„๋ฌธ์„œ ์ž‘์„ฑ โ†’ Codex design ๋ฆฌ๋ทฐ โ†’ ๊ตฌํ˜„ยทํ…Œ์ŠคํŠธ โ†’ req:doctor โ†’ Codex phase ๋ฆฌ๋ทฐ โ†’ req:commit
33
-
34
- ์ž๋™์œผ๋กœ ์ง„ํ–‰ํ•  ๊ฒƒ:
35
- - NEEDS_FIX๊ฐ€ ๋‚˜์˜ค๋ฉด ์ˆ˜์ •ํ•˜๊ณ  ์žฌ๋ฆฌ๋ทฐํ•ด ์Šน์ธ๊นŒ์ง€ ๋ฐ˜๋ณตํ•œ๋‹ค.
36
- - ๋ฆฌ๋ทฐ ๋Œ€์ƒ์€ git add ํ•œ ํŒŒ์ผ๋งŒ์ด๋‹ค.
37
- - `state.json`๊ณผ `responses/`๋Š” ์ง์ ‘ `git add`ํ•˜์ง€ ์•Š๋Š”๋‹ค.
38
-
39
- ๋ฉˆ์ถฐ์„œ ํ™•์ธ๋ฐ›์„ ๋•Œ:
40
- - req:commit --run ์ง์ „
41
- - main ๋ณ‘ํ•ฉ ๋˜๋Š” push ์ง์ „
42
- - reset, clean, force push ๊ฐ™์€ destructive ์ž‘์—… ์ „
43
- - ์š”๊ตฌ์‚ฌํ•ญ ๋ฒ”์œ„๋ฅผ ๋ฐ”๊ฟ”์•ผ ํ•  ๋•Œ
44
- - Codex ๋ฆฌ๋ทฐ๊ฐ€ 3๋ผ์šด๋“œ๋ฅผ ๋„˜์–ด๋„ ์Šน์ธ๋˜์ง€ ์•Š์„ ๋•Œ
45
-
46
- ์š”๊ตฌ์‚ฌํ•ญ:
47
- - ๋ฌด์—‡์„:
48
- - ์™œ:
49
- - ์ œ์•ฝ:
50
- - ์™„๋ฃŒ ๊ธฐ์ค€:
51
- ```
52
-
53
- ์ฒซ ์‘๋‹ต์€ ๋ณดํ†ต ์ด๋ ‡๊ฒŒ ๋‚˜์™€์•ผ ํ•ฉ๋‹ˆ๋‹ค.
54
-
55
- ```text
56
- REQ-2026-002 ๋ฐœํ–‰
57
- ๋ธŒ๋žœ์น˜: feat/req-2026-002-profile-edit-api
58
- phase:
59
- - phase-1: PATCH /profile ๊ตฌํ˜„
60
- - phase-2: ํ…Œ์ŠคํŠธ์™€ ํšŒ๊ท€ ํ™•์ธ
61
- ํ†ต์ œ์ : req:commit --run ์ง์ „, push ์ง์ „
62
- ```
63
-
64
- ์ดํ›„์—๋Š” ์—์ด์ „ํŠธ๊ฐ€ ์„ค๊ณ„, ๊ตฌํ˜„, ํ…Œ์ŠคํŠธ, Codex ๋ฆฌ๋ทฐ๋ฅผ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์ปค๋ฐ‹์ด๋‚˜ push ๊ฐ™์€ ํ†ต์ œ์ ์—์„œ๋งŒ ํ™•์ธํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
65
-
66
- ---
67
-
68
- ## ๋ฌด์—‡์„ ๋ณด์žฅํ•˜๋‚˜์š”?
69
-
70
- CommitGate๊ฐ€ ๋ง‰๋Š” ๊ฒƒ์€ ๋‹จ์ˆœํ•œ ๋ช…๋ น ์‹ค์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ **๋ฆฌ๋ทฐ๋ฐ›์ง€ ์•Š์€ ๋ณ€๊ฒฝ์ด ์ปค๋ฐ‹๋˜๋Š” ์ƒํ™ฉ**์ž…๋‹ˆ๋‹ค.
71
-
72
- - Codex ๋ฆฌ๋ทฐ๊ฐ€ ์‹คํŒจํ•˜๊ฑฐ๋‚˜ ์—†์œผ๋ฉด ์ปค๋ฐ‹ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
73
- - ์Šน์ธ๋œ staged tree์™€ ์ง€๊ธˆ ์ปค๋ฐ‹ํ•˜๋ ค๋Š” staged tree๊ฐ€ ๋‹ค๋ฅด๋ฉด ๋ง‰์Šต๋‹ˆ๋‹ค.
74
- - `state.json`, `responses/` ๊ฐ™์€ ์›Œํฌํ”Œ๋กœ ๋‚ด๋ถ€ ํŒŒ์ผ์„ source ์ปค๋ฐ‹์— ์„ž์œผ๋ฉด ๋ง‰์Šต๋‹ˆ๋‹ค.
75
- - Codex CLI๊ฐ€ ์—†๊ฑฐ๋‚˜ ์‹คํ–‰์— ์‹คํŒจํ•˜๋ฉด ์กฐ์šฉํžˆ ํ†ต๊ณผํ•˜์ง€ ์•Š๊ณ  ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.
76
- - ์„ค์น˜ ์‹œ ๊ธฐ์กด `cross-spawn`์ด ๊ฒ€์ฆ ํ•˜ํ•œ๋ณด๋‹ค ๋‚ฎ์œผ๋ฉด ๊ฒฝ๊ณ ํ•˜๊ณ , `--strict`์—์„œ๋Š” ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค.
77
- - ์Šน์ธ ์‘๋‹ต๊ณผ ์ฆ๊ฑฐ ํŒŒ์ผ์€ `workflow/REQ-.../responses/`์— ๋‚จ์Šต๋‹ˆ๋‹ค.
78
-
79
- ํ•œ ์ค„๋กœ ๋งํ•˜๋ฉด, **ํ™•์‹คํžˆ ์Šน์ธ๋œ ๋ณ€๊ฒฝ๋งŒ ํ†ต๊ณผํ•˜๊ณ  ์• ๋งคํ•˜๋ฉด ๋ฉˆ์ถ”๋Š” ๋ฐฉ์‹**์ž…๋‹ˆ๋‹ค.
80
-
81
- ---
82
-
83
- ## ์„ค์น˜๊ฐ€ ํ•˜๋Š” ์ผ
84
-
85
- `npx commitgate`๋Š” ๋Œ€์ƒ ํ”„๋กœ์ ํŠธ์— ์•„๋ž˜ ํŒŒ์ผ๊ณผ ์„ค์ •์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด ํŒŒ์ผ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฎ์–ด์“ฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
86
-
87
- | ์ถ”๊ฐ€ ํ•ญ๋ชฉ | ์„ค๋ช… |
88
- |---|---|
89
- | `scripts/req/` | `req:new`, `req:review-codex`, `req:doctor`, `req:commit` ์Šคํฌ๋ฆฝํŠธ |
90
- | `workflow/*.schema.json` | Codex ์‘๋‹ต๊ณผ ์„ค์ • ๊ฒ€์ฆ ์Šคํ‚ค๋งˆ |
91
- | `req.config.json` | ํ”„๋กœ์ ํŠธ๋ณ„ ์„ค์ • |
92
- | `AGENTS.md` | ์—์ด์ „ํŠธ์™€ Reviewer๊ฐ€ ์ฝ๋Š” ๊ทœ์น™ ํ…œํ”Œ๋ฆฟ |
93
- | `package.json` ์Šคํฌ๋ฆฝํŠธ | `req:*` ๋ช…๋ น๊ณผ ํ•„์š”ํ•œ devDependencies |
94
-
95
- ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋งŒ ํ•˜๋ ค๋ฉด:
96
-
97
- ```sh
98
- npx commitgate --dry-run
99
- ```
100
-
101
- ๋ณด์•ˆ ํ•˜ํ•œ ๊ฒฝ๊ณ ๋ฅผ ์„ค์น˜ ์‹คํŒจ๋กœ ์ทจ๊ธ‰ํ•˜๋ ค๋ฉด:
102
-
103
- ```sh
104
- npx commitgate --strict
105
- ```
106
-
107
- ๊ธฐ์กด `cross-spawn`์ด ๊ฒ€์ฆ ํ•˜ํ•œ๋ณด๋‹ค ๋‚ฎ์œผ๋ฉด ํŒŒ์ผ์„ ๋ณต์‚ฌํ•˜๊ธฐ ์ „์— ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค.
108
-
109
- ---
110
-
111
- ## ์ค€๋น„๋ฌผ
112
-
113
- | ํ•„์š” | ํ™•์ธ ๋ช…๋ น | ๋น„๊ณ  |
114
- |---|---|---|
115
- | Git | `git --version` | ํ•„์ˆ˜ |
116
- | Node.js 18.17+ | `node --version` | ํ•„์ˆ˜ |
117
- | npm, pnpm, yarn ์ค‘ ํ•˜๋‚˜ | `npm --version` | npm ๊ธฐ์ค€์œผ๋กœ ์•ˆ๋‚ด |
118
- | Codex CLI | `codex --version` | ๋ฆฌ๋ทฐ ์‹คํ–‰์— ํ•„์š” |
119
-
120
- Codex CLI๊ฐ€ ์—†๋‹ค๋ฉด:
121
-
122
- ```sh
123
- npm install -g @openai/codex
124
- codex login
125
- codex login status
126
- ```
127
-
128
- Windows์—์„œ ์„ค์น˜ ์งํ›„ `codex` ๋ช…๋ น์„ ๋ชป ์ฐพ์œผ๋ฉด ์ƒˆ ํ„ฐ๋ฏธ๋„์„ ์—ด์–ด PATH๋ฅผ ๋‹ค์‹œ ์ฝ๊ฒŒ ํ•˜์„ธ์š”.
129
-
130
- ---
131
-
132
- ## ์ˆ˜๋™ ๋ช…๋ น
133
-
134
- ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ์ž๋Š” ์œ„ ํ”„๋กฌํ”„ํŠธ ๋ฐฉ์‹์œผ๋กœ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” ๋‚ด๋ถ€์—์„œ ์–ด๋–ค ๋ช…๋ น์ด ์‹คํ–‰๋˜๋Š”์ง€ ์ดํ•ดํ•˜๊ฑฐ๋‚˜ ์ง์ ‘ ๋””๋ฒ„๊น…ํ•  ๋•Œ๋งŒ ๋ณด๋ฉด ๋ฉ๋‹ˆ๋‹ค.
135
-
136
- ```sh
137
- # 1. ํ‹ฐ์ผ“๊ณผ ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ
138
- npm run req:new -- my-feature --run
139
-
140
- # 2. ์„ค๊ณ„ ๋ฌธ์„œ ์ž‘์„ฑ ํ›„ stage
141
- git add workflow/REQ-2026-001/00-requirement.md workflow/REQ-2026-001/01-design.md workflow/REQ-2026-001/02-plan.md
142
-
143
- # 3. ์„ค๊ณ„ ๋ฆฌ๋ทฐ
144
- npm run req:review-codex -- 2026-001 --kind design --run
145
-
146
- # 4. ์ฝ”๋“œ ๊ตฌํ˜„ ํ›„ stage
147
- git add <changed-source-files>
148
-
149
- # 5. ๊ฒŒ์ดํŠธ ์ ๊ฒ€
150
- npm run req:doctor -- 2026-001
151
-
152
- # 6. ๊ตฌํ˜„ ๋ฆฌ๋ทฐ
153
- npm run req:review-codex -- 2026-001 --kind phase --run
154
-
155
- # 7. ์Šน์ธ๋œ ์ฝ”๋“œ ์ปค๋ฐ‹
156
- npm run req:commit -- 2026-001 --run -m "feat: my feature"
157
- ```
158
-
159
- ์ค‘์š”: source ์ปค๋ฐ‹์—๋Š” ๋‚ด๊ฐ€ ๋งŒ๋“  ์ฝ”๋“œ์™€ ๋ฌธ์„œ๋งŒ stageํ•˜์„ธ์š”. `state.json`๊ณผ `responses/`๋Š” ๋„๊ตฌ๊ฐ€ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
160
-
161
- ์—ฌ๋Ÿฌ ์ค„ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€๋Š” `-m` ๋Œ€์‹  ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜์„ธ์š”.
162
-
163
- ```sh
164
- npm run req:commit -- 2026-001 --run --message-file commit-message.txt
165
- ```
166
-
167
- ---
168
-
169
- ## ๋ช…๋ น์–ด ์š”์•ฝ
170
-
171
- | ๋ช…๋ น | ์šฉ๋„ |
172
- |---|---|
173
- | `npx commitgate` | ํ”„๋กœ์ ํŠธ์— CommitGate ์„ค์น˜ |
174
- | `npx commitgate --dry-run` | ํŒŒ์ผ์„ ์“ฐ์ง€ ์•Š๊ณ  ์„ค์น˜ ๊ณ„ํš ํ™•์ธ |
175
- | `npx commitgate --strict` | ๋‚ฎ์€ `cross-spawn` ๋ฒ„์ „ ๊ฒฝ๊ณ ๋ฅผ ์„ค์น˜ ์‹คํŒจ๋กœ ์ฒ˜๋ฆฌ |
176
- | `req:new <slug> --run` | REQ ํ‹ฐ์ผ“, ๋ธŒ๋žœ์น˜, ์„ค๊ณ„๋ฌธ์„œ ์ƒ์„ฑ |
177
- | `req:review-codex <id> --kind design --run` | ์„ค๊ณ„ ๋ฆฌ๋ทฐ |
178
- | `req:review-codex <id> --kind phase --run` | ๊ตฌํ˜„ ๋ฆฌ๋ทฐ |
179
- | `req:doctor <id>` | ๊ฒŒ์ดํŠธ ์ƒํƒœ ํ™•์ธ |
180
- | `req:commit <id> --run -m "message"` | ์Šน์ธ๋œ ๋ณ€๊ฒฝ ์ปค๋ฐ‹ |
181
-
182
- ---
183
-
184
- ## ์„ค์ •
185
-
186
- ๋Œ€๋ถ€๋ถ„์€ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ํ•„์š”ํ•˜๋ฉด ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์˜ `req.config.json`์„ ์ˆ˜์ •ํ•˜์„ธ์š”.
187
-
188
- | ํ•ญ๋ชฉ | ๊ธฐ๋ณธ๊ฐ’ | ์„ค๋ช… |
189
- |---|---|---|
190
- | `branchPrefix` | `"feat/req-"` | ์ƒˆ ๋ธŒ๋žœ์น˜ prefix |
191
- | `ticketRoot` | `"workflow"` | REQ ํ‹ฐ์ผ“ ํด๋” |
192
- | `packageManager` | ์ž๋™ ๊ฐ์ง€ | `npm`, `pnpm`, `yarn` |
193
- | `designDocs` | `00/01/02` ๋ฌธ์„œ | ์„ค๊ณ„ ๋ฌธ์„œ ํŒŒ์ผ๋ช… |
194
-
195
- ๋นˆ `branchPrefix`๋‚˜ ํ”„๋กœ์ ํŠธ ๋ฐ–์œผ๋กœ ๋‚˜๊ฐ€๋Š” ๊ฒฝ๋กœ๋Š” ๊ฑฐ๋ถ€๋ฉ๋‹ˆ๋‹ค.
196
-
197
- ---
198
-
199
- ## FAQ
200
-
201
- **Codex CLI๊ฐ€ ์—†์œผ๋ฉด ์–ด๋–ป๊ฒŒ ๋˜๋‚˜์š”?**
202
- ๋ฆฌ๋ทฐ ๋ช…๋ น์ด ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. ์กฐ์šฉํžˆ ์Šน์ธ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
203
-
204
- **์Šน์ธ ํ›„ ์ฝ”๋“œ๋ฅผ ์กฐ๊ธˆ ๊ณ ์น˜๋ฉด ์ปค๋ฐ‹๋˜๋‚˜์š”?**
205
- ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ์Šน์ธ๋œ staged tree์™€ ๋‹ฌ๋ผ์ง€๋ฉด stale ์Šน์ธ์œผ๋กœ ๋ณด๊ณ  ๋‹ค์‹œ ๋ฆฌ๋ทฐ๋ฅผ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค.
206
-
207
- **`state.json`์ด๋‚˜ `responses/`๋Š” ์™œ stageํ•˜๋ฉด ์•ˆ ๋˜๋‚˜์š”?**
208
- ์›Œํฌํ”Œ๋กœ ์ฆ๊ฑฐ์™€ ์ƒํƒœ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค. source ์ปค๋ฐ‹์— ์„ž์ด๋ฉด ์Šน์ธ ๋ฐ”์ธ๋”ฉ์ด ํ๋ ค์ง€๋ฏ€๋กœ `req:commit`์ด ๋ง‰์Šต๋‹ˆ๋‹ค.
209
-
210
- **cross-spawn ๋ฒ„์ „ ๊ฒฝ๊ณ ๊ฐ€ ๋‚˜์˜ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•˜๋‚˜์š”?**
211
- ๋Œ€์ƒ ํ”„๋กœ์ ํŠธ์˜ ๊ธฐ์กด `cross-spawn`์ด CommitGate๊ฐ€ ๊ฒ€์ฆํ•œ ํ•˜ํ•œ๋ณด๋‹ค ๋‚ฎ์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค. `npm i -D cross-spawn@^7.0.6`์œผ๋กœ ์˜ฌ๋ฆฌ์„ธ์š”. CI๋‚˜ ๋ณด์•ˆ ๋ฏผ๊ฐ ํ™˜๊ฒฝ์—์„œ๋Š” `npx commitgate --strict`๋ฅผ ์‚ฌ์šฉํ•ด ๊ฒฝ๊ณ ๋ฅผ ์‹คํŒจ๋กœ ๋‹ค๋ฃจ์„ธ์š”.
212
-
213
- **๋‘ ๋ฒˆ ์„ค์น˜ํ•˜๋ฉด ๋ฎ์–ด์“ฐ๋‚˜์š”?**
214
- ์•„๋‹ˆ์š”. ๊ธฐ์กด ํŒŒ์ผ์€ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค. ๊ฐ•์ œ๋กœ ๊ฐฑ์‹ ํ•˜๋ ค๋ฉด `--force`๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.
215
-
216
- ---
217
-
218
- ## ํ˜„์žฌ ๋ฒ”์œ„
219
-
220
- ํ˜„์žฌ ๋ฒ„์ „์€ **Stage A: vendored scaffold ๋ชจ๋ธ**์ž…๋‹ˆ๋‹ค. ์ฆ‰ `npx commitgate`๊ฐ€ ๋Œ€์ƒ ํ”„๋กœ์ ํŠธ์— ์›Œํฌํ”Œ๋กœ ํŒŒ์ผ์„ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.
221
-
222
- ํ˜„์žฌ ์šด์˜ ์ค‘์ธ ๊ฒ€์ฆ์ž…๋‹ˆ๋‹ค.
223
-
224
- - GitHub Actions์—์„œ `ubuntu-latest`, `macos-latest`, `windows-latest` ร— Node 18/20/22 ๋งคํŠธ๋ฆญ์Šค๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
225
- - `npm run smoke`๋Š” pack tarball ์„ค์น˜๋ณธ์˜ `commitgate` bin์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
226
- - Windows `.cmd` ๋ž˜ํผ ์ฃผ์ž… ํšŒ๊ท€ ํ…Œ์ŠคํŠธ๊ฐ€ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €์™€ Codex wrapper ๊ฒฝ๋กœ๋ฅผ ๋ณดํ˜ธํ•ฉ๋‹ˆ๋‹ค.
227
-
228
- ์•„๋ž˜๋Š” ํ›„์† ๋ฒ”์œ„์ž…๋‹ˆ๋‹ค.
229
-
230
- - `node_modules`์—์„œ ์ง์ ‘ ์‹คํ–‰ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ชจ๋ธ
231
- - ๋น„-git VCS ์ง€์›
232
- - ๋” ๋‹ค์–‘ํ•œ ์„ค๊ณ„๋ฌธ์„œ ํ…œํ”Œ๋ฆฟ
233
-
234
- ---
235
-
236
- ## License
237
-
238
- [MIT](./LICENSE) ยฉ 2026 sol5288
1
+ # CommitGate
2
+
3
+ ๐ŸŒ **ํ•œ๊ตญ์–ด** ยท [English](./README.en.md)
4
+
5
+ **AI ์ฝ”๋”ฉ ๋ณ€๊ฒฝ์„ Codex ๋ฆฌ๋ทฐ ์Šน์ธ ์—†์ด๋Š” ์ปค๋ฐ‹ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ๋ง‰๋Š” ์ปค๋ฐ‹ ๊ฒŒ์ดํŠธ์ž…๋‹ˆ๋‹ค.**
6
+
7
+ AI ์—์ด์ „ํŠธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ๋น ๋ฅด๊ฒŒ ๋งŒ๋“ค๋”๋ผ๋„, ๋ฆฌ๋ทฐ ์—†์ด ๋ฐ”๋กœ ์ปค๋ฐ‹๋˜๋ฉด ์œ„ํ—˜ํ•ฉ๋‹ˆ๋‹ค. CommitGate๋Š” ๋ณ€๊ฒฝ์„ ํ‹ฐ์ผ“ ๋‹จ์œ„๋กœ ๋ฌถ๊ณ , Codex๊ฐ€ ์Šน์ธํ•œ staged tree๋งŒ ์ปค๋ฐ‹๋˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ์Šน์ธ ํ›„ ์ฝ”๋“œ๊ฐ€ ๋ฐ”๋€Œ๊ฑฐ๋‚˜ ์ฆ๊ฑฐ๊ฐ€ ๋ถ€์กฑํ•˜๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ง‰์Šต๋‹ˆ๋‹ค.
8
+
9
+ [![CI](https://github.com/sol5288/commitgate/actions/workflows/ci.yml/badge.svg)](https://github.com/sol5288/commitgate/actions/workflows/ci.yml)
10
+ [![npm version](https://img.shields.io/npm/v/commitgate.svg)](https://www.npmjs.com/package/commitgate)
11
+ [![license](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
12
+
13
+ ---
14
+
15
+ ## Quick Start
16
+
17
+ ์•„๋ž˜๋Š” ๊ฐ€์žฅ ์งง์€ ์‚ฌ์šฉ ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ๋Š” **git ์ €์žฅ์†Œ์ด๊ณ  `package.json`์ด ์žˆ๋Š” ํด๋”**์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
18
+
19
+ ```sh
20
+ # ์•„์ง git ์ €์žฅ์†Œ๊ฐ€ ์•„๋‹ˆ๊ฑฐ๋‚˜ package.json์ด ์—†๋Š” ์ƒˆ ํด๋”๋ผ๋ฉด ๋จผ์ €:
21
+ git init
22
+ npm init -y
23
+
24
+ # ๊ทธ๋‹ค์Œ ์„ค์น˜:
25
+ npx commitgate
26
+ npm install
27
+ codex --version
28
+ codex login status
29
+ ```
30
+
31
+ ๊ทธ๋‹ค์Œ AI ์ฝ”๋”ฉ ์—์ด์ „ํŠธ์—๊ฒŒ ์•„๋ž˜ ํ”„๋กฌํ”„ํŠธ๋ฅผ ๋ถ™์—ฌ๋„ฃ์Šต๋‹ˆ๋‹ค.
32
+
33
+ ```text
34
+ ์ด ์š”์ฒญ์€ ์ผ๋ฐ˜ ๊ตฌํ˜„์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์ง€ ๋ง๊ณ , ์ด ํ”„๋กœ์ ํŠธ์— ์„ค์น˜๋œ CommitGate๋ฅผ ์‚ฌ์šฉํ•ด๋ผ.
35
+
36
+ ์ƒˆ REQ ํ‹ฐ์ผ“์„ ๋งŒ๋“ค๊ณ  ๋‹ค์Œ ํ๋ฆ„์„ ๋๊นŒ์ง€ ์ง„ํ–‰ํ•ด๋ผ:
37
+ req:new โ†’ ์„ค๊ณ„๋ฌธ์„œ ์ž‘์„ฑ โ†’ Codex design ๋ฆฌ๋ทฐ โ†’ ๊ตฌํ˜„ยทํ…Œ์ŠคํŠธ โ†’ req:doctor โ†’ Codex phase ๋ฆฌ๋ทฐ โ†’ req:commit
38
+
39
+ ์ž๋™์œผ๋กœ ์ง„ํ–‰ํ•  ๊ฒƒ:
40
+ - `req:review-codex`๊ฐ€ NEEDS_FIX/exit 3์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด findings๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  ์žฌ๋ฆฌ๋ทฐํ•œ๋‹ค.
41
+ - BLOCKED/exit 2๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๊ฐ™์€ ๋ฆฌ๋ทฐ๋ฅผ ์žฌ์‹œ๋„ํ•˜์ง€ ๋ง๊ณ  ์‚ฌ๋žŒ์—๊ฒŒ ๋ณด๊ณ ํ•˜๊ฑฐ๋‚˜ ๋ฆฌ๋ทฐ ๋Œ€์ƒ์„ ๋ฐ”๊พผ๋‹ค. ์Šค๋ ˆ๋“œ ๊ณ ์ฐฉ์ด ์˜์‹ฌ๋˜๋ฉด `--fresh-thread`๋กœ ํ•œ ๋ฒˆ๋งŒ ํšŒ๋ณต์„ ์‹œ๋„ํ•  ์ˆ˜ ์žˆ๋‹ค.
42
+ - ๋ฆฌ๋ทฐ ๋Œ€์ƒ์€ git add ํ•œ ํŒŒ์ผ๋งŒ์ด๋‹ค.
43
+ - `state.json`๊ณผ `responses/`๋Š” ์ง์ ‘ `git add`ํ•˜์ง€ ์•Š๋Š”๋‹ค.
44
+
45
+ ๋ฉˆ์ถฐ์„œ ํ™•์ธ๋ฐ›์„ ๋•Œ(๊ฐ ํ•ญ๋ชฉ์€ ๊ทธ ๋ฌธ์žฅ ๊ทธ๋Œ€๋กœ ์Šน์ธ๋ฐ›์•„์•ผ ํ•˜๋ฉฐ, ํ•œ ์Šน์ธ์€ ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ์ด์›”๋˜์ง€ ์•Š๋Š”๋‹ค):
46
+ - req:commit --run ์ง์ „
47
+ - [๊ฒฝ๋กœ A ยท ์„ ํƒ] [I1] feature branch push + PR ์ƒ์„ฑ ์ง์ „ / [I2] required checks green ํ™•์ธ ํ›„ PR merge ์ง์ „
48
+ - [๊ฒฝ๋กœ B] [B1] protected branch์— direct push ์ง์ „ โ€” "branch protection bypass๋ฅผ ์‚ฌ์šฉํ•œ direct push ์Šน์ธ"์„ ๋”ฐ๋กœ ๋ฐ›๋Š”๋‹ค. ์ด push๋Š” required checks๋ฅผ ์šฐํšŒํ•˜๊ณ , CI๋Š” ์‚ฌํ›„์— ๋ˆ๋‹ค
49
+ - [R1/R2/R3] tag ์ƒ์„ฑยทpush / npm publish / GitHub release โ€” CI green ํ™•์ธ ํ›„ ๊ฐ๊ฐ ๋ณ„๋„ ์Šน์ธ
50
+ - reset, clean, force push ๊ฐ™์€ destructive ์ž‘์—… ์ „
51
+ - ์š”๊ตฌ์‚ฌํ•ญ ๋ฒ”์œ„๋ฅผ ๋ฐ”๊ฟ”์•ผ ํ•  ๋•Œ
52
+ - Codex ๋ฆฌ๋ทฐ๊ฐ€ BLOCKED๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜ ์ œํ•œ๋œ ์žฌ์‹œ๋„ ํ›„์—๋„ ํŒ๋‹จ์ด ๋ถˆ๋ช…ํ™•ํ•  ๋•Œ
53
+
54
+ ์š”๊ตฌ์‚ฌํ•ญ:
55
+ - ๋ฌด์—‡์„:
56
+ - ์™œ:
57
+ - ์ œ์•ฝ:
58
+ - ์™„๋ฃŒ ๊ธฐ์ค€:
59
+ ```
60
+
61
+ ์ฒซ ์‘๋‹ต์€ ๋ณดํ†ต ์ด๋ ‡๊ฒŒ ๋‚˜์™€์•ผ ํ•ฉ๋‹ˆ๋‹ค.
62
+
63
+ ```text
64
+ REQ-2026-002 ๋ฐœํ–‰
65
+ ๋ธŒ๋žœ์น˜: feat/req-2026-002-profile-edit-api
66
+ phase:
67
+ - phase-1: PATCH /profile ๊ตฌํ˜„
68
+ - phase-2: ํ…Œ์ŠคํŠธ์™€ ํšŒ๊ท€ ํ™•์ธ
69
+ ํ†ต์ œ์ : req:commit --run ์ง์ „ / [B1] main direct push ์ง์ „ (๋˜๋Š” [I1] PR ์ƒ์„ฑ โ†’ [I2] merge)
70
+ ```
71
+
72
+ ์ดํ›„์—๋Š” ์—์ด์ „ํŠธ๊ฐ€ ์„ค๊ณ„, ๊ตฌํ˜„, ํ…Œ์ŠคํŠธ, Codex ๋ฆฌ๋ทฐ๋ฅผ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ํ†ต์ œ์ ์—์„œ๋งŒ ํ™•์ธํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
73
+
74
+ main์— ๋ฐ˜์˜ํ•˜๋Š” ๊ฒฝ๋กœ๋Š” **PR ๊ฒฝ์œ (์„ ํƒ)**์™€ **direct push** ๋‘˜ ๋‹ค ์œ ํšจํ•ฉ๋‹ˆ๋‹ค. PR์€ ์˜๋ฌด๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ๋‹ค๋งŒ protected branch๋กœ ์ง์ ‘ pushํ•˜๋ฉด required checks๋ฅผ **์šฐํšŒ**ํ•˜๋ฏ€๋กœ "branch protection bypass๋ฅผ ์‚ฌ์šฉํ•œ direct push ์Šน์ธ"์„ ๋”ฐ๋กœ ๋ฐ›์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค โ€” bypass ๊ถŒํ•œ์ด ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์€ ์Šน์ธ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๋•Œ CI๋Š” push **์ดํ›„์—** ๋„๋Š” **์‚ฌํ›„ ๊ฒ€์ฆ**์ด๋ผ, ๊ทธ ์‚ฌ์‹ค์„ ๋ณด๊ณ ์—์„œ ์ƒ๋žตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. tag, npm publish, GitHub release๋Š” ๋ฐ˜์˜๊ณผ ๋ฌถ์ด์ง€ ์•Š๋Š” ๋ณ„๋„ ํ†ต์ œ์ ์ด๊ณ  CI green ์ดํ›„์— ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๊ณ„์•ฝ์€ [AGENTS.template.md](AGENTS.template.md)์™€ [docs/RELEASING.md](docs/RELEASING.md)๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.
75
+
76
+ ---
77
+
78
+ ## ๋ฌด์—‡์„ ๋ณด์žฅํ•˜๋‚˜์š”?
79
+
80
+ CommitGate๊ฐ€ ๋ง‰๋Š” ๊ฒƒ์€ ๋‹จ์ˆœํ•œ ๋ช…๋ น ์‹ค์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ **๋ฆฌ๋ทฐ๋ฐ›์ง€ ์•Š์€ ๋ณ€๊ฒฝ์ด ์ปค๋ฐ‹๋˜๋Š” ์ƒํ™ฉ**์ž…๋‹ˆ๋‹ค.
81
+
82
+ - Codex ๋ฆฌ๋ทฐ๊ฐ€ ์‹คํŒจํ•˜๊ฑฐ๋‚˜ ์—†์œผ๋ฉด ์ปค๋ฐ‹ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
83
+ - ์Šน์ธ๋œ staged tree์™€ ์ง€๊ธˆ ์ปค๋ฐ‹ํ•˜๋ ค๋Š” staged tree๊ฐ€ ๋‹ค๋ฅด๋ฉด ๋ง‰์Šต๋‹ˆ๋‹ค.
84
+ - `state.json`, `responses/` ๊ฐ™์€ ์›Œํฌํ”Œ๋กœ ๋‚ด๋ถ€ ํŒŒ์ผ์„ source ์ปค๋ฐ‹์— ์„ž์œผ๋ฉด ๋ง‰์Šต๋‹ˆ๋‹ค.
85
+ - Codex CLI๊ฐ€ ์—†๊ฑฐ๋‚˜ ์‹คํ–‰์— ์‹คํŒจํ•˜๋ฉด ์กฐ์šฉํžˆ ํ†ต๊ณผํ•˜์ง€ ์•Š๊ณ  ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.
86
+ - ๋ฆฌ๋ทฐ ์ข…๋ฃŒ์ฝ”๋“œ๋Š” outcome ๊ธฐ์ค€์ž…๋‹ˆ๋‹ค: `0` ์Šน์ธ, `1` ๋ฌดํšจ/fail-closed, `2` blocked(์ง€์  ์—†์Œ+๋ฏธ์Šน์ธ), `3` needs-fix.
87
+ - ์ง€์ ์€ ์—†์ง€๋งŒ ์Šน์ธ๋„ ์—†๋Š” ์‘๋‹ต์€ NEEDS_FIX๊ฐ€ ์•„๋‹ˆ๋ผ BLOCKED์ด๋ฉฐ, ์—์ด์ „ํŠธ๋Š” ๊ฐ™์€ ๋ฆฌ๋ทฐ๋ฅผ ๋ฐ˜๋ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
88
+ - ์„ค์น˜ ์‹œ ๊ธฐ์กด `cross-spawn`์ด ๊ฒ€์ฆ ํ•˜ํ•œ๋ณด๋‹ค ๋‚ฎ์œผ๋ฉด ๊ฒฝ๊ณ ํ•˜๊ณ , `--strict`์—์„œ๋Š” ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค.
89
+ - ์Šน์ธ ์‘๋‹ต๊ณผ ์ฆ๊ฑฐ ํŒŒ์ผ์€ `workflow/REQ-.../responses/`์— ๋‚จ์Šต๋‹ˆ๋‹ค.
90
+
91
+ ํ•œ ์ค„๋กœ ๋งํ•˜๋ฉด, **ํ™•์‹คํžˆ ์Šน์ธ๋œ ๋ณ€๊ฒฝ๋งŒ ํ†ต๊ณผํ•˜๊ณ  ์• ๋งคํ•˜๋ฉด ๋ฉˆ์ถ”๋Š” ๋ฐฉ์‹**์ž…๋‹ˆ๋‹ค.
92
+
93
+ ---
94
+
95
+ ## ์„ค์น˜๊ฐ€ ํ•˜๋Š” ์ผ
96
+
97
+ `npx commitgate`๋Š” ๋Œ€์ƒ ํ”„๋กœ์ ํŠธ์— ์•„๋ž˜ ํŒŒ์ผ๊ณผ ์„ค์ •์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด ํŒŒ์ผ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฎ์–ด์“ฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
98
+
99
+ | ์ถ”๊ฐ€ ํ•ญ๋ชฉ | ์„ค๋ช… |
100
+ |---|---|
101
+ | `scripts/req/` | `req:new`, `req:review-codex`, `req:doctor`, `req:commit` ์Šคํฌ๋ฆฝํŠธ |
102
+ | `workflow/*.schema.json` | Codex ์‘๋‹ต๊ณผ ์„ค์ • ๊ฒ€์ฆ ์Šคํ‚ค๋งˆ |
103
+ | `req.config.json` | ํ”„๋กœ์ ํŠธ๋ณ„ ์„ค์ • |
104
+ | `AGENTS.md` | ์—์ด์ „ํŠธ์™€ Reviewer๊ฐ€ ์ฝ๋Š” ๊ทœ์น™ ํ…œํ”Œ๋ฆฟ |
105
+ | `package.json` ์Šคํฌ๋ฆฝํŠธ | `req:*` ๋ช…๋ น๊ณผ ํ•„์š”ํ•œ devDependencies |
106
+
107
+ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋งŒ ํ•˜๋ ค๋ฉด:
108
+
109
+ ```sh
110
+ npx commitgate --dry-run
111
+ ```
112
+
113
+ ๋ณด์•ˆ ํ•˜ํ•œ ๊ฒฝ๊ณ ๋ฅผ ์„ค์น˜ ์‹คํŒจ๋กœ ์ทจ๊ธ‰ํ•˜๋ ค๋ฉด:
114
+
115
+ ```sh
116
+ npx commitgate --strict
117
+ ```
118
+
119
+ ๊ธฐ์กด `cross-spawn`์ด ๊ฒ€์ฆ ํ•˜ํ•œ๋ณด๋‹ค ๋‚ฎ์œผ๋ฉด ํŒŒ์ผ์„ ๋ณต์‚ฌํ•˜๊ธฐ ์ „์— ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค.
120
+
121
+ > `workflow/machine.schema.json`๊ณผ `workflow/req.config.schema.json`์€ `req.config.json`์˜ `ticketRoot` ์„ค์ •๊ณผ ๋ฌด๊ด€ํ•˜๊ฒŒ **ํ•ญ์ƒ `workflow/` ์•„๋ž˜**์— ๋ณต์‚ฌ๋ฉ๋‹ˆ๋‹ค.
122
+
123
+ ---
124
+
125
+ ## ์ œ๊ฑฐํ•˜๋ ค๋ฉด
126
+
127
+ ๋จผ์ € ์•Œ์•„๋‘˜ ๊ฒƒ: **`npx commitgate`๋Š” ์ „์—ญ ์„ค์น˜๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.** npx๋Š” ํŒจํ‚ค์ง€๋ฅผ npm ์บ์‹œ(`_npx/<hash>/`)์— ๋ฐ›์•„ ํ•œ ๋ฒˆ ์‹คํ–‰ํ•  ๋ฟ์ด๊ณ , ์ „์—ญ `node_modules`์—๋„ PATH์—๋„ ์•„๋ฌด๊ฒƒ๋„ ๋‚จ๊ธฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‹ค์ œ "์„ค์น˜๋ฌผ"์€ ์œ„ ํ‘œ๋Œ€๋กœ **๋Œ€์ƒ repo์— ์ถ”๊ฐ€๋œ ํŒŒ์ผ๊ณผ `package.json` ๋ณ€๊ฒฝ**์ž…๋‹ˆ๋‹ค.
128
+
129
+ ์ œ๊ฑฐ ๊ณ„ํš์„ ๋จผ์ € ํ™•์ธํ•˜์„ธ์š”. ์ด ๋ช…๋ น์€ **์•„๋ฌด๊ฒƒ๋„ ์ง€์šฐ์ง€ ์•Š๊ณ ** ๊ณ„ํš๋งŒ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค:
130
+
131
+ ```sh
132
+ npx commitgate uninstall
133
+ ```
134
+
135
+ repo๋ฅผ ์ฝ์–ด (1) CommitGate๊ฐ€ ์„ค์น˜ํ•œ ํŒŒ์ผ ์ค‘ ํŒจํ‚ค์ง€ ์›๋ณธ๊ณผ ๋ฐ”์ดํŠธ๊ฐ€ ๋™์ผํ•œ ๊ฒƒ, (2) ํŽธ์ง‘๋ผ์„œ ์ง์ ‘ ํ™•์ธ์ด ํ•„์š”ํ•œ ๊ฒƒ, (3) ์ž๋™ ์ œ๊ฑฐํ•˜๋ฉด ์•ˆ ๋˜๋Š” ๊ฒƒ, (4) ๊ฐ์‚ฌ ์ฆ๊ฑฐ๋ฅผ ๋ถ„๋ฅ˜ํ•ด ๋ณด์—ฌ์ฃผ๊ณ , ์ปค๋ฐ‹ ์—ฌ๋ถ€์— ๋งž๋Š” ๋˜๋Œ๋ฆฌ๊ธฐ ๋ช…๋ น์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ์‚ญ์ œ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๊ฒ€ํ† ํ•œ ๋’ค ์ง์ ‘ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
136
+
137
+ ### ์™œ ์ž๋™์œผ๋กœ ์ง€์›Œ์ฃผ์ง€ ์•Š๋‚˜์š”?
138
+
139
+ `init`์€ **๋ฌด์—‡์„ ์ƒˆ๋กœ ๋งŒ๋“ค์—ˆ๋Š”์ง€ ๋””์Šคํฌ์— ๊ธฐ๋กํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.** ๊ทธ๋ž˜์„œ ์ œ๊ฑฐ ์‹œ์ ์—๋Š” ์•„๋ž˜๋ฅผ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
140
+
141
+ - `AGENTS.md`๋Š” **์—†์„ ๋•Œ๋งŒ** ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฏธ ์žˆ์—ˆ๋‹ค๋ฉด ๊ทธ๋Œ€๋กœ ๋‘๋ฏ€๋กœ, init์ด ๋งŒ๋“  ํŒŒ์ผ๊ณผ ์‚ฌ์šฉ์ž๊ฐ€ ์“ด ํŒŒ์ผ์ด ๋””์Šคํฌ์ƒ ๊ฐ™์•„ ๋ณด์ž…๋‹ˆ๋‹ค.
142
+ - `req.config.json`์€ ์ด๋ฏธ ์žˆ์œผ๋ฉด **๋ˆ„๋ฝ๋œ ํ‚ค๋งŒ ๋ณ‘ํ•ฉ**ํ•ฉ๋‹ˆ๋‹ค. ์›๋ณธ์„ ๋ณด๊ด€ํ•˜์ง€ ์•Š์•„ ๋ณ‘ํ•ฉ์„ ๋˜๋Œ๋ฆด ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
143
+ - `package.json`์€ **์—†๋Š” ํ‚ค๋งŒ** ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค. ์›๋ž˜ ์žˆ๋˜ `req:doctor`๋‚˜ `cross-spawn`์€ CommitGate ์†Œ์œ ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. `ajv`ยท`cross-spawn`ยท`tsx`๋Š” ๋‹ค๋ฅธ ํŒจํ‚ค์ง€๋„ ํ”ํžˆ ์“ฐ๋Š” devDependency์ž…๋‹ˆ๋‹ค.
144
+ - `ticketRoot`(๊ธฐ๋ณธ `workflow/`)์—๋Š” REQ ํ‹ฐ์ผ“์˜ `state.json`๊ณผ `approvals.jsonl` โ€” ์ด ๋„๊ตฌ์˜ **๊ฐ์‚ฌ ์ฆ๊ฑฐ** โ€” ๊ฐ€ ์Œ“์ž…๋‹ˆ๋‹ค.
145
+
146
+ ์›์žฅ์ด ์—†๋Š” ์ƒํƒœ์—์„œ ์ผ๊ด„ ์‚ญ์ œํ•˜๋ฉด ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๋ฅผ ํŒŒ๊ดดํ•ฉ๋‹ˆ๋‹ค. CommitGate๋Š” git hook์„ ์„ค์น˜ํ•˜์ง€ ์•Š๊ณ  git config๋„ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๋Š” ์ˆœ์ˆ˜ in-tree ์Šค์บํด๋”์ด๋ฏ€๋กœ, ๋˜๋Œ๋ฆฌ๊ธฐ์˜ ์ •๋ณธ์€ git์ž…๋‹ˆ๋‹ค.
147
+
148
+ ### ์•„์ง ์ปค๋ฐ‹ํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด
149
+
150
+ ```sh
151
+ git status --porcelain -uall # ๋ฌด์—‡์ด ์ถ”๊ฐ€๋๋Š”์ง€ ํ™•์ธ
152
+ git diff -- package.json # ์ฃผ์ž…๋œ req:* ์Šคํฌ๋ฆฝํŠธ์™€ devDependencies ํ™•์ธ
153
+ ```
154
+
155
+ ํ™•์ธํ•œ ๋’ค ์ง์ ‘ ๋˜๋Œ๋ฆฝ๋‹ˆ๋‹ค. `package.json`์€ ๋ฐ˜๋“œ์‹œ `HEAD` ๊ธฐ์ค€์œผ๋กœ ๋ณต์›ํ•˜์„ธ์š”.
156
+
157
+ ```sh
158
+ git checkout HEAD -- package.json
159
+ ```
160
+
161
+ > โš ๏ธ `HEAD`๋ฅผ ๋นผ๋ฉด **์ธ๋ฑ์Šค**์—์„œ ๋ณต์›๋˜์–ด, `git add` ์ดํ›„์—๋Š” ์ฃผ์ž…๋œ `req:*` ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๊ทธ๋Œ€๋กœ ๋‚จ์Šต๋‹ˆ๋‹ค.
162
+ > โš ๏ธ ์ด ๋ช…๋ น์€ `package.json`์˜ **๋‹ค๋ฅธ ๋ฏธ์ปค๋ฐ‹ ํŽธ์ง‘๋„ ํ•จ๊ป˜ ๋ฒ„๋ฆฝ๋‹ˆ๋‹ค.** ๋จผ์ € ์œ„ diff๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
163
+
164
+ ํŒŒ์ผ ์‚ญ์ œ๋Š” `npx commitgate uninstall`์ด ๋‚˜์—ดํ•ด ์ค€ ๊ฒฝ๋กœ๋งŒ ์ง€์šฐ์„ธ์š”. `scripts/req/`๋‚˜ `workflow/`๋ฅผ ๋””๋ ‰ํ„ฐ๋ฆฌ์งธ ์ง€์šฐ๋ฉด ๊ทธ ์•ˆ์˜ ์‚ฌ์šฉ์ž ํŒŒ์ผ์ด๋‚˜ ํ‹ฐ์ผ“ ์ฆ๊ฑฐ๊ฐ€ ํ•จ๊ป˜ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค.
165
+
166
+ > git์€ ๋นˆ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์ถ”์ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํŒŒ์ผ์„ ๋‹ค ์ง€์šด ๋’ค `git status`๊ฐ€ clean์ด์–ด๋„ ๋นˆ `scripts/`ยท`workflow/`๊ฐ€ ํŒŒ์ผ์‹œ์Šคํ…œ์— ๋‚จ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
167
+
168
+ ### ์ด๋ฏธ ์ปค๋ฐ‹ํ–ˆ๋‹ค๋ฉด
169
+
170
+ ์Šค์บํด๋”ฉ์„ ์ถ”๊ฐ€ํ•œ ์ปค๋ฐ‹์„ ๋˜๋Œ๋ฆฝ๋‹ˆ๋‹ค.
171
+
172
+ ```sh
173
+ git log --diff-filter=A --format='%H %s' -- scripts/req/req-new.ts
174
+ git revert <sha>
175
+ ```
176
+
177
+ `npx commitgate uninstall`์ด ๋„์ž… ์ปค๋ฐ‹ ํ›„๋ณด๋ฅผ ์ฐพ์•„ ์ค๋‹ˆ๋‹ค. ๊ทธ ์ปค๋ฐ‹์— ๋‹ค๋ฅธ ๋ณ€๊ฒฝ์ด ์„ž์—ฌ ์žˆ์œผ๋ฉด revert๊ฐ€ ๋ฌด๊ด€ํ•œ ์ž‘์—…๊นŒ์ง€ ๋˜๋Œ๋ฆฌ๋ฏ€๋กœ, ๋จผ์ € `git show <sha>`๋กœ ํ™•์ธํ•˜์„ธ์š”. ๋„์ž… ์ปค๋ฐ‹์ด ์—ฌ๋Ÿฌ ๊ฐœ๋กœ ํฉ์–ด์ ธ ์žˆ์œผ๋ฉด ๋‹จ์ผ revert๋กœ๋Š” ๋˜๋Œ๋ฆด ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
178
+
179
+ ### npx ์บ์‹œ ์ •๋ฆฌ (repo์™€ ๋ฌด๊ด€)
180
+
181
+ ์ „์—ญ ์„ค์น˜ ์—ฌ๋ถ€๋ถ€ํ„ฐ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
182
+
183
+ ```sh
184
+ npm ls -g commitgate # ๋น„์–ด ์žˆ์œผ๋ฉด ์ „์—ญ ์„ค์น˜๊ฐ€ ์•„๋‹˜
185
+ npm uninstall -g commitgate # ์ „์—ญ์œผ๋กœ ์„ค์น˜ํ–ˆ๋˜ ๊ฒฝ์šฐ์—๋งŒ
186
+ ```
187
+
188
+ npx๊ฐ€ ๋ฐ›์•„ ๋‘” ํŒจํ‚ค์ง€๋Š” npm ์บ์‹œ์˜ `_npx/` ์•„๋ž˜์— ๋‚จ์Šต๋‹ˆ๋‹ค.
189
+
190
+ ```powershell
191
+ # Windows (PowerShell)
192
+ Remove-Item -Recurse -Force "$(npm config get cache)\_npx"
193
+ ```
194
+
195
+ ```sh
196
+ # macOS / Linux
197
+ rm -rf "$(npm config get cache)/_npx"
198
+ ```
199
+
200
+ > โš ๏ธ **`npm cache clean --force`๋Š” CommitGate ์ œ๊ฑฐ ๋ช…๋ น์ด ์•„๋‹™๋‹ˆ๋‹ค.** ์ด ๋ช…๋ น์€ `_cacache`๋งŒ ๋น„์šฐ๊ณ  `_npx`๋Š” ๊ทธ๋Œ€๋กœ ๋‘ก๋‹ˆ๋‹ค. repo์˜ ์Šค์บํด๋”ฉ๊ณผ๋„ ์•„๋ฌด ๊ด€๋ จ์ด ์—†์Šต๋‹ˆ๋‹ค.
201
+
202
+ ---
203
+
204
+ ## ์ค€๋น„๋ฌผ
205
+
206
+ | ํ•„์š” | ํ™•์ธ ๋ช…๋ น | ๋น„๊ณ  |
207
+ |---|---|---|
208
+ | Git | `git --version` | ํ•„์ˆ˜ |
209
+ | Node.js 18.17+ | `node --version` | ํ•„์ˆ˜ |
210
+ | npm, pnpm, yarn ์ค‘ ํ•˜๋‚˜ | `npm --version` | npm ๊ธฐ์ค€์œผ๋กœ ์•ˆ๋‚ด |
211
+ | Codex CLI | `codex --version` | ๋ฆฌ๋ทฐ ์‹คํ–‰์— ํ•„์š” |
212
+
213
+ Codex CLI๊ฐ€ ์—†๋‹ค๋ฉด:
214
+
215
+ ```sh
216
+ npm install -g @openai/codex
217
+ codex login
218
+ codex login status
219
+ ```
220
+
221
+ Windows์—์„œ ์„ค์น˜ ์งํ›„ `codex` ๋ช…๋ น์„ ๋ชป ์ฐพ์œผ๋ฉด ์ƒˆ ํ„ฐ๋ฏธ๋„์„ ์—ด์–ด PATH๋ฅผ ๋‹ค์‹œ ์ฝ๊ฒŒ ํ•˜์„ธ์š”.
222
+
223
+ ---
224
+
225
+ ## ์ˆ˜๋™ ๋ช…๋ น
226
+
227
+ ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ์ž๋Š” ์œ„ ํ”„๋กฌํ”„ํŠธ ๋ฐฉ์‹์œผ๋กœ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” ๋‚ด๋ถ€์—์„œ ์–ด๋–ค ๋ช…๋ น์ด ์‹คํ–‰๋˜๋Š”์ง€ ์ดํ•ดํ•˜๊ฑฐ๋‚˜ ์ง์ ‘ ๋””๋ฒ„๊น…ํ•  ๋•Œ๋งŒ ๋ณด๋ฉด ๋ฉ๋‹ˆ๋‹ค.
228
+
229
+ ```sh
230
+ # 1. ํ‹ฐ์ผ“๊ณผ ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ
231
+ npm run req:new -- my-feature --run
232
+
233
+ # 2. ์„ค๊ณ„ ๋ฌธ์„œ ์ž‘์„ฑ ํ›„ stage
234
+ git add workflow/REQ-2026-001/00-requirement.md workflow/REQ-2026-001/01-design.md workflow/REQ-2026-001/02-plan.md
235
+
236
+ # 3. ์„ค๊ณ„ ๋ฆฌ๋ทฐ
237
+ npm run req:review-codex -- 2026-001 --kind design --run
238
+
239
+ # 4. ์ฝ”๋“œ ๊ตฌํ˜„ ํ›„ stage
240
+ git add <changed-source-files>
241
+
242
+ # 5. ๊ฒŒ์ดํŠธ ์ ๊ฒ€
243
+ npm run req:doctor -- 2026-001
244
+
245
+ # 6. ๊ตฌํ˜„ ๋ฆฌ๋ทฐ
246
+ npm run req:review-codex -- 2026-001 --kind phase --run
247
+
248
+ # 7. ์Šน์ธ๋œ ์ฝ”๋“œ ์ปค๋ฐ‹
249
+ npm run req:commit -- 2026-001 --run -m "feat: my feature"
250
+ ```
251
+
252
+ ์ค‘์š”: source ์ปค๋ฐ‹์—๋Š” ๋‚ด๊ฐ€ ๋งŒ๋“  ์ฝ”๋“œ์™€ ๋ฌธ์„œ๋งŒ stageํ•˜์„ธ์š”. `state.json`๊ณผ `responses/`๋Š” ๋„๊ตฌ๊ฐ€ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
253
+
254
+ ์—ฌ๋Ÿฌ ์ค„ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€๋Š” `-m` ๋Œ€์‹  ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜์„ธ์š”.
255
+
256
+ ```sh
257
+ npm run req:commit -- 2026-001 --run --message-file commit-message.txt
258
+ ```
259
+
260
+ ---
261
+
262
+ ## ๋ช…๋ น์–ด ์š”์•ฝ
263
+
264
+ | ๋ช…๋ น | ์šฉ๋„ |
265
+ |---|---|
266
+ | `npx commitgate` | ํ”„๋กœ์ ํŠธ์— CommitGate ์„ค์น˜ |
267
+ | `npx commitgate --dry-run` | ํŒŒ์ผ์„ ์“ฐ์ง€ ์•Š๊ณ  ์„ค์น˜ ๊ณ„ํš ํ™•์ธ |
268
+ | `npx commitgate --strict` | ๋‚ฎ์€ `cross-spawn` ๋ฒ„์ „ ๊ฒฝ๊ณ ๋ฅผ ์„ค์น˜ ์‹คํŒจ๋กœ ์ฒ˜๋ฆฌ |
269
+ | `npx commitgate uninstall` | ์ œ๊ฑฐ ๊ณ„ํš ํ™•์ธ (์ฝ๊ธฐ ์ „์šฉ โ€” ์•„๋ฌด๊ฒƒ๋„ ์ง€์šฐ์ง€ ์•Š์Œ) |
270
+ | `req:new <slug> --run` | REQ ํ‹ฐ์ผ“, ๋ธŒ๋žœ์น˜, ์„ค๊ณ„๋ฌธ์„œ ์ƒ์„ฑ |
271
+ | `req:review-codex <id> --kind design --run` | ์„ค๊ณ„ ๋ฆฌ๋ทฐ |
272
+ | `req:review-codex <id> --kind phase --run` | ๊ตฌํ˜„ ๋ฆฌ๋ทฐ |
273
+ | `req:doctor <id>` | ๊ฒŒ์ดํŠธ ์ƒํƒœ ํ™•์ธ |
274
+ | `req:commit <id> --run -m "message"` | ์Šน์ธ๋œ ๋ณ€๊ฒฝ ์ปค๋ฐ‹ |
275
+
276
+ ---
277
+
278
+ ## ์„ค์ •
279
+
280
+ ๋Œ€๋ถ€๋ถ„์€ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ํ•„์š”ํ•˜๋ฉด ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์˜ `req.config.json`์„ ์ˆ˜์ •ํ•˜์„ธ์š”.
281
+
282
+ | ํ•ญ๋ชฉ | ๊ธฐ๋ณธ๊ฐ’ | ์„ค๋ช… |
283
+ |---|---|---|
284
+ | `branchPrefix` | `"feat/req-"` | ์ƒˆ ๋ธŒ๋žœ์น˜ prefix |
285
+ | `ticketRoot` | `"workflow"` | REQ ํ‹ฐ์ผ“ ํด๋” |
286
+ | `packageManager` | ์ž๋™ ๊ฐ์ง€ | `npm`, `pnpm`, `yarn` |
287
+ | `designDocs` | `00/01/02` ๋ฌธ์„œ | ์„ค๊ณ„ ๋ฌธ์„œ ํŒŒ์ผ๋ช… |
288
+
289
+ ๋นˆ `branchPrefix`๋‚˜ ํ”„๋กœ์ ํŠธ ๋ฐ–์œผ๋กœ ๋‚˜๊ฐ€๋Š” ๊ฒฝ๋กœ๋Š” ๊ฑฐ๋ถ€๋ฉ๋‹ˆ๋‹ค.
290
+
291
+ ---
292
+
293
+ ## FAQ
294
+
295
+ **Codex CLI๊ฐ€ ์—†์œผ๋ฉด ์–ด๋–ป๊ฒŒ ๋˜๋‚˜์š”?**
296
+ ๋ฆฌ๋ทฐ ๋ช…๋ น์ด ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. ์กฐ์šฉํžˆ ์Šน์ธ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
297
+
298
+ **์Šน์ธ ํ›„ ์ฝ”๋“œ๋ฅผ ์กฐ๊ธˆ ๊ณ ์น˜๋ฉด ์ปค๋ฐ‹๋˜๋‚˜์š”?**
299
+ ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ์Šน์ธ๋œ staged tree์™€ ๋‹ฌ๋ผ์ง€๋ฉด stale ์Šน์ธ์œผ๋กœ ๋ณด๊ณ  ๋‹ค์‹œ ๋ฆฌ๋ทฐ๋ฅผ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค.
300
+
301
+ **`state.json`์ด๋‚˜ `responses/`๋Š” ์™œ stageํ•˜๋ฉด ์•ˆ ๋˜๋‚˜์š”?**
302
+ ์›Œํฌํ”Œ๋กœ ์ฆ๊ฑฐ์™€ ์ƒํƒœ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค. source ์ปค๋ฐ‹์— ์„ž์ด๋ฉด ์Šน์ธ ๋ฐ”์ธ๋”ฉ์ด ํ๋ ค์ง€๋ฏ€๋กœ `req:commit`์ด ๋ง‰์Šต๋‹ˆ๋‹ค.
303
+
304
+ **cross-spawn ๋ฒ„์ „ ๊ฒฝ๊ณ ๊ฐ€ ๋‚˜์˜ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•˜๋‚˜์š”?**
305
+ ๋Œ€์ƒ ํ”„๋กœ์ ํŠธ์˜ ๊ธฐ์กด `cross-spawn`์ด CommitGate๊ฐ€ ๊ฒ€์ฆํ•œ ํ•˜ํ•œ๋ณด๋‹ค ๋‚ฎ์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค. `npm i -D cross-spawn@^7.0.6`์œผ๋กœ ์˜ฌ๋ฆฌ์„ธ์š”. CI๋‚˜ ๋ณด์•ˆ ๋ฏผ๊ฐ ํ™˜๊ฒฝ์—์„œ๋Š” `npx commitgate --strict`๋ฅผ ์‚ฌ์šฉํ•ด ๊ฒฝ๊ณ ๋ฅผ ์‹คํŒจ๋กœ ๋‹ค๋ฃจ์„ธ์š”.
306
+
307
+ **๋‘ ๋ฒˆ ์„ค์น˜ํ•˜๋ฉด ๋ฎ์–ด์“ฐ๋‚˜์š”?**
308
+ ์•„๋‹ˆ์š”. ๊ธฐ์กด ํŒŒ์ผ์€ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค. ๊ฐ•์ œ๋กœ ๊ฐฑ์‹ ํ•˜๋ ค๋ฉด `--force`๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.
309
+
310
+ ---
311
+
312
+ ## ํ˜„์žฌ ๋ฒ”์œ„
313
+
314
+ ํ˜„์žฌ ๋ฒ„์ „์€ **Stage A: vendored scaffold ๋ชจ๋ธ**์ž…๋‹ˆ๋‹ค. ์ฆ‰ `npx commitgate`๊ฐ€ ๋Œ€์ƒ ํ”„๋กœ์ ํŠธ์— ์›Œํฌํ”Œ๋กœ ํŒŒ์ผ์„ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.
315
+
316
+ ํ˜„์žฌ ์šด์˜ ์ค‘์ธ ๊ฒ€์ฆ์ž…๋‹ˆ๋‹ค.
317
+
318
+ - GitHub Actions์—์„œ `ubuntu-latest`, `macos-latest`, `windows-latest` ร— Node 18/20/22 ๋งคํŠธ๋ฆญ์Šค๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
319
+ - `npm run smoke`๋Š” pack tarball ์„ค์น˜๋ณธ์˜ `commitgate` bin์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
320
+ - Windows `.cmd` ๋ž˜ํผ ์ฃผ์ž… ํšŒ๊ท€ ํ…Œ์ŠคํŠธ๊ฐ€ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €์™€ Codex wrapper ๊ฒฝ๋กœ๋ฅผ ๋ณดํ˜ธํ•ฉ๋‹ˆ๋‹ค.
321
+
322
+ ์•„๋ž˜๋Š” ํ›„์† ๋ฒ”์œ„์ž…๋‹ˆ๋‹ค.
323
+
324
+ - `node_modules`์—์„œ ์ง์ ‘ ์‹คํ–‰ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ชจ๋ธ
325
+ - ๋น„-git VCS ์ง€์›
326
+ - ๋” ๋‹ค์–‘ํ•œ ์„ค๊ณ„๋ฌธ์„œ ํ…œํ”Œ๋ฆฟ
327
+
328
+ ---
329
+
330
+ ## License
331
+
332
+ [MIT](./LICENSE) ยฉ 2026 sol5288
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
3
  * commitgate bin ๋Ÿฐ์ฒ˜(Stage A).
4
- * npm bin์€ TS๋ฅผ ์ง์ ‘ ์‹คํ–‰ ๋ชป ํ•˜๋ฏ€๋กœ tsx ESM ๋กœ๋”๋ฅผ ์–น์–ด init.ts๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.
4
+ * npm bin์€ TS๋ฅผ ์ง์ ‘ ์‹คํ–‰ ๋ชป ํ•˜๋ฏ€๋กœ tsx ESM ๋กœ๋”๋ฅผ ์–น์–ด init.ts/uninstall.ts๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.
5
5
  *
6
6
  * โš ๏ธ tsx๋Š” ๋ฐ˜๋“œ์‹œ **์ด ๋Ÿฐ์ฒ˜(=ํŒจํ‚ค์ง€) ๊ธฐ์ค€**์œผ๋กœ ํ•ด์†Œํ•ด์•ผ ํ•œ๋‹ค(ํ˜ธ์ถœ cwd ์•„๋‹˜).
7
7
  * npx๋กœ ์‹คํ–‰ํ•˜๋ฉด cwd=๋Œ€์ƒ repo์ธ๋ฐ ๊ทธ๊ณณ์—” ์•„์ง tsx๊ฐ€ ์—†์„ ์ˆ˜ ์žˆ์–ด,
@@ -9,6 +9,9 @@
9
9
  * `import ... from 'tsx/esm/api'`๋Š” ์ด .mjs(ํŒจํ‚ค์ง€ node_modules) ๊ธฐ์ค€์œผ๋กœ ์ •์  ํ•ด์†Œ๋˜๋ฏ€๋กœ cwd ๋ฌด๊ด€.
10
10
  * (node:module์˜ register('tsx/esm')๋Š” tsx v4๊ฐ€ deprecated --loader๋กœ ๊ฐ„์ฃผํ•ด ๊ฑฐ๋ถ€ โ†’ tsx ์ž์ฒด API ์‚ฌ์šฉ.)
11
11
  * (Stage B์—์„œ init.ts๋ฅผ JS๋กœ ๋นŒ๋“œํ•˜๋ฉด ์ด ๋Ÿฐ์ฒ˜๋Š” ์ œ๊ฑฐ ๊ฐ€๋Šฅ.)
12
+ *
13
+ * verb dispatch(REQ-2026-007): `uninstall`๋งŒ ๋ณ„๋„ ๋ชจ๋“ˆ๋กœ ๋ณด๋‚ธ๋‹ค. verb ์—†๋Š” ํ˜ธ์ถœ์€ **ํ˜„ํ–‰ ๊ทธ๋Œ€๋กœ init**(ํ•˜์œ„ํ˜ธํ™˜).
14
+ * dispatch๋ฅผ ์—ฌ๊ธฐ(๋‹จ์ผ bin ์ง„์ž…์ )์— ๋‘๋ฉด uninstall.ts โ†’ init.ts ๋‹จ๋ฐฉํ–ฅ import๊ฐ€ ๋˜์–ด ์ˆœํ™˜์ด ์ƒ๊ธฐ์ง€ ์•Š๋Š”๋‹ค.
12
15
  */
13
16
  import { register } from 'tsx/esm/api'
14
17
  import { fileURLToPath, pathToFileURL } from 'node:url'
@@ -16,6 +19,11 @@ import { dirname, join } from 'node:path'
16
19
 
17
20
  register()
18
21
 
19
- const initTs = pathToFileURL(join(dirname(fileURLToPath(import.meta.url)), 'init.ts')).href
20
- const mod = await import(initTs)
21
- mod.main(process.argv.slice(2))
22
+ const binDir = dirname(fileURLToPath(import.meta.url))
23
+ const argv = process.argv.slice(2)
24
+ const entry = argv[0] === 'uninstall' ? 'uninstall.ts' : 'init.ts'
25
+ const rest = argv[0] === 'uninstall' ? argv.slice(1) : argv
26
+
27
+ const mod = await import(pathToFileURL(join(binDir, entry)).href)
28
+ // runCli = ์˜ˆ์™ธ๋ฅผ ์นœ์ ˆํ•œ ํ•œ ์ค„ ๋ฉ”์‹œ์ง€ + exit 1๋กœ ๋ณ€ํ™˜ํ•˜๋Š” CLI ๊ฒฝ๊ณ„(์ŠคํƒํŠธ๋ ˆ์ด์Šค ๋…ธ์ถœ ๋ฐฉ์ง€).
29
+ mod.runCli(rest)