commitgate 0.2.0 โ†’ 0.2.2

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,217 +1,246 @@
1
- # CommitGate
2
-
3
- ๐ŸŒ **ํ•œ๊ตญ์–ด** ยท [English](./README.en.md)
4
-
5
- **AI ์ฝ”๋”ฉ ๋ณ€๊ฒฝ์„ Codex ๋ฆฌ๋ทฐ ์Šน์ธ ์—†์ด๋Š” ์ปค๋ฐ‹ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ๋ง‰๋Š” ์ปค๋ฐ‹ ๊ฒŒ์ดํŠธ์ž…๋‹ˆ๋‹ค.**
6
-
7
- AI ์—์ด์ „ํŠธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ๋น ๋ฅด๊ฒŒ ๋งŒ๋“ค๋”๋ผ๋„, ๋ฆฌ๋ทฐ ์—†์ด ๋ฐ”๋กœ ์ปค๋ฐ‹๋˜๋ฉด ์œ„ํ—˜ํ•ฉ๋‹ˆ๋‹ค. CommitGate๋Š” ๋ณ€๊ฒฝ์„ ํ‹ฐ์ผ“ ๋‹จ์œ„๋กœ ๋ฌถ๊ณ , Codex๊ฐ€ ์Šน์ธํ•œ staged tree๋งŒ ์ปค๋ฐ‹๋˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ์Šน์ธ ํ›„ ์ฝ”๋“œ๊ฐ€ ๋ฐ”๋€Œ๊ฑฐ๋‚˜ ์ฆ๊ฑฐ๊ฐ€ ๋ถ€์กฑํ•˜๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ง‰์Šต๋‹ˆ๋‹ค.
8
-
9
- [![license](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
10
-
11
- ---
12
-
13
- ## Quick Start
14
-
15
- ์•„๋ž˜๋Š” ๊ฐ€์žฅ ์งง์€ ์‚ฌ์šฉ ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ๋Š” **git ์ €์žฅ์†Œ์ด๊ณ  `package.json`์ด ์žˆ๋Š” ํด๋”**์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
16
-
17
- ```sh
18
- npx commitgate
19
- npm install
20
- codex --version
21
- codex login status
22
- ```
23
-
24
- ๊ทธ๋‹ค์Œ AI ์ฝ”๋”ฉ ์—์ด์ „ํŠธ์—๊ฒŒ ์•„๋ž˜ ํ”„๋กฌํ”„ํŠธ๋ฅผ ๋ถ™์—ฌ๋„ฃ์Šต๋‹ˆ๋‹ค.
25
-
26
- ```text
27
- ์ด ์š”์ฒญ์€ ์ผ๋ฐ˜ ๊ตฌํ˜„์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์ง€ ๋ง๊ณ , ์ด ํ”„๋กœ์ ํŠธ์— ์„ค์น˜๋œ CommitGate๋ฅผ ์‚ฌ์šฉํ•ด๋ผ.
28
-
29
- ์ƒˆ REQ ํ‹ฐ์ผ“์„ ๋งŒ๋“ค๊ณ  ๋‹ค์Œ ํ๋ฆ„์„ ๋๊นŒ์ง€ ์ง„ํ–‰ํ•ด๋ผ:
30
- req:new โ†’ ์„ค๊ณ„๋ฌธ์„œ ์ž‘์„ฑ โ†’ Codex design ๋ฆฌ๋ทฐ โ†’ ๊ตฌํ˜„ยทํ…Œ์ŠคํŠธ โ†’ req:doctor โ†’ Codex phase ๋ฆฌ๋ทฐ โ†’ req:commit
31
-
32
- ์ž๋™์œผ๋กœ ์ง„ํ–‰ํ•  ๊ฒƒ:
33
- - NEEDS_FIX๊ฐ€ ๋‚˜์˜ค๋ฉด ์ˆ˜์ •ํ•˜๊ณ  ์žฌ๋ฆฌ๋ทฐํ•ด ์Šน์ธ๊นŒ์ง€ ๋ฐ˜๋ณตํ•œ๋‹ค.
34
- - ๋ฆฌ๋ทฐ ๋Œ€์ƒ์€ git add ํ•œ ํŒŒ์ผ๋งŒ์ด๋‹ค.
35
- - `state.json`๊ณผ `responses/`๋Š” ์ง์ ‘ `git add`ํ•˜์ง€ ์•Š๋Š”๋‹ค.
36
-
37
- ๋ฉˆ์ถฐ์„œ ํ™•์ธ๋ฐ›์„ ๋•Œ:
38
- - req:commit --run ์ง์ „
39
- - main ๋ณ‘ํ•ฉ ๋˜๋Š” push ์ง์ „
40
- - reset, clean, force push ๊ฐ™์€ destructive ์ž‘์—… ์ „
41
- - ์š”๊ตฌ์‚ฌํ•ญ ๋ฒ”์œ„๋ฅผ ๋ฐ”๊ฟ”์•ผ ํ•  ๋•Œ
42
- - Codex ๋ฆฌ๋ทฐ๊ฐ€ 3๋ผ์šด๋“œ๋ฅผ ๋„˜์–ด๋„ ์Šน์ธ๋˜์ง€ ์•Š์„ ๋•Œ
43
-
44
- ์š”๊ตฌ์‚ฌํ•ญ:
45
- - ๋ฌด์—‡์„:
46
- - ์™œ:
47
- - ์ œ์•ฝ:
48
- - ์™„๋ฃŒ ๊ธฐ์ค€:
49
- ```
50
-
51
- ์ฒซ ์‘๋‹ต์€ ๋ณดํ†ต ์ด๋ ‡๊ฒŒ ๋‚˜์™€์•ผ ํ•ฉ๋‹ˆ๋‹ค.
52
-
53
- ```text
54
- REQ-2026-002 ๋ฐœํ–‰
55
- ๋ธŒ๋žœ์น˜: feat/req-2026-002-profile-edit-api
56
- phase:
57
- - phase-1: PATCH /profile ๊ตฌํ˜„
58
- - phase-2: ํ…Œ์ŠคํŠธ์™€ ํšŒ๊ท€ ํ™•์ธ
59
- ํ†ต์ œ์ : req:commit --run ์ง์ „, push ์ง์ „
60
- ```
61
-
62
- ์ดํ›„์—๋Š” ์—์ด์ „ํŠธ๊ฐ€ ์„ค๊ณ„, ๊ตฌํ˜„, ํ…Œ์ŠคํŠธ, Codex ๋ฆฌ๋ทฐ๋ฅผ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์ปค๋ฐ‹์ด๋‚˜ push ๊ฐ™์€ ํ†ต์ œ์ ์—์„œ๋งŒ ํ™•์ธํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
63
-
64
- ---
65
-
66
- ## ๋ฌด์—‡์„ ๋ณด์žฅํ•˜๋‚˜์š”?
67
-
68
- CommitGate๊ฐ€ ๋ง‰๋Š” ๊ฒƒ์€ ๋‹จ์ˆœํ•œ ๋ช…๋ น ์‹ค์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ **๋ฆฌ๋ทฐ๋ฐ›์ง€ ์•Š์€ ๋ณ€๊ฒฝ์ด ์ปค๋ฐ‹๋˜๋Š” ์ƒํ™ฉ**์ž…๋‹ˆ๋‹ค.
69
-
70
- - Codex ๋ฆฌ๋ทฐ๊ฐ€ ์‹คํŒจํ•˜๊ฑฐ๋‚˜ ์—†์œผ๋ฉด ์ปค๋ฐ‹ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
71
- - ์Šน์ธ๋œ staged tree์™€ ์ง€๊ธˆ ์ปค๋ฐ‹ํ•˜๋ ค๋Š” staged tree๊ฐ€ ๋‹ค๋ฅด๋ฉด ๋ง‰์Šต๋‹ˆ๋‹ค.
72
- - `state.json`, `responses/` ๊ฐ™์€ ์›Œํฌํ”Œ๋กœ ๋‚ด๋ถ€ ํŒŒ์ผ์„ source ์ปค๋ฐ‹์— ์„ž์œผ๋ฉด ๋ง‰์Šต๋‹ˆ๋‹ค.
73
- - Codex CLI๊ฐ€ ์—†๊ฑฐ๋‚˜ ์‹คํ–‰์— ์‹คํŒจํ•˜๋ฉด ์กฐ์šฉํžˆ ํ†ต๊ณผํ•˜์ง€ ์•Š๊ณ  ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.
74
- - ์Šน์ธ ์‘๋‹ต๊ณผ ์ฆ๊ฑฐ ํŒŒ์ผ์€ `workflow/REQ-.../responses/`์— ๋‚จ์Šต๋‹ˆ๋‹ค.
75
-
76
- ํ•œ ์ค„๋กœ ๋งํ•˜๋ฉด, **ํ™•์‹คํžˆ ์Šน์ธ๋œ ๋ณ€๊ฒฝ๋งŒ ํ†ต๊ณผํ•˜๊ณ  ์• ๋งคํ•˜๋ฉด ๋ฉˆ์ถ”๋Š” ๋ฐฉ์‹**์ž…๋‹ˆ๋‹ค.
77
-
78
- ---
79
-
80
- ## ์„ค์น˜๊ฐ€ ํ•˜๋Š” ์ผ
81
-
82
- `npx commitgate`๋Š” ๋Œ€์ƒ ํ”„๋กœ์ ํŠธ์— ์•„๋ž˜ ํŒŒ์ผ๊ณผ ์„ค์ •์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด ํŒŒ์ผ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฎ์–ด์“ฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
83
-
84
- | ์ถ”๊ฐ€ ํ•ญ๋ชฉ | ์„ค๋ช… |
85
- |---|---|
86
- | `scripts/req/` | `req:new`, `req:review-codex`, `req:doctor`, `req:commit` ์Šคํฌ๋ฆฝํŠธ |
87
- | `workflow/*.schema.json` | Codex ์‘๋‹ต๊ณผ ์„ค์ • ๊ฒ€์ฆ ์Šคํ‚ค๋งˆ |
88
- | `req.config.json` | ํ”„๋กœ์ ํŠธ๋ณ„ ์„ค์ • |
89
- | `AGENTS.md` | ์—์ด์ „ํŠธ์™€ Reviewer๊ฐ€ ์ฝ๋Š” ๊ทœ์น™ ํ…œํ”Œ๋ฆฟ |
90
- | `package.json` ์Šคํฌ๋ฆฝํŠธ | `req:*` ๋ช…๋ น๊ณผ ํ•„์š”ํ•œ devDependencies |
91
-
92
- ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋งŒ ํ•˜๋ ค๋ฉด:
93
-
94
- ```sh
95
- npx commitgate --dry-run
96
- ```
97
-
98
- ---
99
-
100
- ## ์ค€๋น„๋ฌผ
101
-
102
- | ํ•„์š” | ํ™•์ธ ๋ช…๋ น | ๋น„๊ณ  |
103
- |---|---|---|
104
- | Git | `git --version` | ํ•„์ˆ˜ |
105
- | Node.js 18.17+ | `node --version` | ํ•„์ˆ˜ |
106
- | npm, pnpm, yarn ์ค‘ ํ•˜๋‚˜ | `npm --version` | npm ๊ธฐ์ค€์œผ๋กœ ์•ˆ๋‚ด |
107
- | Codex CLI | `codex --version` | ๋ฆฌ๋ทฐ ์‹คํ–‰์— ํ•„์š” |
108
-
109
- Codex CLI๊ฐ€ ์—†๋‹ค๋ฉด:
110
-
111
- ```sh
112
- npm install -g @openai/codex
113
- codex login
114
- codex login status
115
- ```
116
-
117
- Windows์—์„œ ์„ค์น˜ ์งํ›„ `codex` ๋ช…๋ น์„ ๋ชป ์ฐพ์œผ๋ฉด ์ƒˆ ํ„ฐ๋ฏธ๋„์„ ์—ด์–ด PATH๋ฅผ ๋‹ค์‹œ ์ฝ๊ฒŒ ํ•˜์„ธ์š”.
118
-
119
- ---
120
-
121
- ## ์ˆ˜๋™ ๋ช…๋ น
122
-
123
- ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ์ž๋Š” ์œ„ ํ”„๋กฌํ”„ํŠธ ๋ฐฉ์‹์œผ๋กœ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” ๋‚ด๋ถ€์—์„œ ์–ด๋–ค ๋ช…๋ น์ด ์‹คํ–‰๋˜๋Š”์ง€ ์ดํ•ดํ•˜๊ฑฐ๋‚˜ ์ง์ ‘ ๋””๋ฒ„๊น…ํ•  ๋•Œ๋งŒ ๋ณด๋ฉด ๋ฉ๋‹ˆ๋‹ค.
124
-
125
- ```sh
126
- # 1. ํ‹ฐ์ผ“๊ณผ ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ
127
- npm run req:new -- my-feature --run
128
-
129
- # 2. ์„ค๊ณ„ ๋ฌธ์„œ ์ž‘์„ฑ ํ›„ stage
130
- git add workflow/REQ-2026-001/00-requirement.md workflow/REQ-2026-001/01-design.md workflow/REQ-2026-001/02-plan.md
131
-
132
- # 3. ์„ค๊ณ„ ๋ฆฌ๋ทฐ
133
- npm run req:review-codex -- 2026-001 --kind design --run
134
-
135
- # 4. ์ฝ”๋“œ ๊ตฌํ˜„ ํ›„ stage
136
- git add <changed-source-files>
137
-
138
- # 5. ๊ฒŒ์ดํŠธ ์ ๊ฒ€
139
- npm run req:doctor -- 2026-001
140
-
141
- # 6. ๊ตฌํ˜„ ๋ฆฌ๋ทฐ
142
- npm run req:review-codex -- 2026-001 --kind phase --run
143
-
144
- # 7. ์Šน์ธ๋œ ์ฝ”๋“œ ์ปค๋ฐ‹
145
- npm run req:commit -- 2026-001 --run -m "feat: my feature"
146
- ```
147
-
148
- ์ค‘์š”: source ์ปค๋ฐ‹์—๋Š” ๋‚ด๊ฐ€ ๋งŒ๋“  ์ฝ”๋“œ์™€ ๋ฌธ์„œ๋งŒ stageํ•˜์„ธ์š”. `state.json`๊ณผ `responses/`๋Š” ๋„๊ตฌ๊ฐ€ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
149
-
150
- ์—ฌ๋Ÿฌ ์ค„ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€๋Š” `-m` ๋Œ€์‹  ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜์„ธ์š”.
151
-
152
- ```sh
153
- npm run req:commit -- 2026-001 --run --message-file commit-message.txt
154
- ```
155
-
156
- ---
157
-
158
- ## ๋ช…๋ น์–ด ์š”์•ฝ
159
-
160
- | ๋ช…๋ น | ์šฉ๋„ |
161
- |---|---|
162
- | `npx commitgate` | ํ”„๋กœ์ ํŠธ์— CommitGate ์„ค์น˜ |
163
- | `req:new <slug> --run` | REQ ํ‹ฐ์ผ“, ๋ธŒ๋žœ์น˜, ์„ค๊ณ„๋ฌธ์„œ ์ƒ์„ฑ |
164
- | `req:review-codex <id> --kind design --run` | ์„ค๊ณ„ ๋ฆฌ๋ทฐ |
165
- | `req:review-codex <id> --kind phase --run` | ๊ตฌํ˜„ ๋ฆฌ๋ทฐ |
166
- | `req:doctor <id>` | ๊ฒŒ์ดํŠธ ์ƒํƒœ ํ™•์ธ |
167
- | `req:commit <id> --run -m "message"` | ์Šน์ธ๋œ ๋ณ€๊ฒฝ ์ปค๋ฐ‹ |
168
-
169
- ---
170
-
171
- ## ์„ค์ •
172
-
173
- ๋Œ€๋ถ€๋ถ„์€ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ํ•„์š”ํ•˜๋ฉด ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์˜ `req.config.json`์„ ์ˆ˜์ •ํ•˜์„ธ์š”.
174
-
175
- | ํ•ญ๋ชฉ | ๊ธฐ๋ณธ๊ฐ’ | ์„ค๋ช… |
176
- |---|---|---|
177
- | `branchPrefix` | `"feat/req-"` | ์ƒˆ ๋ธŒ๋žœ์น˜ prefix |
178
- | `ticketRoot` | `"workflow"` | REQ ํ‹ฐ์ผ“ ํด๋” |
179
- | `packageManager` | ์ž๋™ ๊ฐ์ง€ | `npm`, `pnpm`, `yarn` |
180
- | `designDocs` | `00/01/02` ๋ฌธ์„œ | ์„ค๊ณ„ ๋ฌธ์„œ ํŒŒ์ผ๋ช… |
181
-
182
- ๋นˆ `branchPrefix`๋‚˜ ํ”„๋กœ์ ํŠธ ๋ฐ–์œผ๋กœ ๋‚˜๊ฐ€๋Š” ๊ฒฝ๋กœ๋Š” ๊ฑฐ๋ถ€๋ฉ๋‹ˆ๋‹ค.
183
-
184
- ---
185
-
186
- ## FAQ
187
-
188
- **Codex CLI๊ฐ€ ์—†์œผ๋ฉด ์–ด๋–ป๊ฒŒ ๋˜๋‚˜์š”?**
189
- ๋ฆฌ๋ทฐ ๋ช…๋ น์ด ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. ์กฐ์šฉํžˆ ์Šน์ธ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
190
-
191
- **์Šน์ธ ํ›„ ์ฝ”๋“œ๋ฅผ ์กฐ๊ธˆ ๊ณ ์น˜๋ฉด ์ปค๋ฐ‹๋˜๋‚˜์š”?**
192
- ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ์Šน์ธ๋œ staged tree์™€ ๋‹ฌ๋ผ์ง€๋ฉด stale ์Šน์ธ์œผ๋กœ ๋ณด๊ณ  ๋‹ค์‹œ ๋ฆฌ๋ทฐ๋ฅผ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค.
193
-
194
- **`state.json`์ด๋‚˜ `responses/`๋Š” ์™œ stageํ•˜๋ฉด ์•ˆ ๋˜๋‚˜์š”?**
195
- ์›Œํฌํ”Œ๋กœ ์ฆ๊ฑฐ์™€ ์ƒํƒœ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค. source ์ปค๋ฐ‹์— ์„ž์ด๋ฉด ์Šน์ธ ๋ฐ”์ธ๋”ฉ์ด ํ๋ ค์ง€๋ฏ€๋กœ `req:commit`์ด ๋ง‰์Šต๋‹ˆ๋‹ค.
196
-
197
- **๋‘ ๋ฒˆ ์„ค์น˜ํ•˜๋ฉด ๋ฎ์–ด์“ฐ๋‚˜์š”?**
198
- ์•„๋‹ˆ์š”. ๊ธฐ์กด ํŒŒ์ผ์€ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค. ๊ฐ•์ œ๋กœ ๊ฐฑ์‹ ํ•˜๋ ค๋ฉด `--force`๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.
199
-
200
- ---
201
-
202
- ## ํ˜„์žฌ ๋ฒ”์œ„
203
-
204
- ํ˜„์žฌ ๋ฒ„์ „์€ **Stage A: vendored scaffold ๋ชจ๋ธ**์ž…๋‹ˆ๋‹ค. ์ฆ‰ `npx commitgate`๊ฐ€ ๋Œ€์ƒ ํ”„๋กœ์ ํŠธ์— ์›Œํฌํ”Œ๋กœ ํŒŒ์ผ์„ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.
205
-
206
- ์•„๋ž˜๋Š” ํ›„์† ๋ฒ”์œ„์ž…๋‹ˆ๋‹ค.
207
-
208
- - `node_modules`์—์„œ ์ง์ ‘ ์‹คํ–‰ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ชจ๋ธ
209
- - ๋น„-git VCS ์ง€์›
210
- - ๋” ๋‹ค์–‘ํ•œ ์„ค๊ณ„๋ฌธ์„œ ํ…œํ”Œ๋ฆฟ
211
- - Linux/macOS CI smoke ํ™•๋Œ€
212
-
213
- ---
214
-
215
- ## License
216
-
217
- [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
+ - main ๋ณ‘ํ•ฉ ๋˜๋Š” push ์ง์ „
48
+ - reset, clean, force push ๊ฐ™์€ destructive ์ž‘์—… ์ „
49
+ - ์š”๊ตฌ์‚ฌํ•ญ ๋ฒ”์œ„๋ฅผ ๋ฐ”๊ฟ”์•ผ ํ•  ๋•Œ
50
+ - Codex ๋ฆฌ๋ทฐ๊ฐ€ BLOCKED๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜ ์ œํ•œ๋œ ์žฌ์‹œ๋„ ํ›„์—๋„ ํŒ๋‹จ์ด ๋ถˆ๋ช…ํ™•ํ•  ๋•Œ
51
+
52
+ ์š”๊ตฌ์‚ฌํ•ญ:
53
+ - ๋ฌด์—‡์„:
54
+ - ์™œ:
55
+ - ์ œ์•ฝ:
56
+ - ์™„๋ฃŒ ๊ธฐ์ค€:
57
+ ```
58
+
59
+ ์ฒซ ์‘๋‹ต์€ ๋ณดํ†ต ์ด๋ ‡๊ฒŒ ๋‚˜์™€์•ผ ํ•ฉ๋‹ˆ๋‹ค.
60
+
61
+ ```text
62
+ REQ-2026-002 ๋ฐœํ–‰
63
+ ๋ธŒ๋žœ์น˜: feat/req-2026-002-profile-edit-api
64
+ phase:
65
+ - phase-1: PATCH /profile ๊ตฌํ˜„
66
+ - phase-2: ํ…Œ์ŠคํŠธ์™€ ํšŒ๊ท€ ํ™•์ธ
67
+ ํ†ต์ œ์ : req:commit --run ์ง์ „, push ์ง์ „
68
+ ```
69
+
70
+ ์ดํ›„์—๋Š” ์—์ด์ „ํŠธ๊ฐ€ ์„ค๊ณ„, ๊ตฌํ˜„, ํ…Œ์ŠคํŠธ, Codex ๋ฆฌ๋ทฐ๋ฅผ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์ปค๋ฐ‹์ด๋‚˜ push ๊ฐ™์€ ํ†ต์ œ์ ์—์„œ๋งŒ ํ™•์ธํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
71
+
72
+ ---
73
+
74
+ ## ๋ฌด์—‡์„ ๋ณด์žฅํ•˜๋‚˜์š”?
75
+
76
+ CommitGate๊ฐ€ ๋ง‰๋Š” ๊ฒƒ์€ ๋‹จ์ˆœํ•œ ๋ช…๋ น ์‹ค์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ **๋ฆฌ๋ทฐ๋ฐ›์ง€ ์•Š์€ ๋ณ€๊ฒฝ์ด ์ปค๋ฐ‹๋˜๋Š” ์ƒํ™ฉ**์ž…๋‹ˆ๋‹ค.
77
+
78
+ - Codex ๋ฆฌ๋ทฐ๊ฐ€ ์‹คํŒจํ•˜๊ฑฐ๋‚˜ ์—†์œผ๋ฉด ์ปค๋ฐ‹ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
79
+ - ์Šน์ธ๋œ staged tree์™€ ์ง€๊ธˆ ์ปค๋ฐ‹ํ•˜๋ ค๋Š” staged tree๊ฐ€ ๋‹ค๋ฅด๋ฉด ๋ง‰์Šต๋‹ˆ๋‹ค.
80
+ - `state.json`, `responses/` ๊ฐ™์€ ์›Œํฌํ”Œ๋กœ ๋‚ด๋ถ€ ํŒŒ์ผ์„ source ์ปค๋ฐ‹์— ์„ž์œผ๋ฉด ๋ง‰์Šต๋‹ˆ๋‹ค.
81
+ - Codex CLI๊ฐ€ ์—†๊ฑฐ๋‚˜ ์‹คํ–‰์— ์‹คํŒจํ•˜๋ฉด ์กฐ์šฉํžˆ ํ†ต๊ณผํ•˜์ง€ ์•Š๊ณ  ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.
82
+ - ๋ฆฌ๋ทฐ ์ข…๋ฃŒ์ฝ”๋“œ๋Š” outcome ๊ธฐ์ค€์ž…๋‹ˆ๋‹ค: `0` ์Šน์ธ, `1` ๋ฌดํšจ/fail-closed, `2` blocked(์ง€์  ์—†์Œ+๋ฏธ์Šน์ธ), `3` needs-fix.
83
+ - ์ง€์ ์€ ์—†์ง€๋งŒ ์Šน์ธ๋„ ์—†๋Š” ์‘๋‹ต์€ NEEDS_FIX๊ฐ€ ์•„๋‹ˆ๋ผ BLOCKED์ด๋ฉฐ, ์—์ด์ „ํŠธ๋Š” ๊ฐ™์€ ๋ฆฌ๋ทฐ๋ฅผ ๋ฐ˜๋ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
84
+ - ์„ค์น˜ ์‹œ ๊ธฐ์กด `cross-spawn`์ด ๊ฒ€์ฆ ํ•˜ํ•œ๋ณด๋‹ค ๋‚ฎ์œผ๋ฉด ๊ฒฝ๊ณ ํ•˜๊ณ , `--strict`์—์„œ๋Š” ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค.
85
+ - ์Šน์ธ ์‘๋‹ต๊ณผ ์ฆ๊ฑฐ ํŒŒ์ผ์€ `workflow/REQ-.../responses/`์— ๋‚จ์Šต๋‹ˆ๋‹ค.
86
+
87
+ ํ•œ ์ค„๋กœ ๋งํ•˜๋ฉด, **ํ™•์‹คํžˆ ์Šน์ธ๋œ ๋ณ€๊ฒฝ๋งŒ ํ†ต๊ณผํ•˜๊ณ  ์• ๋งคํ•˜๋ฉด ๋ฉˆ์ถ”๋Š” ๋ฐฉ์‹**์ž…๋‹ˆ๋‹ค.
88
+
89
+ ---
90
+
91
+ ## ์„ค์น˜๊ฐ€ ํ•˜๋Š” ์ผ
92
+
93
+ `npx commitgate`๋Š” ๋Œ€์ƒ ํ”„๋กœ์ ํŠธ์— ์•„๋ž˜ ํŒŒ์ผ๊ณผ ์„ค์ •์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด ํŒŒ์ผ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฎ์–ด์“ฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
94
+
95
+ | ์ถ”๊ฐ€ ํ•ญ๋ชฉ | ์„ค๋ช… |
96
+ |---|---|
97
+ | `scripts/req/` | `req:new`, `req:review-codex`, `req:doctor`, `req:commit` ์Šคํฌ๋ฆฝํŠธ |
98
+ | `workflow/*.schema.json` | Codex ์‘๋‹ต๊ณผ ์„ค์ • ๊ฒ€์ฆ ์Šคํ‚ค๋งˆ |
99
+ | `req.config.json` | ํ”„๋กœ์ ํŠธ๋ณ„ ์„ค์ • |
100
+ | `AGENTS.md` | ์—์ด์ „ํŠธ์™€ Reviewer๊ฐ€ ์ฝ๋Š” ๊ทœ์น™ ํ…œํ”Œ๋ฆฟ |
101
+ | `package.json` ์Šคํฌ๋ฆฝํŠธ | `req:*` ๋ช…๋ น๊ณผ ํ•„์š”ํ•œ devDependencies |
102
+
103
+ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋งŒ ํ•˜๋ ค๋ฉด:
104
+
105
+ ```sh
106
+ npx commitgate --dry-run
107
+ ```
108
+
109
+ ๋ณด์•ˆ ํ•˜ํ•œ ๊ฒฝ๊ณ ๋ฅผ ์„ค์น˜ ์‹คํŒจ๋กœ ์ทจ๊ธ‰ํ•˜๋ ค๋ฉด:
110
+
111
+ ```sh
112
+ npx commitgate --strict
113
+ ```
114
+
115
+ ๊ธฐ์กด `cross-spawn`์ด ๊ฒ€์ฆ ํ•˜ํ•œ๋ณด๋‹ค ๋‚ฎ์œผ๋ฉด ํŒŒ์ผ์„ ๋ณต์‚ฌํ•˜๊ธฐ ์ „์— ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค.
116
+
117
+ ---
118
+
119
+ ## ์ค€๋น„๋ฌผ
120
+
121
+ | ํ•„์š” | ํ™•์ธ ๋ช…๋ น | ๋น„๊ณ  |
122
+ |---|---|---|
123
+ | Git | `git --version` | ํ•„์ˆ˜ |
124
+ | Node.js 18.17+ | `node --version` | ํ•„์ˆ˜ |
125
+ | npm, pnpm, yarn ์ค‘ ํ•˜๋‚˜ | `npm --version` | npm ๊ธฐ์ค€์œผ๋กœ ์•ˆ๋‚ด |
126
+ | Codex CLI | `codex --version` | ๋ฆฌ๋ทฐ ์‹คํ–‰์— ํ•„์š” |
127
+
128
+ Codex CLI๊ฐ€ ์—†๋‹ค๋ฉด:
129
+
130
+ ```sh
131
+ npm install -g @openai/codex
132
+ codex login
133
+ codex login status
134
+ ```
135
+
136
+ Windows์—์„œ ์„ค์น˜ ์งํ›„ `codex` ๋ช…๋ น์„ ๋ชป ์ฐพ์œผ๋ฉด ์ƒˆ ํ„ฐ๋ฏธ๋„์„ ์—ด์–ด PATH๋ฅผ ๋‹ค์‹œ ์ฝ๊ฒŒ ํ•˜์„ธ์š”.
137
+
138
+ ---
139
+
140
+ ## ์ˆ˜๋™ ๋ช…๋ น
141
+
142
+ ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ์ž๋Š” ์œ„ ํ”„๋กฌํ”„ํŠธ ๋ฐฉ์‹์œผ๋กœ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” ๋‚ด๋ถ€์—์„œ ์–ด๋–ค ๋ช…๋ น์ด ์‹คํ–‰๋˜๋Š”์ง€ ์ดํ•ดํ•˜๊ฑฐ๋‚˜ ์ง์ ‘ ๋””๋ฒ„๊น…ํ•  ๋•Œ๋งŒ ๋ณด๋ฉด ๋ฉ๋‹ˆ๋‹ค.
143
+
144
+ ```sh
145
+ # 1. ํ‹ฐ์ผ“๊ณผ ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ
146
+ npm run req:new -- my-feature --run
147
+
148
+ # 2. ์„ค๊ณ„ ๋ฌธ์„œ ์ž‘์„ฑ ํ›„ stage
149
+ git add workflow/REQ-2026-001/00-requirement.md workflow/REQ-2026-001/01-design.md workflow/REQ-2026-001/02-plan.md
150
+
151
+ # 3. ์„ค๊ณ„ ๋ฆฌ๋ทฐ
152
+ npm run req:review-codex -- 2026-001 --kind design --run
153
+
154
+ # 4. ์ฝ”๋“œ ๊ตฌํ˜„ ํ›„ stage
155
+ git add <changed-source-files>
156
+
157
+ # 5. ๊ฒŒ์ดํŠธ ์ ๊ฒ€
158
+ npm run req:doctor -- 2026-001
159
+
160
+ # 6. ๊ตฌํ˜„ ๋ฆฌ๋ทฐ
161
+ npm run req:review-codex -- 2026-001 --kind phase --run
162
+
163
+ # 7. ์Šน์ธ๋œ ์ฝ”๋“œ ์ปค๋ฐ‹
164
+ npm run req:commit -- 2026-001 --run -m "feat: my feature"
165
+ ```
166
+
167
+ ์ค‘์š”: source ์ปค๋ฐ‹์—๋Š” ๋‚ด๊ฐ€ ๋งŒ๋“  ์ฝ”๋“œ์™€ ๋ฌธ์„œ๋งŒ stageํ•˜์„ธ์š”. `state.json`๊ณผ `responses/`๋Š” ๋„๊ตฌ๊ฐ€ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
168
+
169
+ ์—ฌ๋Ÿฌ ์ค„ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€๋Š” `-m` ๋Œ€์‹  ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜์„ธ์š”.
170
+
171
+ ```sh
172
+ npm run req:commit -- 2026-001 --run --message-file commit-message.txt
173
+ ```
174
+
175
+ ---
176
+
177
+ ## ๋ช…๋ น์–ด ์š”์•ฝ
178
+
179
+ | ๋ช…๋ น | ์šฉ๋„ |
180
+ |---|---|
181
+ | `npx commitgate` | ํ”„๋กœ์ ํŠธ์— CommitGate ์„ค์น˜ |
182
+ | `npx commitgate --dry-run` | ํŒŒ์ผ์„ ์“ฐ์ง€ ์•Š๊ณ  ์„ค์น˜ ๊ณ„ํš ํ™•์ธ |
183
+ | `npx commitgate --strict` | ๋‚ฎ์€ `cross-spawn` ๋ฒ„์ „ ๊ฒฝ๊ณ ๋ฅผ ์„ค์น˜ ์‹คํŒจ๋กœ ์ฒ˜๋ฆฌ |
184
+ | `req:new <slug> --run` | REQ ํ‹ฐ์ผ“, ๋ธŒ๋žœ์น˜, ์„ค๊ณ„๋ฌธ์„œ ์ƒ์„ฑ |
185
+ | `req:review-codex <id> --kind design --run` | ์„ค๊ณ„ ๋ฆฌ๋ทฐ |
186
+ | `req:review-codex <id> --kind phase --run` | ๊ตฌํ˜„ ๋ฆฌ๋ทฐ |
187
+ | `req:doctor <id>` | ๊ฒŒ์ดํŠธ ์ƒํƒœ ํ™•์ธ |
188
+ | `req:commit <id> --run -m "message"` | ์Šน์ธ๋œ ๋ณ€๊ฒฝ ์ปค๋ฐ‹ |
189
+
190
+ ---
191
+
192
+ ## ์„ค์ •
193
+
194
+ ๋Œ€๋ถ€๋ถ„์€ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ํ•„์š”ํ•˜๋ฉด ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์˜ `req.config.json`์„ ์ˆ˜์ •ํ•˜์„ธ์š”.
195
+
196
+ | ํ•ญ๋ชฉ | ๊ธฐ๋ณธ๊ฐ’ | ์„ค๋ช… |
197
+ |---|---|---|
198
+ | `branchPrefix` | `"feat/req-"` | ์ƒˆ ๋ธŒ๋žœ์น˜ prefix |
199
+ | `ticketRoot` | `"workflow"` | REQ ํ‹ฐ์ผ“ ํด๋” |
200
+ | `packageManager` | ์ž๋™ ๊ฐ์ง€ | `npm`, `pnpm`, `yarn` |
201
+ | `designDocs` | `00/01/02` ๋ฌธ์„œ | ์„ค๊ณ„ ๋ฌธ์„œ ํŒŒ์ผ๋ช… |
202
+
203
+ ๋นˆ `branchPrefix`๋‚˜ ํ”„๋กœ์ ํŠธ ๋ฐ–์œผ๋กœ ๋‚˜๊ฐ€๋Š” ๊ฒฝ๋กœ๋Š” ๊ฑฐ๋ถ€๋ฉ๋‹ˆ๋‹ค.
204
+
205
+ ---
206
+
207
+ ## FAQ
208
+
209
+ **Codex CLI๊ฐ€ ์—†์œผ๋ฉด ์–ด๋–ป๊ฒŒ ๋˜๋‚˜์š”?**
210
+ ๋ฆฌ๋ทฐ ๋ช…๋ น์ด ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. ์กฐ์šฉํžˆ ์Šน์ธ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
211
+
212
+ **์Šน์ธ ํ›„ ์ฝ”๋“œ๋ฅผ ์กฐ๊ธˆ ๊ณ ์น˜๋ฉด ์ปค๋ฐ‹๋˜๋‚˜์š”?**
213
+ ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ์Šน์ธ๋œ staged tree์™€ ๋‹ฌ๋ผ์ง€๋ฉด stale ์Šน์ธ์œผ๋กœ ๋ณด๊ณ  ๋‹ค์‹œ ๋ฆฌ๋ทฐ๋ฅผ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค.
214
+
215
+ **`state.json`์ด๋‚˜ `responses/`๋Š” ์™œ stageํ•˜๋ฉด ์•ˆ ๋˜๋‚˜์š”?**
216
+ ์›Œํฌํ”Œ๋กœ ์ฆ๊ฑฐ์™€ ์ƒํƒœ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค. source ์ปค๋ฐ‹์— ์„ž์ด๋ฉด ์Šน์ธ ๋ฐ”์ธ๋”ฉ์ด ํ๋ ค์ง€๋ฏ€๋กœ `req:commit`์ด ๋ง‰์Šต๋‹ˆ๋‹ค.
217
+
218
+ **cross-spawn ๋ฒ„์ „ ๊ฒฝ๊ณ ๊ฐ€ ๋‚˜์˜ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•˜๋‚˜์š”?**
219
+ ๋Œ€์ƒ ํ”„๋กœ์ ํŠธ์˜ ๊ธฐ์กด `cross-spawn`์ด CommitGate๊ฐ€ ๊ฒ€์ฆํ•œ ํ•˜ํ•œ๋ณด๋‹ค ๋‚ฎ์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค. `npm i -D cross-spawn@^7.0.6`์œผ๋กœ ์˜ฌ๋ฆฌ์„ธ์š”. CI๋‚˜ ๋ณด์•ˆ ๋ฏผ๊ฐ ํ™˜๊ฒฝ์—์„œ๋Š” `npx commitgate --strict`๋ฅผ ์‚ฌ์šฉํ•ด ๊ฒฝ๊ณ ๋ฅผ ์‹คํŒจ๋กœ ๋‹ค๋ฃจ์„ธ์š”.
220
+
221
+ **๋‘ ๋ฒˆ ์„ค์น˜ํ•˜๋ฉด ๋ฎ์–ด์“ฐ๋‚˜์š”?**
222
+ ์•„๋‹ˆ์š”. ๊ธฐ์กด ํŒŒ์ผ์€ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค. ๊ฐ•์ œ๋กœ ๊ฐฑ์‹ ํ•˜๋ ค๋ฉด `--force`๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.
223
+
224
+ ---
225
+
226
+ ## ํ˜„์žฌ ๋ฒ”์œ„
227
+
228
+ ํ˜„์žฌ ๋ฒ„์ „์€ **Stage A: vendored scaffold ๋ชจ๋ธ**์ž…๋‹ˆ๋‹ค. ์ฆ‰ `npx commitgate`๊ฐ€ ๋Œ€์ƒ ํ”„๋กœ์ ํŠธ์— ์›Œํฌํ”Œ๋กœ ํŒŒ์ผ์„ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.
229
+
230
+ ํ˜„์žฌ ์šด์˜ ์ค‘์ธ ๊ฒ€์ฆ์ž…๋‹ˆ๋‹ค.
231
+
232
+ - GitHub Actions์—์„œ `ubuntu-latest`, `macos-latest`, `windows-latest` ร— Node 18/20/22 ๋งคํŠธ๋ฆญ์Šค๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
233
+ - `npm run smoke`๋Š” pack tarball ์„ค์น˜๋ณธ์˜ `commitgate` bin์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
234
+ - Windows `.cmd` ๋ž˜ํผ ์ฃผ์ž… ํšŒ๊ท€ ํ…Œ์ŠคํŠธ๊ฐ€ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €์™€ Codex wrapper ๊ฒฝ๋กœ๋ฅผ ๋ณดํ˜ธํ•ฉ๋‹ˆ๋‹ค.
235
+
236
+ ์•„๋ž˜๋Š” ํ›„์† ๋ฒ”์œ„์ž…๋‹ˆ๋‹ค.
237
+
238
+ - `node_modules`์—์„œ ์ง์ ‘ ์‹คํ–‰ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ชจ๋ธ
239
+ - ๋น„-git VCS ์ง€์›
240
+ - ๋” ๋‹ค์–‘ํ•œ ์„ค๊ณ„๋ฌธ์„œ ํ…œํ”Œ๋ฆฟ
241
+
242
+ ---
243
+
244
+ ## License
245
+
246
+ [MIT](./LICENSE) ยฉ 2026 sol5288
@@ -18,4 +18,5 @@ register()
18
18
 
19
19
  const initTs = pathToFileURL(join(dirname(fileURLToPath(import.meta.url)), 'init.ts')).href
20
20
  const mod = await import(initTs)
21
- mod.main(process.argv.slice(2))
21
+ // runCli = ์˜ˆ์™ธ๋ฅผ ์นœ์ ˆํ•œ ํ•œ ์ค„ ๋ฉ”์‹œ์ง€ + exit 1๋กœ ๋ณ€ํ™˜ํ•˜๋Š” CLI ๊ฒฝ๊ณ„(์ŠคํƒํŠธ๋ ˆ์ด์Šค ๋…ธ์ถœ ๋ฐฉ์ง€).
22
+ mod.runCli(process.argv.slice(2))
package/bin/init.ts CHANGED
@@ -21,10 +21,11 @@ import {
21
21
  copyFileSync,
22
22
  realpathSync,
23
23
  } from 'node:fs'
24
+ import { execFileSync } from 'node:child_process'
24
25
  import { resolve, join, dirname, relative } from 'node:path'
25
26
  import { fileURLToPath, pathToFileURL } from 'node:url'
26
27
  import { loadConfig, stripBom, type PackageManager } from '../scripts/req/lib/config'
27
- import { createGitAdapter } from '../scripts/req/lib/adapters'
28
+ import { createGitAdapter, type GitRunner } from '../scripts/req/lib/adapters'
28
29
  import * as semver from 'semver'
29
30
 
30
31
  /** ์ด ํŒจํ‚ค์ง€ ๋ฃจํŠธ(bin/ ๊ธฐ์ค€ 1๋‹จ๊ณ„ ์œ„). ๋ณต์‚ฌ ์›๋ณธ. */
@@ -73,7 +74,12 @@ export interface InitResult {
73
74
  * targetRoot๊ฐ€ repo top-level๊ณผ ์ผ์น˜ํ•ด์•ผ ํ•จ(ํ•˜์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์Šค์บํด๋“œ ๋ฐฉ์ง€). git ๋ฏธ์„ค์น˜/๋น„-repo โ†’ throw(fail-closed).
74
75
  */
75
76
  function assertGitWorkTree(targetRoot: string): void {
76
- const git = createGitAdapter(targetRoot)
77
+ // probe ์ „์šฉ runner: ๋น„-repo์ผ ๋•Œ git์ด ๋ฑ‰๋Š” `fatal: not a git repository` stderr๋ฅผ ์‚ผํ‚จ๋‹ค.
78
+ // ์šฐ๋ฆฌ๊ฐ€ ๋” ๋ช…ํ™•ํ•œ ์กฐ์น˜ ๋ฉ”์‹œ์ง€๋กœ ๋Œ€์ฒดํ•˜๋ฏ€๋กœ raw git stderr๋Š” ๋…ธ์ด์ฆˆ์ผ ๋ฟ(design ํ›„์† UX).
79
+ // โš ๏ธ ์ „์—ญ GitAdapter ๊ธฐ๋ณธ(stderr ์ƒ์†)์€ ๊ทธ๋Œ€๋กœ โ€” ๋‹ค๋ฅธ git ํ˜ธ์ถœ(req:commit ๋“ฑ)์˜ ์ง„๋‹จ ์†์‹ค ๋ฐฉ์ง€.
80
+ const quietRunner: GitRunner = (file, args, opts) =>
81
+ execFileSync(file, args, { ...opts, stdio: ['ignore', 'pipe', 'ignore'] })
82
+ const git = createGitAdapter(targetRoot, quietRunner)
77
83
  let inside: string
78
84
  let topLevel: string
79
85
  try {
@@ -98,6 +104,16 @@ export function detectPackageManager(root: string): PackageManager {
98
104
  return 'npm'
99
105
  }
100
106
 
107
+ /**
108
+ * ๋Œ€์ƒ pm์— ๋งž๋Š” package.json script ์‹คํ–‰ ์ปค๋งจ๋“œ ๋ฌธ์ž์—ด.
109
+ * npm์€ ์ž„์˜ ์Šคํฌ๋ฆฝํŠธ๋ฅผ `npm run <script>`๋กœ๋งŒ ์‹คํ–‰ํ•˜๊ณ  ์ธ์ž ์ „๋‹ฌ์— `--` ๊ตฌ๋ถ„์ž๊ฐ€ ํ•„์š”ํ•˜๋‹ค
110
+ * (`npm req:new โ€ฆ`์€ "Unknown command"๋กœ ์‹คํŒจ). pnpm/yarn์€ bare script + ์ธ์ž ์ง์ ‘ ์ „๋‹ฌ์„ ์ง€์›.
111
+ * โ†’ ์•ˆ๋‚ด ๋ฌธ๊ตฌ๊ฐ€ ์‹ค์ œ๋กœ ๋ณต๋ถ™ ๊ฐ€๋Šฅํ•œ ์œ ํšจ ์ปค๋งจ๋“œ๊ฐ€ ๋˜๋„๋ก pm๋ณ„๋กœ ๋ถ„๊ธฐ(README ์ˆ˜๋™ ๋ช…๋ น๊ณผ ๋™์ผ ํ˜•ํƒœ).
112
+ */
113
+ export function runScriptCmd(pm: PackageManager, script: string, args: string): string {
114
+ return pm === 'npm' ? `npm run ${script} -- ${args}` : `${pm} ${script} ${args}`
115
+ }
116
+
101
117
  /** dir ํ•˜์œ„ ๋ชจ๋“  ํŒŒ์ผ์˜ ์ ˆ๋Œ€๊ฒฝ๋กœ(์žฌ๊ท€). */
102
118
  function walkFiles(dir: string): string[] {
103
119
  const out: string[] = []
@@ -388,7 +404,7 @@ function printHelp(): void {
388
404
  console.log(`commitgate โ€” AI REQ workflow(์ปค๋ฐ‹ ๊ฒŒ์ดํŠธ) kit ์„ค์น˜
389
405
 
390
406
  ์‚ฌ์šฉ๋ฒ•:
391
- npx commitgate [--dir <๋Œ€์ƒrepo>] [--force] [--dry-run]
407
+ npx commitgate [--dir <๋Œ€์ƒrepo>] [--force] [--dry-run] [--strict]
392
408
 
393
409
  ์˜ต์…˜:
394
410
  --dir <path> ๋Œ€์ƒ repo ๋ฃจํŠธ(๊ธฐ๋ณธ: ํ˜„์žฌ ๋””๋ ‰ํ„ฐ๋ฆฌ)
@@ -401,7 +417,10 @@ function printHelp(): void {
401
417
  1. <๋Œ€์ƒrepo>์—์„œ ์˜์กด์„ฑ ์„ค์น˜(๊ฐ์ง€๋œ ํŒจํ‚ค์ง€๋งค๋‹ˆ์ €)
402
418
  2. codex CLI ์„ค์น˜ ํ™•์ธ(๋ฆฌ๋ทฐ ์‹คํ˜ธ์ถœ์šฉ)
403
419
  3. req.config.json ์กฐ์ •(branchPrefix/ticketRoot ๋“ฑ)
404
- 4. <pm> req:new <slug> --run ์œผ๋กœ ์ฒซ ํ‹ฐ์ผ“ ์ƒ์„ฑ`)
420
+ 4. ์ฒซ ํ‹ฐ์ผ“ ์ƒ์„ฑ:
421
+ npm โ†’ npm run req:new -- <slug> --run
422
+ pnpm โ†’ pnpm req:new <slug> --run
423
+ yarn โ†’ yarn req:new <slug> --run`)
405
424
  }
406
425
 
407
426
  export function main(argv: string[]): void {
@@ -430,9 +449,24 @@ export function main(argv: string[]): void {
430
449
  console.log(` 1. cd ${r.targetRoot} && ${r.packageManager} install`)
431
450
  console.log(` 2. codex --version # ๋ฆฌ๋ทฐ ์‹คํ˜ธ์ถœ ์ „์ œ(๋ฏธ์„ค์น˜๋ฉด review-codex --run์ด fail-closed)`)
432
451
  console.log(` 3. req.config.json ํ™•์ธ(branchPrefix ๋“ฑ)`)
433
- console.log(` 4. ${r.packageManager} req:new <slug> --run`)
452
+ console.log(` 4. ${runScriptCmd(r.packageManager, 'req:new', '<slug> --run')}`)
453
+ }
454
+ }
455
+
456
+ /**
457
+ * CLI ๊ฒฝ๊ณ„: main์„ ์‹คํ–‰ํ•˜๋˜ ์‚ฌ์ „์กฐ๊ฑด ๋ฏธ์ถฉ์กฑ ๋“ฑ ์˜ˆ์ƒ๋œ ์‹คํŒจ(throw)๋Š”
458
+ * raw ์ŠคํƒํŠธ๋ ˆ์ด์Šค๊ฐ€ ์•„๋‹ˆ๋ผ ์นœ์ ˆํ•œ ํ•œ ์ค„ ๋ฉ”์‹œ์ง€ + ์ข…๋ฃŒ์ฝ”๋“œ 1๋กœ ํ‘œ๋ฉดํ™”ํ•œ๋‹ค.
459
+ * (์—๋Ÿฌ ๋ฌธ๊ตฌ ์ž์ฒด๊ฐ€ ์ด๋ฏธ ์กฐ์น˜ ์•ˆ๋‚ด๋ฅผ ๋‹ด๊ณ  ์žˆ์–ด ์ŠคํƒํŠธ๋ ˆ์ด์Šค๋Š” ๋…ธ์ด์ฆˆ์ผ ๋ฟ โ€” REQ ํ›„์† UX ๊ฐœ์„ .)
460
+ * bin/commitgate.mjs ๋Ÿฐ์ฒ˜์™€ ์ง์ ‘ ์‹คํ–‰(`tsx bin/init.ts`)์ด ๊ณต์œ ํ•˜๋Š” ๋‹จ์ผ ๊ฒฝ๊ณ„.
461
+ */
462
+ export function runCli(argv: string[]): void {
463
+ try {
464
+ main(argv)
465
+ } catch (err) {
466
+ console.error(`commitgate: ${err instanceof Error ? err.message : String(err)}`)
467
+ process.exitCode = 1
434
468
  }
435
469
  }
436
470
 
437
471
  const isMain = import.meta.url === pathToFileURL(process.argv[1] ?? '').href
438
- if (isMain) main(process.argv.slice(2))
472
+ if (isMain) runCli(process.argv.slice(2))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "commitgate",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "CommitGate โ€” Builderโ†”Reviewer(Claudeโ†”Codex) fail-closed ์ปค๋ฐ‹ ๊ฒŒ์ดํŠธ: ๋ฆฌ๋ทฐยท์Šน์ธยท์ฆ๊ฑฐ ์—†์ธ ์ปค๋ฐ‹์„ ํ†ต๊ณผ์‹œํ‚ค์ง€ ์•Š๋Š” AI REQ ์›Œํฌํ”Œ๋กœ kit (req:new/review-codex/doctor/commit)",
5
5
  "type": "module",
6
6
  "license": "MIT",