commitgate 0.1.1 → 0.2.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.en.md +120 -244
- package/README.md +121 -245
- package/bin/init.ts +115 -5
- package/package.json +66 -63
package/README.en.md
CHANGED
|
@@ -1,341 +1,217 @@
|
|
|
1
|
-
# CommitGate
|
|
1
|
+
# CommitGate
|
|
2
2
|
|
|
3
3
|
🌐 [한국어](./README.md) · **English**
|
|
4
4
|
|
|
5
|
-
**A
|
|
5
|
+
**A commit gate that blocks AI-generated code from being committed until Codex has reviewed and approved it.**
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
AI coding agents can move quickly, but unreviewed changes should not go straight into your history. CommitGate wraps each change in a REQ ticket and only allows the staged tree approved by Codex to be committed. If the code changes after approval, or if evidence is missing, it fails closed.
|
|
8
8
|
|
|
9
9
|
[](./LICENSE)
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Quick Start
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Run this from your project root. The project must be a **git repository with a `package.json`**.
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
In short, instead of "build alone, commit alone," it enforces **cross-verification between the AI that built it and the AI that checked it.**
|
|
24
|
-
|
|
25
|
-
## 🎯 What problem does it solve?
|
|
26
|
-
|
|
27
|
-
AI produces code **fast**, but committing it without verification is risky. CommitGate:
|
|
28
|
-
|
|
29
|
-
- ✅ Forces **every change through review.**
|
|
30
|
-
- ✅ Binds approval to **"the exact code that was reviewed."** (You can't swap in changes after approval — it's compared like a fingerprint.)
|
|
31
|
-
- ✅ **Blocks by default (fail-closed)** whenever something is ambiguous or missing. "Pass only when certain" is the default, so it's safe.
|
|
32
|
-
- ✅ Leaves **evidence on disk** of who approved what and when.
|
|
33
|
-
|
|
34
|
-
## 🔄 The flow at a glance
|
|
35
|
-
|
|
36
|
-
```
|
|
37
|
-
① create ticket → ② write design → ③ design review(Codex) → ④ implement code
|
|
38
|
-
req:new req:review-codex
|
|
39
|
-
|
|
40
|
-
→ ⑤ gate check → ⑥ code review(Codex) → ⑦ commit once approved
|
|
41
|
-
req:doctor req:review-codex req:commit
|
|
17
|
+
```sh
|
|
18
|
+
npx commitgate
|
|
19
|
+
npm install
|
|
20
|
+
codex --version
|
|
21
|
+
codex login status
|
|
42
22
|
```
|
|
43
23
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
## 📦 Prerequisites
|
|
24
|
+
Then paste this prompt into your AI coding agent.
|
|
49
25
|
|
|
50
|
-
|
|
26
|
+
```text
|
|
27
|
+
Do not handle this as a normal implementation. Use the CommitGate workflow installed in this project.
|
|
51
28
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
| **Git** (required) | `git --version` | install from [git-scm.com](https://git-scm.com) |
|
|
55
|
-
| **Node.js 18.17+** (required) | `node --version` | install from [nodejs.org](https://nodejs.org) |
|
|
56
|
-
| **Codex CLI** (for review) | `codex --version` | install OpenAI Codex CLI (without it only review is unavailable; the rest works) |
|
|
57
|
-
| **Package manager** | `npm --version` | `npm` ships with Node (or use `pnpm`/`yarn`) |
|
|
58
|
-
|
|
59
|
-
> 💡 **Reviewer = Codex CLI.** To actually run reviews, the Codex CLI must be installed. Without it, review commands **fail safely (fail-closed)** — they never silently pass.
|
|
60
|
-
|
|
61
|
-
### 🔧 Install & log in to the Codex CLI (Reviewer setup)
|
|
29
|
+
Create a new REQ ticket and run this flow end to end:
|
|
30
|
+
req:new → write design docs → Codex design review → implement and test → req:doctor → Codex phase review → req:commit
|
|
62
31
|
|
|
63
|
-
|
|
32
|
+
Proceed automatically:
|
|
33
|
+
- If Codex returns NEEDS_FIX, fix the findings and rerun review until approved.
|
|
34
|
+
- The review target is only what has been staged with git add.
|
|
35
|
+
- Do not manually git add state.json or responses/.
|
|
64
36
|
|
|
65
|
-
|
|
37
|
+
Stop for human confirmation only:
|
|
38
|
+
- Right before req:commit --run
|
|
39
|
+
- Before merging to main or pushing
|
|
40
|
+
- Before destructive actions such as reset, clean, or force push
|
|
41
|
+
- When the requested scope must change
|
|
42
|
+
- When Codex review is still not approved after 3 rounds
|
|
66
43
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
brew install codex
|
|
44
|
+
Requirement:
|
|
45
|
+
- What:
|
|
46
|
+
- Why:
|
|
47
|
+
- Constraints:
|
|
48
|
+
- Done when:
|
|
73
49
|
```
|
|
74
50
|
|
|
75
|
-
|
|
51
|
+
The agent's first reply should look roughly like this.
|
|
76
52
|
|
|
77
|
-
```
|
|
78
|
-
|
|
53
|
+
```text
|
|
54
|
+
REQ-2026-002 created
|
|
55
|
+
Branch: feat/req-2026-002-profile-edit-api
|
|
56
|
+
Phases:
|
|
57
|
+
- phase-1: implement PATCH /profile
|
|
58
|
+
- phase-2: tests and regression checks
|
|
59
|
+
Control points: before req:commit --run, before push
|
|
79
60
|
```
|
|
80
61
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
- **Option A. With a ChatGPT account (recommended, browser)**
|
|
84
|
-
```sh
|
|
85
|
-
codex login
|
|
86
|
-
```
|
|
87
|
-
A browser opens → sign in with your ChatGPT account → return to the terminal when done.
|
|
62
|
+
After that, the agent runs design, implementation, tests, and Codex review. You only confirm at control points such as commit or push.
|
|
88
63
|
|
|
89
|
-
|
|
90
|
-
```sh
|
|
91
|
-
# via environment variable (simplest)
|
|
92
|
-
export OPENAI_API_KEY=sk-... # Windows PowerShell: $env:OPENAI_API_KEY="sk-..."
|
|
64
|
+
---
|
|
93
65
|
|
|
94
|
-
|
|
95
|
-
printenv OPENAI_API_KEY | codex login --with-api-key
|
|
96
|
-
```
|
|
97
|
-
Create an API key at [platform.openai.com](https://platform.openai.com/api-keys).
|
|
66
|
+
## What Does It Enforce?
|
|
98
67
|
|
|
99
|
-
|
|
68
|
+
CommitGate is designed to block **unreviewed changes from being committed**, not just to wrap commands.
|
|
100
69
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
70
|
+
- No Codex approval means no commit.
|
|
71
|
+
- If the approved staged tree differs from the current staged tree, the commit is blocked.
|
|
72
|
+
- Workflow files such as `state.json` and `responses/` cannot be mixed into the source commit.
|
|
73
|
+
- If Codex CLI is missing or fails, the workflow fails instead of silently passing.
|
|
74
|
+
- Approval responses and evidence are kept under `workflow/REQ-.../responses/`.
|
|
105
75
|
|
|
106
|
-
|
|
107
|
-
> ⚠️ If Windows can't find the `codex` command, open a **new terminal** so PATH is reloaded (a common issue right after a global install).
|
|
76
|
+
In short: **approved changes pass, ambiguous changes stop.**
|
|
108
77
|
|
|
109
78
|
---
|
|
110
79
|
|
|
111
|
-
##
|
|
112
|
-
|
|
113
|
-
**In your project folder** (= a git repo that has a `package.json`):
|
|
80
|
+
## What Installation Adds
|
|
114
81
|
|
|
115
|
-
|
|
116
|
-
npx commitgate
|
|
117
|
-
```
|
|
82
|
+
`npx commitgate` adds the following to the target project. Existing files are not overwritten by default.
|
|
118
83
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
84
|
+
| Added item | Purpose |
|
|
85
|
+
|---|---|
|
|
86
|
+
| `scripts/req/` | `req:new`, `req:review-codex`, `req:doctor`, `req:commit` scripts |
|
|
87
|
+
| `workflow/*.schema.json` | Schemas for Codex responses and config |
|
|
88
|
+
| `req.config.json` | Project-level configuration |
|
|
89
|
+
| `AGENTS.md` | Template rules for the agent and reviewer |
|
|
90
|
+
| `package.json` scripts | `req:*` commands and required devDependencies |
|
|
125
91
|
|
|
126
|
-
|
|
92
|
+
Preview without writing files:
|
|
127
93
|
|
|
128
94
|
```sh
|
|
129
|
-
|
|
95
|
+
npx commitgate --dry-run
|
|
130
96
|
```
|
|
131
97
|
|
|
132
|
-
> Add `--dry-run` to preview what it would do **without changing anything**: `npx commitgate --dry-run`
|
|
133
|
-
|
|
134
98
|
---
|
|
135
99
|
|
|
136
|
-
##
|
|
137
|
-
|
|
138
|
-
Honestly, **nobody types `req:new → review → implement → review → commit` by hand, one at a time.** It's tedious.
|
|
139
|
-
|
|
140
|
-
The real way to use CommitGate is this: **give your AI coding agent a prompt with your "requirements" plus "use this workflow," and the agent drives the whole thing.** You only approve at **control points (commit, merge, push, etc.).**
|
|
141
|
-
|
|
142
|
-
### What this mode assumes
|
|
143
|
-
- **An AI coding agent that can run shell commands** — Claude Code, Cursor (agent), Codex CLI, etc. (it must be able to run terminal commands in your repo)
|
|
144
|
-
- **Codex CLI installed** — the Reviewer role. Without it, the review step stops (fail-closed).
|
|
145
|
-
- **A filled-in `AGENTS.md`** — write your project's rules (coding conventions, test commands, etc.) into the template that `npx commitgate` created; it improves review quality.
|
|
146
|
-
|
|
147
|
-
### Three steps and you're done
|
|
148
|
-
1. Copy the **prompt template** below and fill the `[Requirements]` block at the bottom with your request.
|
|
149
|
-
2. Paste the whole thing **into your AI agent's chat.**
|
|
150
|
-
3. The agent's **first reply reports only the REQ number, branch, phase plan, and control points.** After that it asks you **only at control points** — everything else (implementation, tests, Codex review, applying NEEDS_FIX, re-review) is automatic.
|
|
151
|
-
|
|
152
|
-
### 📋 Copy-paste prompt template
|
|
100
|
+
## Prerequisites
|
|
153
101
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
[Do automatically]
|
|
162
|
-
- Within the approved phase scope, do implementation, tests, keeping codex-request consistent, applying NEEDS_FIX, and re-review (resume) automatically. Do not ask me every time.
|
|
163
|
-
- If Codex returns NEEDS_FIX, apply the feedback and re-run the review until approved (max 3 rounds per phase).
|
|
164
|
-
- Only what is `git add`ed is reviewed. NEVER `git add` state.json or responses/ (the tool manages those).
|
|
165
|
-
|
|
166
|
-
[Control points — stop and ask me ONLY here]
|
|
167
|
-
- Right before `req:commit --run` (the actual commit / HIGH impact)
|
|
168
|
-
- Right before merging to main or `git push`
|
|
169
|
-
- Destructive operations such as reset, clean, force push
|
|
170
|
-
- When a design-scope change or a feature not in [Requirements] is needed
|
|
171
|
-
- When Codex review exceeds 3 rounds without approval, or the judgment is unclear
|
|
172
|
-
- When a prerequisite is missing (not a git repo, no Codex CLI / Node / package manager) and you must fail-closed
|
|
173
|
-
|
|
174
|
-
[First reply] Report only the REQ number, branch, phase plan, and control points. After that, stop only at control points.
|
|
175
|
-
|
|
176
|
-
[Requirements]
|
|
177
|
-
- What: (e.g.) Add a user-profile edit API
|
|
178
|
-
- Why: (e.g.) Only the name is editable today — email and bio should be editable too
|
|
179
|
-
- Constraints: (e.g.) Reuse the existing auth middleware, validate email format, no new external libraries
|
|
180
|
-
- Done when: (e.g.) PATCH /profile works + unit tests pass + existing tests unbroken
|
|
181
|
-
````
|
|
182
|
-
|
|
183
|
-
> The `[Requirements]` example above is **just a sample.** Just replace the 4 lines (What / Why / Constraints / Done when) with your own. If the request is large, it's split into multiple phases, each going through its own review and gate.
|
|
102
|
+
| Requirement | Check | Notes |
|
|
103
|
+
|---|---|---|
|
|
104
|
+
| Git | `git --version` | Required |
|
|
105
|
+
| Node.js 18.17+ | `node --version` | Required |
|
|
106
|
+
| npm, pnpm, or yarn | `npm --version` | Examples use npm |
|
|
107
|
+
| Codex CLI | `codex --version` | Required for review runs |
|
|
184
108
|
|
|
185
|
-
|
|
109
|
+
If Codex CLI is not installed:
|
|
186
110
|
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
- phase-2: unit tests + regression
|
|
192
|
-
Control points: proceed per phase after design approval / confirm before req:commit --run / push needs separate approval
|
|
193
|
-
→ Starting with the design docs. Once the design review passes, I'll move to implementation.
|
|
111
|
+
```sh
|
|
112
|
+
npm install -g @openai/codex
|
|
113
|
+
codex login
|
|
114
|
+
codex login status
|
|
194
115
|
```
|
|
195
116
|
|
|
196
|
-
|
|
117
|
+
On Windows, if `codex` is not found right after installation, open a new terminal so PATH is reloaded.
|
|
197
118
|
|
|
198
119
|
---
|
|
199
120
|
|
|
200
|
-
##
|
|
121
|
+
## Manual Commands
|
|
201
122
|
|
|
202
|
-
|
|
203
|
-
> These are the actual commands the workflow runs internally. Refer to them only when you need to **understand the behavior, debug, or run steps manually.**
|
|
204
|
-
|
|
205
|
-
Let's walk the whole flow with one small feature as an example. (Commands use `npm`; arguments after `npm run` go after `--`. With `pnpm` you can drop the `--`, e.g. `pnpm req:new my-feature --run`.)
|
|
206
|
-
|
|
207
|
-
### Step 1 — create a work ticket
|
|
123
|
+
Most users should use the prompt flow above. This section is for understanding what the workflow runs internally or for debugging.
|
|
208
124
|
|
|
209
125
|
```sh
|
|
126
|
+
# 1. Create a ticket and branch
|
|
210
127
|
npm run req:new -- my-feature --run
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
- A new branch (`feat/req-...`) is created, and three design docs appear under `workflow/REQ-2026-001/`.
|
|
214
|
-
- The output shows a **ticket number** (e.g. `REQ-2026-001`). Later commands use just the number → `2026-001`
|
|
215
|
-
|
|
216
|
-
### Step 2 — write the design docs
|
|
217
|
-
|
|
218
|
-
Fill in the three files under `workflow/REQ-2026-001/`:
|
|
219
|
-
|
|
220
|
-
- `00-requirement.md` — **what** to build and why
|
|
221
|
-
- `01-design.md` — **how** to build it
|
|
222
|
-
- `02-plan.md` — in what **order/phases** to proceed
|
|
223
|
-
|
|
224
|
-
### Step 3 — get a design review (Codex)
|
|
225
|
-
|
|
226
|
-
Stage your design (i.e. `git add`):
|
|
227
128
|
|
|
228
|
-
|
|
129
|
+
# 2. Write design docs, then stage them
|
|
229
130
|
git add workflow/REQ-2026-001/00-requirement.md workflow/REQ-2026-001/01-design.md workflow/REQ-2026-001/02-plan.md
|
|
230
|
-
npm run req:review-codex -- 2026-001 --kind design --run
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
- Codex reads the design and returns **approval** or **NEEDS_FIX**.
|
|
234
|
-
- If NEEDS_FIX, apply the feedback, then **`git add` again → re-run the command.** Repeat until approved.
|
|
235
|
-
|
|
236
|
-
### Step 4 — implement code + tests
|
|
237
131
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
### Step 5 — gate check
|
|
132
|
+
# 3. Design review
|
|
133
|
+
npm run req:review-codex -- 2026-001 --kind design --run
|
|
241
134
|
|
|
242
|
-
|
|
135
|
+
# 4. Implement code, then stage source files
|
|
136
|
+
git add <changed-source-files>
|
|
243
137
|
|
|
244
|
-
|
|
245
|
-
git add <files-you-changed>
|
|
138
|
+
# 5. Gate check
|
|
246
139
|
npm run req:doctor -- 2026-001
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
- It checks several things (is the design approval valid, does the staged code match the approved code, is the working tree clean, etc.) and shows **PASS/FAIL.**
|
|
250
140
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
### Step 6 — get a code review (Codex)
|
|
254
|
-
|
|
255
|
-
```sh
|
|
141
|
+
# 6. Implementation review
|
|
256
142
|
npm run req:review-codex -- 2026-001 --kind phase --run
|
|
143
|
+
|
|
144
|
+
# 7. Commit approved code
|
|
145
|
+
npm run req:commit -- 2026-001 --run -m "feat: my feature"
|
|
257
146
|
```
|
|
258
147
|
|
|
259
|
-
|
|
260
|
-
- Once approved, `commit_allowed=true` and the commit opens.
|
|
148
|
+
Important: only stage code and documents you authored for the source commit. `state.json` and `responses/` are managed by the tool.
|
|
261
149
|
|
|
262
|
-
|
|
150
|
+
For multi-line commit messages, use a file instead of `-m`.
|
|
263
151
|
|
|
264
152
|
```sh
|
|
265
|
-
npm run req:commit -- 2026-001 --run -
|
|
153
|
+
npm run req:commit -- 2026-001 --run --message-file commit-message.txt
|
|
266
154
|
```
|
|
267
155
|
|
|
268
|
-
- After passing the gate (doctor) one final time, it makes a **code commit + an evidence commit.**
|
|
269
|
-
- If it isn't approved, or the code changed after approval, it **stops here.** (That's the heart of CommitGate.)
|
|
270
|
-
|
|
271
|
-
🎉 Done! Your code is now committed safely with review, approval, and evidence all recorded.
|
|
272
|
-
|
|
273
156
|
---
|
|
274
157
|
|
|
275
|
-
##
|
|
158
|
+
## Command Cheat Sheet
|
|
276
159
|
|
|
277
|
-
| Command |
|
|
160
|
+
| Command | Purpose |
|
|
278
161
|
|---|---|
|
|
279
|
-
| `npx commitgate` | Install
|
|
280
|
-
| `req:new <
|
|
281
|
-
| `req:review-codex <
|
|
282
|
-
| `req:review-codex <
|
|
283
|
-
| `req:doctor <
|
|
284
|
-
| `req:commit <
|
|
285
|
-
|
|
286
|
-
> Instead of `-m "message"`, multi-line messages can be read from a file with `--message-file message.txt`.
|
|
162
|
+
| `npx commitgate` | Install CommitGate into a project |
|
|
163
|
+
| `req:new <slug> --run` | Create a REQ ticket, branch, and design docs |
|
|
164
|
+
| `req:review-codex <id> --kind design --run` | Review the design |
|
|
165
|
+
| `req:review-codex <id> --kind phase --run` | Review the implementation |
|
|
166
|
+
| `req:doctor <id>` | Check gate status |
|
|
167
|
+
| `req:commit <id> --run -m "message"` | Commit approved changes |
|
|
287
168
|
|
|
288
169
|
---
|
|
289
170
|
|
|
290
|
-
##
|
|
171
|
+
## Configuration
|
|
291
172
|
|
|
292
|
-
|
|
173
|
+
Defaults are enough for most projects. If needed, edit `req.config.json` in the project root.
|
|
293
174
|
|
|
294
175
|
| Key | Default | Meaning |
|
|
295
176
|
|---|---|---|
|
|
296
|
-
| `branchPrefix` | `"feat/req-"` | Prefix for
|
|
297
|
-
| `ticketRoot` | `"workflow"` |
|
|
298
|
-
| `packageManager` | auto-detected | `npm
|
|
299
|
-
| `designDocs` | `00
|
|
177
|
+
| `branchPrefix` | `"feat/req-"` | Prefix for new branches |
|
|
178
|
+
| `ticketRoot` | `"workflow"` | REQ ticket directory |
|
|
179
|
+
| `packageManager` | auto-detected | `npm`, `pnpm`, or `yarn` |
|
|
180
|
+
| `designDocs` | `00/01/02` docs | Design document filenames |
|
|
300
181
|
|
|
301
|
-
|
|
182
|
+
Empty `branchPrefix` values and paths that escape the project root are rejected.
|
|
302
183
|
|
|
303
184
|
---
|
|
304
185
|
|
|
305
|
-
##
|
|
186
|
+
## FAQ
|
|
306
187
|
|
|
307
|
-
**
|
|
308
|
-
|
|
188
|
+
**What happens if Codex CLI is missing?**
|
|
189
|
+
The review command fails. It is not treated as approval.
|
|
309
190
|
|
|
310
|
-
**
|
|
311
|
-
|
|
191
|
+
**Can I edit code after approval and still commit?**
|
|
192
|
+
No. If the staged tree changes after approval, CommitGate treats the approval as stale and requires review again.
|
|
312
193
|
|
|
313
|
-
**
|
|
314
|
-
|
|
194
|
+
**Why should I not stage `state.json` or `responses/`?**
|
|
195
|
+
They are workflow state and evidence files. Mixing them into the source commit weakens the approval binding, so `req:commit` blocks it.
|
|
315
196
|
|
|
316
|
-
**
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
**Q. On Windows my commit message newlines look wrong.**
|
|
320
|
-
A. For multi-line messages, use `--message-file file.txt` instead of `-m`.
|
|
197
|
+
**Does running install twice overwrite files?**
|
|
198
|
+
No. Existing files are skipped. Use `--force` if you intentionally want to refresh them.
|
|
321
199
|
|
|
322
200
|
---
|
|
323
201
|
|
|
324
|
-
##
|
|
202
|
+
## Current Scope
|
|
325
203
|
|
|
326
|
-
|
|
204
|
+
The current release is **Stage A: vendored scaffold model**. `npx commitgate` copies workflow files into the target project.
|
|
327
205
|
|
|
328
|
-
|
|
329
|
-
- Codex not installed / review failed → not a pass, fails clearly
|
|
330
|
-
- The approved code fingerprint differs from the current code → commit rejected
|
|
331
|
-
- The working tree is dirty (unreviewed changes mixed in) → review/commit rejected
|
|
206
|
+
Future scope:
|
|
332
207
|
|
|
333
|
-
|
|
208
|
+
- Running directly from `node_modules` as a library-style model
|
|
209
|
+
- Non-git VCS support
|
|
210
|
+
- More design document templates
|
|
211
|
+
- Broader Linux/macOS CI smoke coverage
|
|
334
212
|
|
|
335
213
|
---
|
|
336
214
|
|
|
337
|
-
##
|
|
215
|
+
## License
|
|
338
216
|
|
|
339
217
|
[MIT](./LICENSE) © 2026 sol5288
|
|
340
|
-
|
|
341
|
-
> This workflow was extracted as a standalone package from the REQ-2026-017 portability kit of `palm-kiosk-app`, and was validated by **reviewing and approving itself through this very workflow (dogfood).**
|
package/README.md
CHANGED
|
@@ -1,341 +1,217 @@
|
|
|
1
|
-
# CommitGate
|
|
1
|
+
# CommitGate
|
|
2
2
|
|
|
3
3
|
🌐 **한국어** · [English](./README.en.md)
|
|
4
4
|
|
|
5
|
-
**AI
|
|
5
|
+
**AI 코딩 변경을 Codex 리뷰 승인 없이는 커밋하지 못하게 막는 커밋 게이트입니다.**
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
AI 에이전트가 코드를 빠르게 만들더라도, 리뷰 없이 바로 커밋되면 위험합니다. CommitGate는 변경을 티켓 단위로 묶고, Codex가 승인한 staged tree만 커밋되게 합니다. 승인 후 코드가 바뀌거나 증거가 부족하면 기본적으로 막습니다.
|
|
8
8
|
|
|
9
9
|
[](./LICENSE)
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Quick Start
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
아래는 가장 짧은 사용 경로입니다. 프로젝트 루트는 **git 저장소이고 `package.json`이 있는 폴더**여야 합니다.
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
즉, "혼자 만들고 혼자 커밋"이 아니라 **"만든 AI ↔ 검사한 AI"의 교차 검증**을 강제합니다.
|
|
24
|
-
|
|
25
|
-
## 🎯 어떤 문제를 푸나요?
|
|
26
|
-
|
|
27
|
-
AI는 코드를 **빠르게** 만들지만, 검증 없이 그대로 커밋되면 위험합니다. CommitGate는:
|
|
28
|
-
|
|
29
|
-
- ✅ 모든 변경이 **리뷰를 반드시 거치게** 합니다.
|
|
30
|
-
- ✅ 승인은 **"리뷰한 바로 그 코드"에 묶입니다.** (승인 후 몰래 코드를 바꿔치기 못 함 — 지문처럼 대조)
|
|
31
|
-
- ✅ 무언가 애매하거나 빠지면 **일단 막습니다(fail-closed).** "확실할 때만 통과"가 기본값이라 안전합니다.
|
|
32
|
-
- ✅ 누가 언제 무엇을 승인했는지 **증거가 파일로 남습니다.**
|
|
33
|
-
|
|
34
|
-
## 🔄 동작 흐름 한눈에
|
|
35
|
-
|
|
36
|
-
```
|
|
37
|
-
① 티켓 만들기 → ② 설계 작성 → ③ 설계 리뷰(Codex) → ④ 코드 구현
|
|
38
|
-
req:new req:review-codex
|
|
39
|
-
|
|
40
|
-
→ ⑤ 관문 점검 → ⑥ 구현 리뷰(Codex) → ⑦ 승인되면 커밋
|
|
41
|
-
req:doctor req:review-codex req:commit
|
|
17
|
+
```sh
|
|
18
|
+
npx commitgate
|
|
19
|
+
npm install
|
|
20
|
+
codex --version
|
|
21
|
+
codex login status
|
|
42
22
|
```
|
|
43
23
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
## 📦 준비물 (Prerequisites)
|
|
24
|
+
그다음 AI 코딩 에이전트에게 아래 프롬프트를 붙여넣습니다.
|
|
49
25
|
|
|
50
|
-
|
|
26
|
+
```text
|
|
27
|
+
이 요청은 일반 구현으로 처리하지 말고, 이 프로젝트에 설치된 CommitGate를 사용해라.
|
|
51
28
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
| **Git** (필수) | `git --version` | [git-scm.com](https://git-scm.com) 에서 설치 |
|
|
55
|
-
| **Node.js 18.17+** (필수) | `node --version` | [nodejs.org](https://nodejs.org) 에서 설치 |
|
|
56
|
-
| **Codex CLI** (리뷰용) | `codex --version` | OpenAI Codex CLI 설치 (없으면 리뷰만 안 되고 나머지는 됨) |
|
|
57
|
-
| **패키지 매니저** | `npm --version` | Node 설치 시 `npm`은 기본 포함 (또는 `pnpm`/`yarn`) |
|
|
58
|
-
|
|
59
|
-
> 💡 **Reviewer = Codex CLI** 입니다. 리뷰를 실제로 돌리려면 Codex CLI가 설치되어 있어야 해요. 없으면 리뷰 명령이 "안전하게 실패(fail-closed)"합니다 — 조용히 통과되는 일은 없습니다.
|
|
60
|
-
|
|
61
|
-
### 🔧 Codex CLI 설치 & 로그인 (Reviewer 준비)
|
|
29
|
+
새 REQ 티켓을 만들고 다음 흐름을 끝까지 진행해라:
|
|
30
|
+
req:new → 설계문서 작성 → Codex design 리뷰 → 구현·테스트 → req:doctor → Codex phase 리뷰 → req:commit
|
|
62
31
|
|
|
63
|
-
|
|
32
|
+
자동으로 진행할 것:
|
|
33
|
+
- NEEDS_FIX가 나오면 수정하고 재리뷰해 승인까지 반복한다.
|
|
34
|
+
- 리뷰 대상은 git add 한 파일만이다.
|
|
35
|
+
- `state.json`과 `responses/`는 직접 `git add`하지 않는다.
|
|
64
36
|
|
|
65
|
-
|
|
37
|
+
멈춰서 확인받을 때:
|
|
38
|
+
- req:commit --run 직전
|
|
39
|
+
- main 병합 또는 push 직전
|
|
40
|
+
- reset, clean, force push 같은 destructive 작업 전
|
|
41
|
+
- 요구사항 범위를 바꿔야 할 때
|
|
42
|
+
- Codex 리뷰가 3라운드를 넘어도 승인되지 않을 때
|
|
66
43
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
brew install codex
|
|
44
|
+
요구사항:
|
|
45
|
+
- 무엇을:
|
|
46
|
+
- 왜:
|
|
47
|
+
- 제약:
|
|
48
|
+
- 완료 기준:
|
|
73
49
|
```
|
|
74
50
|
|
|
75
|
-
|
|
51
|
+
첫 응답은 보통 이렇게 나와야 합니다.
|
|
76
52
|
|
|
77
|
-
```
|
|
78
|
-
|
|
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 직전
|
|
79
60
|
```
|
|
80
61
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
- **방법 A. ChatGPT 계정으로 (권장, 브라우저)**
|
|
84
|
-
```sh
|
|
85
|
-
codex login
|
|
86
|
-
```
|
|
87
|
-
브라우저가 열리면 ChatGPT 계정으로 로그인 → 터미널로 돌아오면 완료.
|
|
62
|
+
이후에는 에이전트가 설계, 구현, 테스트, Codex 리뷰를 진행합니다. 사용자는 커밋이나 push 같은 통제점에서만 확인하면 됩니다.
|
|
88
63
|
|
|
89
|
-
|
|
90
|
-
```sh
|
|
91
|
-
# 환경변수로 (가장 간단)
|
|
92
|
-
export OPENAI_API_KEY=sk-... # Windows PowerShell: $env:OPENAI_API_KEY="sk-..."
|
|
64
|
+
---
|
|
93
65
|
|
|
94
|
-
|
|
95
|
-
printenv OPENAI_API_KEY | codex login --with-api-key
|
|
96
|
-
```
|
|
97
|
-
API 키는 [platform.openai.com](https://platform.openai.com/api-keys) 에서 발급합니다.
|
|
66
|
+
## 무엇을 보장하나요?
|
|
98
67
|
|
|
99
|
-
|
|
68
|
+
CommitGate가 막는 것은 단순한 명령 실수가 아니라 **리뷰받지 않은 변경이 커밋되는 상황**입니다.
|
|
100
69
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
70
|
+
- Codex 리뷰가 실패하거나 없으면 커밋할 수 없습니다.
|
|
71
|
+
- 승인된 staged tree와 지금 커밋하려는 staged tree가 다르면 막습니다.
|
|
72
|
+
- `state.json`, `responses/` 같은 워크플로 내부 파일을 source 커밋에 섞으면 막습니다.
|
|
73
|
+
- Codex CLI가 없거나 실행에 실패하면 조용히 통과하지 않고 실패합니다.
|
|
74
|
+
- 승인 응답과 증거 파일은 `workflow/REQ-.../responses/`에 남습니다.
|
|
105
75
|
|
|
106
|
-
|
|
107
|
-
> ⚠️ Windows에서 `codex` 명령을 못 찾으면 **새 터미널**을 열어 PATH를 새로 읽게 하세요(전역 설치 직후 흔한 문제).
|
|
76
|
+
한 줄로 말하면, **확실히 승인된 변경만 통과하고 애매하면 멈추는 방식**입니다.
|
|
108
77
|
|
|
109
78
|
---
|
|
110
79
|
|
|
111
|
-
##
|
|
112
|
-
|
|
113
|
-
**당신의 프로젝트 폴더**(= git 저장소, `package.json` 있는 곳)에서:
|
|
80
|
+
## 설치가 하는 일
|
|
114
81
|
|
|
115
|
-
|
|
116
|
-
npx commitgate
|
|
117
|
-
```
|
|
82
|
+
`npx commitgate`는 대상 프로젝트에 아래 파일과 설정을 추가합니다. 기존 파일은 기본적으로 덮어쓰지 않습니다.
|
|
118
83
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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 |
|
|
125
91
|
|
|
126
|
-
|
|
92
|
+
미리보기만 하려면:
|
|
127
93
|
|
|
128
94
|
```sh
|
|
129
|
-
|
|
95
|
+
npx commitgate --dry-run
|
|
130
96
|
```
|
|
131
97
|
|
|
132
|
-
> `--dry-run` 을 붙이면 **실제로 바꾸지 않고** 무엇을 할지 미리 볼 수 있어요: `npx commitgate --dry-run`
|
|
133
|
-
|
|
134
98
|
---
|
|
135
99
|
|
|
136
|
-
##
|
|
137
|
-
|
|
138
|
-
솔직히, `req:new → 리뷰 → 구현 → 리뷰 → 커밋`을 **손으로 하나씩 치는 사람은 없습니다.** 피곤하니까요.
|
|
139
|
-
|
|
140
|
-
CommitGate의 진짜 사용법은 이겁니다: **당신의 AI 코딩 에이전트에게 "요구사항"과 "이 워크플로를 쓰라"는 프롬프트를 던지면, 에이전트가 알아서 전 과정을 굴립니다.** 당신은 **통제점(커밋·머지·푸시 등)에서만** 승인하면 됩니다.
|
|
141
|
-
|
|
142
|
-
### 이 방식의 전제
|
|
143
|
-
- **셸 명령을 실행할 수 있는 AI 코딩 에이전트** — Claude Code, Cursor(agent), Codex CLI 등. (당신의 저장소에서 터미널 명령을 직접 돌릴 수 있어야 함)
|
|
144
|
-
- **Codex CLI 설치** — 리뷰어(Reviewer) 역할. 없으면 리뷰 단계가 fail-closed로 멈춥니다.
|
|
145
|
-
- **`AGENTS.md` 채우기** — `npx commitgate`가 만든 템플릿에 당신 프로젝트의 규칙(코딩 컨벤션·테스트 명령 등)을 적어두면 리뷰 품질이 올라갑니다.
|
|
146
|
-
|
|
147
|
-
### 3단계면 끝
|
|
148
|
-
1. 아래 **프롬프트 템플릿**을 복사하고, 맨 아래 `[요구사항]` 칸을 당신 요구로 채웁니다.
|
|
149
|
-
2. 전체를 **AI 에이전트 대화창에 그대로 붙여넣습니다.**
|
|
150
|
-
3. 에이전트가 **첫 응답으로 REQ 번호·브랜치·phase 계획·통제점**만 보고합니다. 이후엔 **통제점에서만** 당신에게 확인을 받습니다 — 나머지(구현·테스트·Codex 리뷰·NEEDS_FIX 반영·재리뷰)는 자동입니다.
|
|
151
|
-
|
|
152
|
-
### 📋 복사해서 쓰는 프롬프트 템플릿
|
|
100
|
+
## 준비물
|
|
153
101
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
[자동으로 진행할 것]
|
|
162
|
-
- 승인된 phase 범위 안에서 구현·테스트·codex-request 정합·NEEDS_FIX 반영·재리뷰(resume)는 자동으로 진행해라. 매번 확인받지 마라.
|
|
163
|
-
- Codex가 NEEDS_FIX를 주면 지적을 반영하고 재리뷰를 돌려 승인까지 반복해라(phase당 최대 3라운드).
|
|
164
|
-
- 리뷰 대상은 git add 한 것만이다. state.json·responses/ 는 절대 git add 하지 마라(도구가 관리한다).
|
|
165
|
-
|
|
166
|
-
[멈춰서 사람 확인을 받을 통제점 — 여기서만 멈춰라]
|
|
167
|
-
- req:commit --run 직전 (실제 커밋 / HIGH 영향)
|
|
168
|
-
- main 병합 또는 git push 직전
|
|
169
|
-
- reset·clean·force push 등 destructive 작업
|
|
170
|
-
- 설계 범위 변경 또는 [요구사항]에 없는 기능 추가가 필요할 때
|
|
171
|
-
- Codex 리뷰가 3라운드를 넘겨도 승인 안 되거나 판단이 불명확할 때
|
|
172
|
-
- git 저장소가 아니거나 Codex CLI·Node·패키지매니저 전제가 없어 fail-closed 해야 할 때
|
|
173
|
-
|
|
174
|
-
[첫 응답] REQ 번호, 브랜치, phase 계획, 통제점만 간단히 보고해라. 그 뒤부터는 통제점에서만 멈춰라.
|
|
175
|
-
|
|
176
|
-
[요구사항]
|
|
177
|
-
- 무엇을: (예) 사용자 프로필 편집 API 추가
|
|
178
|
-
- 왜: (예) 지금은 이름만 수정 가능 — 이메일·소개도 편집 필요
|
|
179
|
-
- 제약: (예) 기존 인증 미들웨어 재사용, 이메일 형식 검증, 외부 라이브러리 추가 금지
|
|
180
|
-
- 완료 기준: (예) PATCH /profile 동작 + 단위 테스트 통과 + 기존 테스트 무손상
|
|
181
|
-
````
|
|
182
|
-
|
|
183
|
-
> 위 `[요구사항]` 예시는 **샘플일 뿐**입니다. 4줄(무엇을/왜/제약/완료 기준)을 당신 요구로 바꾸기만 하면 됩니다. 요구가 크면 phase가 여러 개로 쪼개지고, 각 phase마다 리뷰·게이트를 거칩니다.
|
|
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` | 리뷰 실행에 필요 |
|
|
184
108
|
|
|
185
|
-
|
|
109
|
+
Codex CLI가 없다면:
|
|
186
110
|
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
- phase-2: 단위 테스트 + 회귀
|
|
192
|
-
통제점: design 승인 후 phase별 진행 / req:commit --run 직전 확인 / push는 별도 승인
|
|
193
|
-
→ 설계문서 작성부터 진행합니다. design 리뷰 통과하면 구현으로 넘어갑니다.
|
|
111
|
+
```sh
|
|
112
|
+
npm install -g @openai/codex
|
|
113
|
+
codex login
|
|
114
|
+
codex login status
|
|
194
115
|
```
|
|
195
116
|
|
|
196
|
-
|
|
117
|
+
Windows에서 설치 직후 `codex` 명령을 못 찾으면 새 터미널을 열어 PATH를 다시 읽게 하세요.
|
|
197
118
|
|
|
198
119
|
---
|
|
199
120
|
|
|
200
|
-
##
|
|
121
|
+
## 수동 명령
|
|
201
122
|
|
|
202
|
-
|
|
203
|
-
> 아래는 워크플로가 내부에서 돌리는 실제 명령들입니다. **동작 이해·디버깅·수동 실행**이 필요할 때만 참고하세요.
|
|
204
|
-
|
|
205
|
-
작은 기능 하나를 예로, 전체 흐름을 그대로 밟아 봅니다. (명령은 `npm` 기준이며, `npm run` 뒤 인자는 `--` 다음에 씁니다. `pnpm`을 쓰면 `pnpm req:new my-feature --run` 처럼 `--` 없이 됩니다.)
|
|
206
|
-
|
|
207
|
-
### 1단계 — 작업 티켓 만들기
|
|
123
|
+
대부분의 사용자는 위 프롬프트 방식으로 충분합니다. 아래는 내부에서 어떤 명령이 실행되는지 이해하거나 직접 디버깅할 때만 보면 됩니다.
|
|
208
124
|
|
|
209
125
|
```sh
|
|
126
|
+
# 1. 티켓과 브랜치 생성
|
|
210
127
|
npm run req:new -- my-feature --run
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
- 새 브랜치(`feat/req-...`)가 생기고, `workflow/REQ-2026-001/` 폴더에 설계 문서 3종이 만들어집니다.
|
|
214
|
-
- 출력에 **티켓 번호**(예: `REQ-2026-001`)가 나옵니다. 이후 명령에선 번호만 씁니다 → `2026-001`
|
|
215
|
-
|
|
216
|
-
### 2단계 — 설계 문서 작성
|
|
217
|
-
|
|
218
|
-
`workflow/REQ-2026-001/` 안의 세 파일을 채웁니다:
|
|
219
|
-
|
|
220
|
-
- `00-requirement.md` — **무엇을** 왜 만드는가
|
|
221
|
-
- `01-design.md` — **어떻게** 만들 것인가
|
|
222
|
-
- `02-plan.md` — 어떤 **순서/단계**로 진행할 것인가
|
|
223
|
-
|
|
224
|
-
### 3단계 — 설계 리뷰 받기 (Codex)
|
|
225
|
-
|
|
226
|
-
작성한 설계를 검사대에 올립니다(= `git add`):
|
|
227
128
|
|
|
228
|
-
|
|
129
|
+
# 2. 설계 문서 작성 후 stage
|
|
229
130
|
git add workflow/REQ-2026-001/00-requirement.md workflow/REQ-2026-001/01-design.md workflow/REQ-2026-001/02-plan.md
|
|
230
|
-
npm run req:review-codex -- 2026-001 --kind design --run
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
- Codex가 설계를 읽고 **승인** 또는 **보완 요청(NEEDS_FIX)** 을 돌려줍니다.
|
|
234
|
-
- 보완 요청이면 지적사항을 반영하고 **다시 `git add` → 위 명령을 재실행**하세요. 승인될 때까지 반복합니다.
|
|
235
|
-
|
|
236
|
-
### 4단계 — 코드 구현 + 테스트
|
|
237
131
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
### 5단계 — 관문 점검
|
|
132
|
+
# 3. 설계 리뷰
|
|
133
|
+
npm run req:review-codex -- 2026-001 --kind design --run
|
|
241
134
|
|
|
242
|
-
|
|
135
|
+
# 4. 코드 구현 후 stage
|
|
136
|
+
git add <changed-source-files>
|
|
243
137
|
|
|
244
|
-
|
|
245
|
-
git add <내가-바꾼-코드-파일들>
|
|
138
|
+
# 5. 게이트 점검
|
|
246
139
|
npm run req:doctor -- 2026-001
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
- 여러 항목(설계 승인 유효한지, 검사대에 올린 코드와 승인된 코드가 같은지, 워킹트리가 깨끗한지 등)을 점검해 **PASS/FAIL** 을 보여줍니다.
|
|
250
140
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
### 6단계 — 구현 리뷰 받기 (Codex)
|
|
254
|
-
|
|
255
|
-
```sh
|
|
141
|
+
# 6. 구현 리뷰
|
|
256
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"
|
|
257
146
|
```
|
|
258
147
|
|
|
259
|
-
|
|
260
|
-
- 승인되면 `commit_allowed=true` 가 되어 커밋이 열립니다.
|
|
148
|
+
중요: source 커밋에는 내가 만든 코드와 문서만 stage하세요. `state.json`과 `responses/`는 도구가 관리합니다.
|
|
261
149
|
|
|
262
|
-
|
|
150
|
+
여러 줄 커밋 메시지는 `-m` 대신 파일을 사용하세요.
|
|
263
151
|
|
|
264
152
|
```sh
|
|
265
|
-
npm run req:commit -- 2026-001 --run -
|
|
153
|
+
npm run req:commit -- 2026-001 --run --message-file commit-message.txt
|
|
266
154
|
```
|
|
267
155
|
|
|
268
|
-
- 관문(doctor 게이트)을 마지막으로 통과한 뒤 **코드 커밋 + 증거 커밋** 을 남깁니다.
|
|
269
|
-
- 승인되지 않았거나, 승인 후 코드가 바뀌었으면 **여기서 막힙니다.** (그게 CommitGate의 핵심)
|
|
270
|
-
|
|
271
|
-
🎉 끝! 이제 리뷰·승인·증거가 모두 남은 상태로 안전하게 커밋되었습니다.
|
|
272
|
-
|
|
273
156
|
---
|
|
274
157
|
|
|
275
|
-
##
|
|
158
|
+
## 명령어 요약
|
|
276
159
|
|
|
277
|
-
| 명령 |
|
|
160
|
+
| 명령 | 용도 |
|
|
278
161
|
|---|---|
|
|
279
|
-
| `npx commitgate` | 프로젝트에 CommitGate 설치
|
|
280
|
-
| `req:new
|
|
281
|
-
| `req:review-codex
|
|
282
|
-
| `req:review-codex
|
|
283
|
-
| `req:doctor
|
|
284
|
-
| `req:commit
|
|
285
|
-
|
|
286
|
-
> `-m "메시지"` 대신 여러 줄 메시지는 `--message-file 메시지.txt` 로 파일에서 읽을 수 있습니다.
|
|
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"` | 승인된 변경 커밋 |
|
|
287
168
|
|
|
288
169
|
---
|
|
289
170
|
|
|
290
|
-
##
|
|
171
|
+
## 설정
|
|
291
172
|
|
|
292
|
-
프로젝트 루트의 `req.config.json
|
|
173
|
+
대부분은 기본값으로 충분합니다. 필요하면 프로젝트 루트의 `req.config.json`을 수정하세요.
|
|
293
174
|
|
|
294
|
-
| 항목 | 기본값 |
|
|
175
|
+
| 항목 | 기본값 | 설명 |
|
|
295
176
|
|---|---|---|
|
|
296
|
-
| `branchPrefix` | `"feat/req-"` |
|
|
297
|
-
| `ticketRoot` | `"workflow"` | 티켓 폴더
|
|
298
|
-
| `packageManager` | 자동 감지 | `npm
|
|
299
|
-
| `designDocs` | `00
|
|
177
|
+
| `branchPrefix` | `"feat/req-"` | 새 브랜치 prefix |
|
|
178
|
+
| `ticketRoot` | `"workflow"` | REQ 티켓 폴더 |
|
|
179
|
+
| `packageManager` | 자동 감지 | `npm`, `pnpm`, `yarn` |
|
|
180
|
+
| `designDocs` | `00/01/02` 문서 | 설계 문서 파일명 |
|
|
300
181
|
|
|
301
|
-
|
|
182
|
+
빈 `branchPrefix`나 프로젝트 밖으로 나가는 경로는 거부됩니다.
|
|
302
183
|
|
|
303
184
|
---
|
|
304
185
|
|
|
305
|
-
##
|
|
186
|
+
## FAQ
|
|
306
187
|
|
|
307
|
-
**
|
|
308
|
-
|
|
188
|
+
**Codex CLI가 없으면 어떻게 되나요?**
|
|
189
|
+
리뷰 명령이 실패합니다. 조용히 승인 처리하지 않습니다.
|
|
309
190
|
|
|
310
|
-
|
|
311
|
-
|
|
191
|
+
**승인 후 코드를 조금 고치면 커밋되나요?**
|
|
192
|
+
안 됩니다. 승인된 staged tree와 달라지면 stale 승인으로 보고 다시 리뷰를 요구합니다.
|
|
312
193
|
|
|
313
|
-
|
|
314
|
-
|
|
194
|
+
**`state.json`이나 `responses/`는 왜 stage하면 안 되나요?**
|
|
195
|
+
워크플로 증거와 상태 파일입니다. source 커밋에 섞이면 승인 바인딩이 흐려지므로 `req:commit`이 막습니다.
|
|
315
196
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
**Q. Windows인데 커밋 메시지 줄바꿈이 이상해요.**
|
|
320
|
-
A. 여러 줄 메시지는 `-m` 대신 `--message-file 파일.txt` 를 쓰면 깔끔합니다.
|
|
197
|
+
**두 번 설치하면 덮어쓰나요?**
|
|
198
|
+
아니요. 기존 파일은 건너뜁니다. 강제로 갱신하려면 `--force`를 사용하세요.
|
|
321
199
|
|
|
322
200
|
---
|
|
323
201
|
|
|
324
|
-
##
|
|
202
|
+
## 현재 범위
|
|
325
203
|
|
|
326
|
-
|
|
204
|
+
현재 버전은 **Stage A: vendored scaffold 모델**입니다. 즉 `npx commitgate`가 대상 프로젝트에 워크플로 파일을 복사합니다.
|
|
327
205
|
|
|
328
|
-
|
|
329
|
-
- Codex가 설치 안 됨 / 리뷰 실패 → 통과 아님, 명확히 실패
|
|
330
|
-
- 승인된 코드 지문과 지금 코드가 다르면 → 커밋 거부
|
|
331
|
-
- 워킹트리가 지저분하면(리뷰 안 한 변경 섞임) → 리뷰/커밋 거부
|
|
206
|
+
아래는 후속 범위입니다.
|
|
332
207
|
|
|
333
|
-
|
|
208
|
+
- `node_modules`에서 직접 실행하는 라이브러리 모델
|
|
209
|
+
- 비-git VCS 지원
|
|
210
|
+
- 더 다양한 설계문서 템플릿
|
|
211
|
+
- Linux/macOS CI smoke 확대
|
|
334
212
|
|
|
335
213
|
---
|
|
336
214
|
|
|
337
|
-
##
|
|
215
|
+
## License
|
|
338
216
|
|
|
339
217
|
[MIT](./LICENSE) © 2026 sol5288
|
|
340
|
-
|
|
341
|
-
> 이 워크플로는 `palm-kiosk-app`의 REQ-2026-017 portability kit에서 독립 패키지로 추출되었고, **자기 자신을 이 워크플로로 리뷰·승인(dogfood)** 하여 검증되었습니다.
|
package/bin/init.ts
CHANGED
|
@@ -25,6 +25,7 @@ import { resolve, join, dirname, relative } from 'node:path'
|
|
|
25
25
|
import { fileURLToPath, pathToFileURL } from 'node:url'
|
|
26
26
|
import { loadConfig, stripBom, type PackageManager } from '../scripts/req/lib/config'
|
|
27
27
|
import { createGitAdapter } from '../scripts/req/lib/adapters'
|
|
28
|
+
import * as semver from 'semver'
|
|
28
29
|
|
|
29
30
|
/** 이 패키지 루트(bin/ 기준 1단계 위). 복사 원본. */
|
|
30
31
|
const PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')
|
|
@@ -37,10 +38,13 @@ const REQ_SCRIPTS: Record<string, string> = {
|
|
|
37
38
|
'req:commit': 'tsx scripts/req/req-commit.ts',
|
|
38
39
|
}
|
|
39
40
|
|
|
41
|
+
/** cross-spawn 주입 spec(= 보안 하한 SSOT). 진단(#1)과 주입이 이 값을 공유. */
|
|
42
|
+
const CROSS_SPAWN_SPEC = '^7.0.6'
|
|
43
|
+
|
|
40
44
|
/** 대상 package.json에 주입할 devDeps(워크플로 실행 전제). cross-spawn = 복사된 adapters.ts의 안전 spawn(P1) 런타임 의존. */
|
|
41
45
|
const REQ_DEV_DEPS: Record<string, string> = {
|
|
42
46
|
ajv: '^8.20.0',
|
|
43
|
-
'cross-spawn':
|
|
47
|
+
'cross-spawn': CROSS_SPAWN_SPEC,
|
|
44
48
|
tsx: '^4.19.1',
|
|
45
49
|
}
|
|
46
50
|
|
|
@@ -48,6 +52,7 @@ export interface InitOptions {
|
|
|
48
52
|
dir: string
|
|
49
53
|
force: boolean
|
|
50
54
|
dryRun: boolean
|
|
55
|
+
strict: boolean // cross-spawn 하한 미만이면 WARN 대신 throw(#1)
|
|
51
56
|
}
|
|
52
57
|
|
|
53
58
|
export interface InitResult {
|
|
@@ -59,6 +64,7 @@ export interface InitResult {
|
|
|
59
64
|
packageJsonAdded: string[] // 추가된 script/devDep 키
|
|
60
65
|
agentsCreated: boolean
|
|
61
66
|
packageManager: PackageManager
|
|
67
|
+
crossSpawnFloorWarned: boolean // 기존 cross-spawn이 보안 하한 미만이라 경고(#1)
|
|
62
68
|
dryRun: boolean
|
|
63
69
|
}
|
|
64
70
|
|
|
@@ -142,6 +148,92 @@ function parseJsonObject(path: string, label: string): Record<string, unknown> {
|
|
|
142
148
|
return parsed as Record<string, unknown>
|
|
143
149
|
}
|
|
144
150
|
|
|
151
|
+
// ─────────────────────────────── cross-spawn 버전 하한 진단 (#1) ──
|
|
152
|
+
|
|
153
|
+
/** 보안 하한 = 주입 spec의 최소버전(SSOT — 하드코딩 이중화 금지). '^7.0.6' → 7.0.6. */
|
|
154
|
+
const CROSS_SPAWN_FLOOR = semver.minVersion(CROSS_SPAWN_SPEC)
|
|
155
|
+
|
|
156
|
+
/** obj가 plain object일 때 obj[key](문자열). 아니면 undefined. */
|
|
157
|
+
function stringField(obj: unknown, key: string): string | undefined {
|
|
158
|
+
if (obj && typeof obj === 'object' && !Array.isArray(obj)) {
|
|
159
|
+
const v = (obj as Record<string, unknown>)[key]
|
|
160
|
+
if (typeof v === 'string') return v
|
|
161
|
+
}
|
|
162
|
+
return undefined
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** 대상의 기존 cross-spawn spec(devDeps 우선, 없으면 deps). 없으면 null. */
|
|
166
|
+
function existingCrossSpawnSpec(pkg: Record<string, unknown>): string | null {
|
|
167
|
+
return stringField(pkg.devDependencies, 'cross-spawn') ?? stringField(pkg.dependencies, 'cross-spawn') ?? null
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** node_modules에 실제 설치된 cross-spawn 버전(valid semver). 없으면 null. */
|
|
171
|
+
function installedCrossSpawnVersion(targetRoot: string): string | null {
|
|
172
|
+
const p = join(targetRoot, 'node_modules', 'cross-spawn', 'package.json')
|
|
173
|
+
if (!existsSync(p)) return null
|
|
174
|
+
try {
|
|
175
|
+
const v = (JSON.parse(stripBom(readFileSync(p, 'utf8'))) as { version?: unknown }).version
|
|
176
|
+
return typeof v === 'string' && semver.valid(v) ? v : null
|
|
177
|
+
} catch {
|
|
178
|
+
return null
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/** lockfile 해소 cross-spawn 버전(package-lock v2/v3 JSON 우선, pnpm/yarn best-effort). 없으면 null. */
|
|
183
|
+
function lockedCrossSpawnVersion(targetRoot: string): string | null {
|
|
184
|
+
const pl = join(targetRoot, 'package-lock.json')
|
|
185
|
+
if (existsSync(pl)) {
|
|
186
|
+
try {
|
|
187
|
+
const j = JSON.parse(stripBom(readFileSync(pl, 'utf8'))) as {
|
|
188
|
+
packages?: Record<string, { version?: unknown }>
|
|
189
|
+
dependencies?: Record<string, { version?: unknown }>
|
|
190
|
+
}
|
|
191
|
+
const v = j.packages?.['node_modules/cross-spawn']?.version ?? j.dependencies?.['cross-spawn']?.version
|
|
192
|
+
if (typeof v === 'string' && semver.valid(v)) return v
|
|
193
|
+
} catch {
|
|
194
|
+
/* best-effort */
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
for (const [file, re] of [
|
|
198
|
+
['pnpm-lock.yaml', /cross-spawn@(\d+\.\d+\.\d+)/],
|
|
199
|
+
['yarn.lock', /(?:^|\n)"?cross-spawn@[^\n]*:[\s\S]*?\n\s+version:?\s+"?(\d+\.\d+\.\d+)"?/],
|
|
200
|
+
] as const) {
|
|
201
|
+
const fp = join(targetRoot, file)
|
|
202
|
+
if (!existsSync(fp)) continue
|
|
203
|
+
try {
|
|
204
|
+
const m = readFileSync(fp, 'utf8').match(re)
|
|
205
|
+
if (m?.[1] && semver.valid(m[1])) return m[1]
|
|
206
|
+
} catch {
|
|
207
|
+
/* best-effort */
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return null
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* 기존 cross-spawn이 보안 하한 미만인지 판정(#1). 우선순위: **설치버전 → lockfile 해소버전 → range**.
|
|
215
|
+
* range fallback은 `>=floor`로 절대 해소 불가한 spec만 below로 본다(‘^7.0.0’·‘~7.0.1’ 오탐 방지 — R1 P2).
|
|
216
|
+
* 기존 cross-spawn 없으면 null(우리가 `^7.0.6` 주입 → 진단 불필요).
|
|
217
|
+
*/
|
|
218
|
+
export function crossSpawnBelowFloor(
|
|
219
|
+
targetRoot: string,
|
|
220
|
+
pkg: Record<string, unknown>,
|
|
221
|
+
): { below: boolean; detail: string } | null {
|
|
222
|
+
if (!CROSS_SPAWN_FLOOR) return null // 이론상 도달 불가(REQ_DEV_DEPS 고정값)
|
|
223
|
+
const floor = CROSS_SPAWN_FLOOR.version
|
|
224
|
+
const spec = existingCrossSpawnSpec(pkg)
|
|
225
|
+
if (!spec) return null
|
|
226
|
+
|
|
227
|
+
const installed = installedCrossSpawnVersion(targetRoot)
|
|
228
|
+
if (installed) return { below: semver.lt(installed, floor), detail: `설치버전 ${installed}` }
|
|
229
|
+
|
|
230
|
+
const locked = lockedCrossSpawnVersion(targetRoot)
|
|
231
|
+
if (locked) return { below: semver.lt(locked, floor), detail: `lockfile ${locked}` }
|
|
232
|
+
|
|
233
|
+
if (semver.validRange(spec)) return { below: !semver.intersects(spec, `>=${floor}`), detail: `범위 ${spec}` }
|
|
234
|
+
return { below: false, detail: `범위 ${spec}(파싱 불가 — 무경고)` }
|
|
235
|
+
}
|
|
236
|
+
|
|
145
237
|
/**
|
|
146
238
|
* 설치 코어. IO는 여기서만(테스트가 임시 repo로 직접 호출).
|
|
147
239
|
* **Preflight(전 검증·파싱) → Apply(쓰기) 2단계** — malformed 입력에 대해 어떤 파일도 복사·수정하기 전에 실패한다(부분 설치 방지, design R2 P2).
|
|
@@ -161,11 +253,23 @@ export function runInit(opts: InitOptions): InitResult {
|
|
|
161
253
|
scripts?: Record<string, string>
|
|
162
254
|
devDependencies?: Record<string, string>
|
|
163
255
|
}
|
|
164
|
-
// scripts·devDependencies가 존재하면 반드시 plain object — 배열/원시면 patch
|
|
165
|
-
|
|
256
|
+
// scripts·devDependencies·dependencies가 존재하면 반드시 plain object — 배열/원시면 patch 유실(scripts/devDeps, phase R1 P2)
|
|
257
|
+
// 또는 cross-spawn 진단(dependencies, design R1 P3) 오동작. 읽기 전에 shape 검증(fail-closed).
|
|
258
|
+
for (const field of ['scripts', 'devDependencies', 'dependencies'] as const) {
|
|
166
259
|
const v = (pkg as Record<string, unknown>)[field]
|
|
167
260
|
if (v !== undefined && (typeof v !== 'object' || v === null || Array.isArray(v)))
|
|
168
|
-
throw new Error(`package.json의 ${field} 필드가 객체가 아님(${pkgPath}) —
|
|
261
|
+
throw new Error(`package.json의 ${field} 필드가 객체가 아님(${pkgPath}) — 배열/원시 미지원.`)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// cross-spawn 보안 하한 진단(#1): 기존 cross-spawn이 하한 미만이면 WARN(기본)/throw(--strict). preflight라 strict throw 시 부분 설치 없음.
|
|
265
|
+
let crossSpawnFloorWarned = false
|
|
266
|
+
const floorCheck = crossSpawnBelowFloor(targetRoot, pkg as Record<string, unknown>)
|
|
267
|
+
if (floorCheck?.below) {
|
|
268
|
+
const spec = CROSS_SPAWN_SPEC
|
|
269
|
+
const msg = `기존 cross-spawn(${floorCheck.detail})이 보안 하한 >=${CROSS_SPAWN_FLOOR?.version} 미만 — CommitGate 안전 경계(safeSpawnSync)는 ${spec} 검증분입니다. 'npm i -D cross-spawn@${spec}' 권장.`
|
|
270
|
+
if (opts.strict) throw new Error(`[--strict] ${msg}`)
|
|
271
|
+
console.warn(`⚠️ ${msg} (설치는 계속 — 강제 중단하려면 --strict)`)
|
|
272
|
+
crossSpawnFloorWarned = true
|
|
169
273
|
}
|
|
170
274
|
|
|
171
275
|
const cfgPath = join(targetRoot, 'req.config.json')
|
|
@@ -247,6 +351,7 @@ export function runInit(opts: InitOptions): InitResult {
|
|
|
247
351
|
packageJsonAdded,
|
|
248
352
|
agentsCreated,
|
|
249
353
|
packageManager,
|
|
354
|
+
crossSpawnFloorWarned,
|
|
250
355
|
dryRun: opts.dryRun,
|
|
251
356
|
}
|
|
252
357
|
}
|
|
@@ -255,6 +360,7 @@ export function parseArgs(argv: string[]): InitOptions {
|
|
|
255
360
|
let dir = process.cwd()
|
|
256
361
|
let force = false
|
|
257
362
|
let dryRun = false
|
|
363
|
+
let strict = false
|
|
258
364
|
for (let i = 0; i < argv.length; i++) {
|
|
259
365
|
const a = argv[i]
|
|
260
366
|
if (a === '--dir') {
|
|
@@ -266,6 +372,8 @@ export function parseArgs(argv: string[]): InitOptions {
|
|
|
266
372
|
force = true
|
|
267
373
|
} else if (a === '--dry-run') {
|
|
268
374
|
dryRun = true
|
|
375
|
+
} else if (a === '--strict') {
|
|
376
|
+
strict = true
|
|
269
377
|
} else if (a === '-h' || a === '--help') {
|
|
270
378
|
printHelp()
|
|
271
379
|
process.exit(0)
|
|
@@ -273,7 +381,7 @@ export function parseArgs(argv: string[]): InitOptions {
|
|
|
273
381
|
throw new Error(`알 수 없는 인자: ${a}`)
|
|
274
382
|
}
|
|
275
383
|
}
|
|
276
|
-
return { dir: resolve(dir), force, dryRun }
|
|
384
|
+
return { dir: resolve(dir), force, dryRun, strict }
|
|
277
385
|
}
|
|
278
386
|
|
|
279
387
|
function printHelp(): void {
|
|
@@ -286,6 +394,7 @@ function printHelp(): void {
|
|
|
286
394
|
--dir <path> 대상 repo 루트(기본: 현재 디렉터리)
|
|
287
395
|
--force 기존 kit 파일 덮어쓰기(기본: 스킵)
|
|
288
396
|
--dry-run 변경 없이 수행 예정 목록만 출력
|
|
397
|
+
--strict 기존 cross-spawn이 보안 하한(>=7.0.6) 미만이면 경고 대신 중단(fail-closed)
|
|
289
398
|
-h, --help 도움말
|
|
290
399
|
|
|
291
400
|
설치 후:
|
|
@@ -315,6 +424,7 @@ export function main(argv: string[]): void {
|
|
|
315
424
|
`${tag} package.json: ${r.packageJsonAdded.length > 0 ? '추가 ' + r.packageJsonAdded.join(', ') : '변경 없음'}`,
|
|
316
425
|
)
|
|
317
426
|
console.log(`${tag} AGENTS.md: ${r.agentsCreated ? '템플릿 생성' : '이미 존재(유지)'}`)
|
|
427
|
+
if (r.crossSpawnFloorWarned) console.log(`${tag} ⚠️ cross-spawn 버전 하한 경고(위 참조) — 강제 중단은 --strict`)
|
|
318
428
|
if (!r.dryRun) {
|
|
319
429
|
console.log(`\n다음:`)
|
|
320
430
|
console.log(` 1. cd ${r.targetRoot} && ${r.packageManager} install`)
|
package/package.json
CHANGED
|
@@ -1,63 +1,66 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "commitgate",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "CommitGate — Builder↔Reviewer(Claude↔Codex) fail-closed 커밋 게이트: 리뷰·승인·증거 없인 커밋을 통과시키지 않는 AI REQ 워크플로 kit (req:new/review-codex/doctor/commit)",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"license": "MIT",
|
|
7
|
-
"author": "sol5288",
|
|
8
|
-
"repository": {
|
|
9
|
-
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/sol5288/commitgate.git"
|
|
11
|
-
},
|
|
12
|
-
"homepage": "https://github.com/sol5288/commitgate#readme",
|
|
13
|
-
"bugs": {
|
|
14
|
-
"url": "https://github.com/sol5288/commitgate/issues"
|
|
15
|
-
},
|
|
16
|
-
"keywords": [
|
|
17
|
-
"ai",
|
|
18
|
-
"code-review",
|
|
19
|
-
"workflow",
|
|
20
|
-
"codex",
|
|
21
|
-
"claude",
|
|
22
|
-
"git",
|
|
23
|
-
"commit-gate",
|
|
24
|
-
"fail-closed",
|
|
25
|
-
"review-gate",
|
|
26
|
-
"cli"
|
|
27
|
-
],
|
|
28
|
-
"bin": {
|
|
29
|
-
"commitgate": "bin/commitgate.mjs"
|
|
30
|
-
},
|
|
31
|
-
"scripts": {
|
|
32
|
-
"req:new": "tsx scripts/req/req-new.ts",
|
|
33
|
-
"req:review-codex": "tsx scripts/req/review-codex.ts",
|
|
34
|
-
"req:doctor": "tsx scripts/req/req-doctor.ts",
|
|
35
|
-
"req:commit": "tsx scripts/req/req-commit.ts",
|
|
36
|
-
"test": "vitest run",
|
|
37
|
-
"typecheck": "tsc --noEmit"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
"workflow/
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"README.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
|
|
63
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "commitgate",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "CommitGate — Builder↔Reviewer(Claude↔Codex) fail-closed 커밋 게이트: 리뷰·승인·증거 없인 커밋을 통과시키지 않는 AI REQ 워크플로 kit (req:new/review-codex/doctor/commit)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "sol5288",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/sol5288/commitgate.git"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/sol5288/commitgate#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/sol5288/commitgate/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"ai",
|
|
18
|
+
"code-review",
|
|
19
|
+
"workflow",
|
|
20
|
+
"codex",
|
|
21
|
+
"claude",
|
|
22
|
+
"git",
|
|
23
|
+
"commit-gate",
|
|
24
|
+
"fail-closed",
|
|
25
|
+
"review-gate",
|
|
26
|
+
"cli"
|
|
27
|
+
],
|
|
28
|
+
"bin": {
|
|
29
|
+
"commitgate": "bin/commitgate.mjs"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"req:new": "tsx scripts/req/req-new.ts",
|
|
33
|
+
"req:review-codex": "tsx scripts/req/review-codex.ts",
|
|
34
|
+
"req:doctor": "tsx scripts/req/req-doctor.ts",
|
|
35
|
+
"req:commit": "tsx scripts/req/req-commit.ts",
|
|
36
|
+
"test": "vitest run",
|
|
37
|
+
"typecheck": "tsc --noEmit",
|
|
38
|
+
"smoke": "node scripts/smoke.mjs"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"scripts/req",
|
|
42
|
+
"workflow/machine.schema.json",
|
|
43
|
+
"workflow/req.config.schema.json",
|
|
44
|
+
"bin",
|
|
45
|
+
"AGENTS.template.md",
|
|
46
|
+
"req.config.json.sample",
|
|
47
|
+
"README.md",
|
|
48
|
+
"README.en.md"
|
|
49
|
+
],
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=18.17"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"ajv": "^8.20.0",
|
|
55
|
+
"cross-spawn": "^7.0.6",
|
|
56
|
+
"semver": "^7.6.3",
|
|
57
|
+
"tsx": "^4.19.1"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@types/cross-spawn": "^6.0.6",
|
|
61
|
+
"@types/node": "^22.7.4",
|
|
62
|
+
"@types/semver": "^7.5.8",
|
|
63
|
+
"typescript": "^5.6.2",
|
|
64
|
+
"vitest": "^2.1.2"
|
|
65
|
+
}
|
|
66
|
+
}
|