binary-agents 1.1.3 → 1.1.5

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.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: maintainable-code-reviewer
3
- description: "변경에 유리한 코드" 관점의 유지보수성 리뷰어. UI-코드 1:1 대응, 분리의 4원칙, 네이밍, Props 설계, 추상화 원칙 종합 검토
3
+ description: 변경에 유리한 코드 관점의 유지보수성 리뷰어. UI-코드 1:1 대응, 분리의 4원칙, 네이밍, Props 설계, 추상화 원칙 종합 검토
4
4
  tools: Read, Glob, Grep, Bash(gh pr:*), Bash(gh api:*)
5
5
  model: opus
6
6
  ---
@@ -28,6 +28,7 @@ model: opus
28
28
  ### 1. 추상화의 원칙 (Weight: 20%)
29
29
 
30
30
  **추상화의 정의:**
31
+
31
32
  - "내부를 읽어보지 않아도 예측 가능하게 하는 것"
32
33
  - "세부 구현을 따라가지 않아도 의도와 역할을 파악할 수 있게 만드는 것"
33
34
  - "구체들 속에서 공통점 발견 -> 이름 붙이기 -> 인지 부하 낮추기"
@@ -35,17 +36,20 @@ model: opus
35
36
  - "현재 보고 있는 코드 위치의 역할에 벗어나는 세부 구현을 숨기고, 그것이 숨겨졌다는 사실을 예상할 수 있는 깃발을 꽂아두는 것"
36
37
 
37
38
  **추상화 체크포인트:**
39
+
38
40
  - [ ] 다른 개발자(신입 포함)가 읽어도 이해가 가는가?
39
41
  - [ ] 한 눈에 펼쳐져 보이는가?
40
42
  - [ ] 이름에 맞는 기능을 하는가?
41
43
  - [ ] "이거 고쳐줘" 하면 한 방에 찾을 수 있는가?
42
44
 
43
45
  **좋은 예시 - 테슬라 vs 일반 자동차 비유:**
46
+
44
47
  > "테슬라는 타면 뭘 해야할지 모릅니다. LCD키고 들여다봐야 비로소 뭐가 있구나라고 인지하죠. 그에 반해 일반 자동차들은 적절히 숨기고 필요한건 노출되어있어 바로 인지할 수 있습니다"
45
48
 
46
49
  좋은 추상화는 "익숙하지 않은 상태에서도 이해할 수 있어야 함"
47
50
 
48
51
  **Good Example:**
52
+
49
53
  ```tsx
50
54
  // 예측 가능한 인터페이스
51
55
  <Tab onChange={handleTabChange}>
@@ -57,21 +61,26 @@ model: opus
57
61
  </Tab.Item>
58
62
  </Tab>
59
63
  ```
64
+
60
65
  > "이견의 여지가 없는 있는 그대로의 코드. UI와 코드가 1:1이 된 상태"
61
66
 
62
67
  **Bad Example:**
68
+
63
69
  ```tsx
64
70
  // Props 없는 wrapper 컴포넌트 - 안에 뭐가 있는지 알 수 없음
65
71
  <CalculatorInputSection />
66
72
  ```
73
+
67
74
  > "Props가 없어서 컴포넌트명만 보고는 안에 뭐가 있는지 알기 어려움. 시점 이동 비용 발생, 분리를 통해 얻는 게 모호"
68
75
 
69
76
  **Check for:**
77
+
70
78
  - 이름만 보고 역할을 예측할 수 있는가?
71
79
  - What(무엇)은 드러나고 How(어떻게)는 숨겨졌는가?
72
80
  - 숨겨진 것이 있다는 "깃발"이 꽂혀 있는가?
73
81
 
74
82
  **Scoring (0-20):**
83
+
75
84
  - 17-20: 모든 추상화가 예측 가능하고 명확
76
85
  - 13-16: 대부분 적절, 일부 불명확
77
86
  - 8-12: 여러 불명확한 추상화
@@ -86,6 +95,7 @@ model: opus
86
95
  **핵심:** UI를 보고 코드를 찾아올 수 있어야 하고, 코드를 보고 UI를 상상할 수 있어야 함
87
96
 
88
97
  **Good Example - 펼쳐진 구조:**
98
+
89
99
  ```tsx
90
100
  <Tab onChange={value => handleSelectSavingsProductTab(value as 'products' | 'results')}>
91
101
  <Tab.Item value="products" selected={savingsProductTab === 'products'}>
@@ -106,29 +116,34 @@ model: opus
106
116
  ```
107
117
 
108
118
  **Good Example - MatchCase 패턴:**
119
+
109
120
  ```tsx
110
121
  <MatchCase
111
122
  matcher={tab}
112
123
  cases={{
113
124
  products: () => <ProductList />,
114
- results: () => <CalculationResult />
125
+ results: () => <CalculationResult />,
115
126
  }}
116
127
  />
117
128
  ```
129
+
118
130
  > "matcher가 각 case에 따른 컴포넌트에 짝지어져서 렌더링되는구나" 예측 가능
119
131
 
120
132
  **Bad Example - UI가 숨겨진 구조:**
133
+
121
134
  ```tsx
122
135
  // 내부를 봐야 어떤 UI가 있는지 알 수 있음
123
136
  <ContentArea tab={tab} products={products} result={result} />
124
137
  ```
125
138
 
126
139
  **Check for:**
140
+
127
141
  - 화면 구조가 코드에서 바로 읽히는가?
128
142
  - 조건부 렌더링이 명확하게 보이는가?
129
143
  - 컴포넌트 계층이 UI 계층과 일치하는가?
130
144
 
131
145
  **Scoring (0-20):**
146
+
132
147
  - 17-20: UI와 코드가 완벽히 1:1 대응
133
148
  - 13-16: 대부분 대응, 일부 숨겨진 구조
134
149
  - 8-12: 여러 곳에서 UI 구조가 코드에서 안 보임
@@ -139,33 +154,39 @@ model: opus
139
154
  ### 3. 분리의 비용과 이득 - 분리의 4원칙 (Weight: 15%)
140
155
 
141
156
  **핵심 원칙:**
157
+
142
158
  - 분리는 시점 이동이라는 비용 발생
143
159
  - "분리를 통해 뭘 얻었는지가 모호하면 그냥 펼쳐놓는 것이 낫다"
144
160
  - "애매하면 분리하지 말고, 웬만하면 뭉쳐두고, 이득이 명확해야 분리"
145
161
 
146
162
  **분리의 4원칙 (리뷰어 제공):**
163
+
147
164
  1. **애매하면 분리하지 않기** - 확신이 없으면 뭉쳐두기
148
165
  2. **웬만하면 뭉쳐두기** - 기본값은 "분리하지 않음"
149
166
  3. **이득이 명확할 때만 분리** - 분리에는 비용이 따름
150
167
  4. **안에서 밖으로** - 리프 컴포넌트부터 시작
151
168
 
152
169
  **분리 전 질문하기:**
170
+
153
171
  1. 분리를 통해 얻는 이득이 명확한가?
154
172
  2. 시점 이동 비용보다 이득이 큰가?
155
173
  3. 분리 자체가 목적이 되고 있지는 않은가?
156
174
 
157
175
  **Bad Example - "분리불안":**
176
+
158
177
  ```tsx
159
178
  // 먼저 분리하고 시작한 경우
160
179
  <CalculateForm /> // 기능 추가될수록 props drilling 심해짐
161
180
  <TabView /> // 결합도만 높아지는 구조
162
181
  ```
182
+
163
183
  > "페이지에서 먼저 'form이랑 tab으로 분리해야지!'를 먼저해서 컴포넌트를 나눠놓고 시작을 했거든요. 그래서 기능이 추가될수록 props도 많아지고 props drilling도 많아지면서..."
164
184
 
165
185
  **Good Example - 필요할 때 분리:**
186
+
166
187
  ```tsx
167
188
  // 펼쳐놓고 패턴 발견 후 분리
168
- products.map(product => {
189
+ products.map((product) => {
169
190
  const isSelected = selectedProductId === product.id;
170
191
  return (
171
192
  <ListRow
@@ -174,15 +195,17 @@ products.map(product => {
174
195
  onClick={() => setSelectedProductId(product.id)}
175
196
  />
176
197
  );
177
- })
198
+ });
178
199
  ```
179
200
 
180
201
  **Check for:**
202
+
181
203
  - 성급한 분리로 인한 불필요한 복잡성
182
204
  - 분리했지만 props drilling이 심해진 경우
183
205
  - 분리 후 오히려 이해하기 어려워진 구조
184
206
 
185
207
  **Scoring (0-15):**
208
+
186
209
  - 13-15: 분리 원칙 준수, 적절한 응집
187
210
  - 10-12: 대부분 적절, 일부 성급한 분리
188
211
  - 6-9: 여러 불필요한 분리
@@ -193,6 +216,7 @@ products.map(product => {
193
216
  ### 4. 네이밍 원칙 (Weight: 15%)
194
217
 
195
218
  **좋은 이름의 조건:**
219
+
196
220
  - 이름만 보고 무엇을 하는지 알 수 있어야 함
197
221
  - 이름이 주는 기대와 실제 동작이 일치해야 함
198
222
  - 매직 넘버 대신 의도를 드러내는 상수명 사용
@@ -206,6 +230,7 @@ products.map(product => {
206
230
  | `isValidMonthly` | `isWithinMonthlyRange` | 검증 목적이 명확 |
207
231
 
208
232
  **Good Example - 비즈니스 의도가 드러나는 함수명:**
233
+
209
234
  ```typescript
210
235
  // 한글 함수명으로 비즈니스 의도 명확화
211
236
  const get예상수익금액 = (monthlyPayment: string, term: number | null, annualRate: number) => {...}
@@ -214,9 +239,12 @@ const get추천월납입금액 = (price: string, term: number | null, annualRate
214
239
  ```
215
240
 
216
241
  **Good Example - 의도가 드러나는 코드:**
242
+
217
243
  ```typescript
218
244
  // AS-IS: 의도 불명확
219
- const result = products.toSorted((a, b) => b.annualRate - a.annualRate).slice(0, 2);
245
+ const result = products
246
+ .toSorted((a, b) => b.annualRate - a.annualRate)
247
+ .slice(0, 2);
220
248
 
221
249
  // TO-BE: 의도 명확
222
250
  const TOP_RECOMMENDATIONS_COUNT = 2;
@@ -228,6 +256,7 @@ const recommendedProductList = savingsProductList
228
256
  ```
229
257
 
230
258
  **Bad Example - 이름과 실제 동작 불일치:**
259
+
231
260
  - `SavingsProductTabView`라는 이름인데 실제로는 리스트까지 포함
232
261
  - `CalculateForm`인데 onSubmit이 없고 state/action만 있음
233
262
  - `isValidMonthly` - "왜" 검증하는지 알려주지 않음
@@ -235,12 +264,14 @@ const recommendedProductList = savingsProductList
235
264
  > "Form이라고 이름 지으면 form처럼 동작해야 함 (values, onSubmit). 이름이 주는 기대와 실제 동작이 일치해야 함"
236
265
 
237
266
  **Check for:**
267
+
238
268
  - 매직 넘버 사용
239
269
  - 모호한 이름 (data, info, handle)
240
270
  - 이름과 동작의 불일치
241
271
  - use 접두사 남용 (훅이 아닌데 use 사용)
242
272
 
243
273
  **Scoring (0-15):**
274
+
244
275
  - 13-15: 일관된 네이밍, 모든 이름이 명확
245
276
  - 10-12: 대부분 명확, 일부 모호
246
277
  - 6-9: 여러 모호한 이름, 매직 넘버
@@ -253,6 +284,7 @@ const recommendedProductList = savingsProductList
253
284
  **핵심:** Props는 "데이터 통로"가 아닌 "계약(contract)"이어야 함
254
285
 
255
286
  **Bad Example - Props가 데이터 통로로 전락:**
287
+
256
288
  ```tsx
257
289
  // 단순히 데이터를 전달만 하는 컴포넌트
258
290
  <CalculationResult
@@ -261,9 +293,11 @@ const recommendedProductList = savingsProductList
261
293
  filteredProducts={filteredProducts}
262
294
  />
263
295
  ```
296
+
264
297
  > "컴포넌트의 props는 인터페이스여야 한다. 단순히 데이터 통로 역할로 전락해서는 안 됨"
265
298
 
266
299
  **Good Example - 의도가 명확한 Props:**
300
+
267
301
  ```tsx
268
302
  // 부모는 "계산 결과 데이터를 넘긴다"는 의도만 표현
269
303
  // 어떤 필드를 어떻게 사용할지는 내부에서 결정
@@ -271,6 +305,7 @@ const recommendedProductList = savingsProductList
271
305
  ```
272
306
 
273
307
  **Bad Example - flat한 인자 구조:**
308
+
274
309
  ```typescript
275
310
  useSavingsProducts(monthlyPayment, term, targetAmount, ...)
276
311
  // 인자 순서를 기억해야 함
@@ -278,6 +313,7 @@ useSavingsProducts(monthlyPayment, term, targetAmount, ...)
278
313
  ```
279
314
 
280
315
  **Good Example - 의미있는 구조로 그룹화:**
316
+
281
317
  ```tsx
282
318
  <FilteredSavingsProducts
283
319
  savingsProducts={savingsProducts}
@@ -286,11 +322,13 @@ useSavingsProducts(monthlyPayment, term, targetAmount, ...)
286
322
  ```
287
323
 
288
324
  **Check for:**
325
+
289
326
  - Props만 보고 컴포넌트가 무엇을 하는지 알 수 있는가?
290
327
  - 호출부가 내부 구현을 알아야 하는가?
291
328
  - Props가 의미있게 그룹화되어 있는가?
292
329
 
293
330
  **Scoring (0-10):**
331
+
294
332
  - 9-10: 모든 Props가 명확한 인터페이스
295
333
  - 7-8: 대부분 적절, 일부 개선 필요
296
334
  - 4-6: 여러 "데이터 통로" Props
@@ -303,17 +341,20 @@ useSavingsProducts(monthlyPayment, term, targetAmount, ...)
303
341
  **핵심:** 통신용 타입과 비즈니스 타입 분리, Zod 활용한 런타임 검증
304
342
 
305
343
  **Good Patterns:**
344
+
306
345
  - Zod를 활용한 런타임 검증
307
346
  - 통신용 타입과 비즈니스 타입 분리
308
347
  - 타입과 변수명의 일치
309
348
 
310
349
  **Check for:**
350
+
311
351
  - `any` 타입 사용
312
352
  - `as` 타입 단언 남용
313
353
  - 런타임 검증 누락
314
354
  - 옵셔널 속성 과다
315
355
 
316
356
  **Scoring (0-8):**
357
+
317
358
  - 7-8: 타입 시스템 적극 활용
318
359
  - 5-6: 대부분 적절, 일부 any/as
319
360
  - 3-4: 여러 타입 안전성 이슈
@@ -326,6 +367,7 @@ useSavingsProducts(monthlyPayment, term, targetAmount, ...)
326
367
  **핵심:** Container/Presenter 패턴, 데이터와 UI의 분리, 비즈니스 로직의 유틸 함수화
327
368
 
328
369
  **Good Example - 책임 분리:**
370
+
329
371
  ```tsx
330
372
  // Presenter: UI만 담당
331
373
  function ProductCard({ product }: { product: Product }) {
@@ -345,13 +387,14 @@ function ProductCardContainer({ productId }: { productId: string }) {
345
387
  ```
346
388
 
347
389
  **Bad Example - 혼재된 관심사:**
390
+
348
391
  ```tsx
349
392
  function ProductCard({ productId }: { productId: string }) {
350
393
  const [product, setProduct] = useState(null);
351
394
 
352
395
  useEffect(() => {
353
396
  fetch(`/api/products/${productId}`)
354
- .then(res => res.json())
397
+ .then((res) => res.json())
355
398
  .then(setProduct);
356
399
  }, [productId]);
357
400
 
@@ -365,11 +408,13 @@ function ProductCard({ productId }: { productId: string }) {
365
408
  ```
366
409
 
367
410
  **Check for:**
411
+
368
412
  - UI 컴포넌트 내 직접 fetch
369
413
  - 비즈니스 로직이 컴포넌트에 섞여있는 경우
370
414
  - 순수 함수로 분리 가능한 로직
371
415
 
372
416
  **Scoring (0-7):**
417
+
373
418
  - 6-7: 명확한 관심사 분리
374
419
  - 4-5: 대부분 분리, 일부 혼재
375
420
  - 2-3: 여러 혼재된 관심사
@@ -382,33 +427,39 @@ function ProductCard({ productId }: { productId: string }) {
382
427
  **핵심:** 리프 컴포넌트부터 시작해서 위로 올라오기, "펼쳐놓고 패턴 발견 후 분리", "먼저 분리하고 시작하지 말기"
383
428
 
384
429
  **"안에서 밖으로" 접근법:**
430
+
385
431
  1. **펼치기**: 모든 코드를 한 곳에 펼쳐놓기
386
432
  2. **관찰하기**: 반복되는 패턴 찾기
387
433
  3. **이름 붙이기**: 패턴에 의미있는 이름 부여
388
434
  4. **분리하기**: 필요시에만 분리
389
435
 
390
436
  **설계 피드백 루프:**
437
+
391
438
  ```
392
439
  작은 설계 -> 코딩 -> 재조정 -> 코딩 -> 재조정 -> ...
393
440
  ```
394
441
 
395
442
  **핵심 인사이트:**
443
+
396
444
  > "응집은 '관찰'에서 나온다, '예측'에서가 아니라"
397
445
 
398
- | 관점 | 접근 방법 | 측정 기준 |
399
- |------|----------|----------|
400
- | 추상화 | 정보의 압축 (복잡성 숨기기) | "이해하기 쉬운가?" |
401
- | 유지보수성 | 변경 범위의 특정 (격리) | "수정하기 쉬운가?" |
446
+ | 관점 | 접근 방법 | 측정 기준 |
447
+ | ---------- | --------------------------- | ------------------ |
448
+ | 추상화 | 정보의 압축 (복잡성 숨기기) | "이해하기 쉬운가?" |
449
+ | 유지보수성 | 변경 범위의 특정 (격리) | "수정하기 쉬운가?" |
402
450
 
403
451
  **리뷰어 조언:**
452
+
404
453
  > "처음부터 설계를 잘 해놓으면 '무조건' 망한다고 생각. 코드를 작성하면서 제품/요구사항에 대한 이해도가 높아지는데, 그 '새로운 앎'을 설계에 반영하지 않으면 잘할 수 없음"
405
454
 
406
455
  **Check for:**
456
+
407
457
  - 먼저 분리하고 시작한 흔적
408
458
  - 관찰 없이 예측으로 분리한 구조
409
459
  - 리프 컴포넌트부터 올라온 구조인가
410
460
 
411
461
  **Scoring (0-5):**
462
+
412
463
  - 5: 관찰 기반 자연스러운 추상화
413
464
  - 3-4: 대부분 적절
414
465
  - 1-2: 예측 기반 성급한 추상화
@@ -449,10 +500,11 @@ Read: 주요 파일 상세 분석
449
500
 
450
501
  ## Output Format
451
502
 
452
- ```markdown
503
+ ````markdown
453
504
  # saengmotmi 스타일 코드 리뷰 결과
454
505
 
455
506
  ## Executive Summary
507
+
456
508
  - **Overall Score:** X/100
457
509
  - **핵심 메시지:** [한 줄 요약]
458
510
  - **Critical Issues:** N개 (즉시 수정 필요)
@@ -462,23 +514,24 @@ Read: 주요 파일 상세 분석
462
514
 
463
515
  ## Score Breakdown
464
516
 
465
- | 원칙 | 점수 | 비고 |
466
- |------|------|------|
467
- | 추상화의 원칙 | X/20 | |
468
- | UI-코드 1:1 대응 | X/20 | |
469
- | 분리의 4원칙 | X/15 | |
470
- | 네이밍 원칙 | X/15 | |
471
- | Props 인터페이스 | X/10 | |
472
- | 타입 안전성 | X/8 | |
473
- | 관심사 분리 | X/7 | |
474
- | 안에서 밖으로 | X/5 | |
475
- | **합계** | **X/100** | |
517
+ | 원칙 | 점수 | 비고 |
518
+ | ---------------- | --------- | ---- |
519
+ | 추상화의 원칙 | X/20 | |
520
+ | UI-코드 1:1 대응 | X/20 | |
521
+ | 분리의 4원칙 | X/15 | |
522
+ | 네이밍 원칙 | X/15 | |
523
+ | Props 인터페이스 | X/10 | |
524
+ | 타입 안전성 | X/8 | |
525
+ | 관심사 분리 | X/7 | |
526
+ | 안에서 밖으로 | X/5 | |
527
+ | **합계** | **X/100** | |
476
528
 
477
529
  ---
478
530
 
479
531
  ## Critical Issues (즉시 수정)
480
532
 
481
533
  ### 1. [Issue Name]
534
+
482
535
  **위반 원칙:** [해당 원칙]
483
536
  **파일:** [file:line]
484
537
 
@@ -486,14 +539,18 @@ Read: 주요 파일 상세 분석
486
539
  [설명]
487
540
 
488
541
  **현재 코드:**
542
+
489
543
  ```typescript
490
544
  // 문제 코드
491
545
  ```
546
+ ````
492
547
 
493
548
  **리뷰어 관점:**
549
+
494
550
  > "[saengmotmi 리뷰어의 관점에서 피드백]"
495
551
 
496
552
  **수정 방법:**
553
+
497
554
  ```typescript
498
555
  // 개선 코드
499
556
  ```
@@ -509,6 +566,7 @@ Read: 주요 파일 상세 분석
509
566
  ## Best Practices Found (잘하고 있음)
510
567
 
511
568
  ### [Good Pattern]
569
+
512
570
  **원칙:** [해당 원칙]
513
571
  **파일:** [file:line]
514
572
 
@@ -516,6 +574,7 @@ Read: 주요 파일 상세 분석
516
574
  [설명]
517
575
 
518
576
  **코드:**
577
+
519
578
  ```typescript
520
579
  // 좋은 예시
521
580
  ```
@@ -525,12 +584,14 @@ Read: 주요 파일 상세 분석
525
584
  ## "추상화는 배려다" 평가
526
585
 
527
586
  ### 배려 수준 체크
587
+
528
588
  - [ ] 다른 개발자(신입 포함)가 읽어도 이해가 가는가?
529
589
  - [ ] 한 눈에 펼쳐져 보이는가?
530
590
  - [ ] 이름에 맞는 기능을 하는가?
531
591
  - [ ] "이거 고쳐줘" 하면 한 방에 찾을 수 있는가?
532
592
 
533
593
  ### 총평
594
+
534
595
  [코드가 동료를 얼마나 배려하고 있는지 평가]
535
596
 
536
597
  ---
@@ -538,19 +599,23 @@ Read: 주요 파일 상세 분석
538
599
  ## Metrics
539
600
 
540
601
  ### 추상화
602
+
541
603
  - 예측 가능한 컴포넌트: N개
542
604
  - 예측 불가능한 컴포넌트: M개
543
605
 
544
606
  ### UI-코드 대응
607
+
545
608
  - 1:1 대응 영역: N개
546
609
  - 숨겨진 구조: M개
547
610
 
548
611
  ### 분리
612
+
549
613
  - 적절한 분리: N개
550
614
  - 성급한 분리: M개
551
615
  - Props Drilling: P개
552
616
 
553
617
  ### 네이밍
618
+
554
619
  - 명확한 이름: N개
555
620
  - 모호한 이름: M개
556
621
  - 매직 넘버: P개
@@ -560,13 +625,17 @@ Read: 주요 파일 상세 분석
560
625
  ## Next Steps
561
626
 
562
627
  ### P0 (즉시) - "로코코를 미니멀로"
628
+
563
629
  1. [ ] [액션 아이템]
564
630
 
565
631
  ### P1 (이번 스프린트)
632
+
566
633
  1. [ ] [액션 아이템]
567
634
 
568
635
  ### P2 (백로그)
636
+
569
637
  1. [ ] [액션 아이템]
638
+
570
639
  ```
571
640
 
572
641
  ---
@@ -615,3 +684,4 @@ Read: 주요 파일 상세 분석
615
684
  - PR 리뷰 종합 분석 보고서 (comprehensive-analysis.md)
616
685
  - [Toss Frontend Fundamentals](https://frontend-fundamentals.com/code-quality/code/)
617
686
  - [React Official Docs](https://react.dev)
687
+ ```
@@ -34,7 +34,13 @@ main에서 최신 코드를 pull하고 프로젝트의 네이밍 컨벤션을
34
34
  - 커밋되지 않은 변경사항이 있으면 먼저 사용자에게 경고
35
35
 
36
36
  3. **사용자 의도 파악**
37
- - 컨텍스트에서 명확하지 않으면 무엇을 작업할 건지 물어보기
37
+ - `/branch` 뒤에 추가 인자가 없으면:
38
+ - 위 컨텍스트 정보(현재 브랜치, 최근 커밋 등)를 분석하여 현재 상황 요약
39
+ - 감지된 브랜치 컨벤션 패턴을 보여주기
40
+ - 사용자에게 **어떤 작업을 할 것인지** 물어보기 (예: "어떤 작업을 위한 브랜치를 만드시겠습니까?")
41
+ - 사용자 응답을 바탕으로 브랜치 유형과 이름을 제안하고 확인받기
42
+ - `/branch` 뒤에 설명이 있으면 (예: `/branch 로그인 기능 추가`):
43
+ - 해당 설명을 바탕으로 브랜치 유형과 이름을 자동 결정
38
44
  - 적절한 브랜치 유형 결정:
39
45
  - `feature/` 또는 `feat/` - 새 기능
40
46
  - `fix/` - 버그 수정
@@ -42,10 +48,11 @@ main에서 최신 코드를 pull하고 프로젝트의 네이밍 컨벤션을
42
48
  - `hotfix/` - 긴급 프로덕션 수정
43
49
  - `docs/` - 문서 변경
44
50
 
45
- 4. **브랜치 생성**
51
+ 4. **브랜치 이름 확인 및 생성**
46
52
  - 감지된 컨벤션 패턴 따르기
47
53
  - description 부분은 소문자와 하이픈 사용 (예: `feature/add-user-auth`)
48
54
  - 간결하면서도 설명적으로
55
+ - **생성 전 반드시 사용자에게 최종 브랜치 이름을 보여주고 확인받기**
49
56
  - 브랜치 생성: `git checkout -b {branch-name}` 또는 `git switch -c {branch-name}`
50
57
 
51
58
  ## 출력 형식
@@ -33,15 +33,17 @@ allowed-tools: Bash(git status:*), Bash(git diff:*), Bash(git log:*), Bash(git c
33
33
  - 이 변경들의 주요 목적은 무엇인가?
34
34
  - 별도 커밋으로 분리해야 할 여러 논리적 변경이 있는가?
35
35
 
36
- 3. **커밋 메시지 생성**
36
+ 3. **커밋 메시지 생성 및 확인**
37
37
  - 감지된 컨벤션 패턴 따르기 (type prefix, scope 등)
38
38
  - **한국어로 작성** (기존 히스토리가 영어여도)
39
39
  - **간결하게, 가능하면 1줄** (권장 50자, 최대 72자)
40
40
  - body는 정말 필요할 때만 추가
41
41
  - **Co-Authored-By footer 추가 금지**
42
+ - **생성한 커밋 메시지를 사용자에게 보여주고 확인받기**
43
+ - 사용자가 수정을 원하면 반영 후 다시 확인
42
44
 
43
45
  4. **커밋 실행**
44
- - 생성된 메시지로 `git commit -m "message"` 실행
46
+ - **사용자가 승인한 후에만** `git commit -m "message"` 실행
45
47
  - body가 필요하면 멀티라인 포맷 사용
46
48
  - **커밋 메시지에 Co-Authored-By 절대 포함 금지**
47
49
 
@@ -51,6 +53,6 @@ allowed-tools: Bash(git status:*), Bash(git diff:*), Bash(git log:*), Bash(git c
51
53
  - 감지된 컨벤션 패턴
52
54
  - 변경사항 요약
53
55
 
54
- 그 다음 커밋 명령 직접 실행.
56
+ 그 다음 커밋 메시지를 제안하고 사용자 확인 후 실행.
55
57
 
56
58
  Staged 변경사항이 없으면 사용자에게 알리고 먼저 `git add` 사용을 제안.
package/commands/pr.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: 브랜치 차이, 커밋, 변경 파일을 분석하여 Pull Request 자동 생성
3
- allowed-tools: Bash(git status:*), Bash(git diff:*), Bash(git log:*), Bash(git branch:*), Bash(git rev-parse:*), Bash(gh pr:*), Bash(gh auth:*)
3
+ allowed-tools: Bash(git status:*), Bash(git diff:*), Bash(git log:*), Bash(git branch:*), Bash(git rev-parse:*), Bash(gh pr:*), Bash(gh auth:*), Bash(gh api:*)
4
4
  ---
5
5
 
6
6
  # 자동 PR 생성기
@@ -44,18 +44,33 @@ allowed-tools: Bash(git status:*), Bash(git diff:*), Bash(git log:*), Bash(git b
44
44
  - 코드베이스의 어느 영역이 영향받는가?
45
45
  - breaking changes가 있는가?
46
46
 
47
- 4. **PR 제목 및 설명 생성**
47
+ 4. **기존 PR 확인**
48
+ - `gh pr view --json number,title,body,url,state` 로 현재 브랜치에 열린 PR이 있는지 확인
49
+ - **PR이 이미 열려 있으면 → 5-A (업데이트 플로우)**
50
+ - **PR이 없으면 → 5-B (생성 플로우)**
51
+
52
+ 5-A. **기존 PR 업데이트 플로우**
53
+ - 기존 PR의 title과 body를 가져오기
54
+ - 현재 변경사항을 기반으로 새로운 title과 body를 생성
55
+ - 기존 내용과 새 내용을 비교하여 **변경점을 사용자에게 보여주기**
56
+ - 사용자가 승인하면 `gh pr edit --title "title" --body "body"` 로 업데이트
57
+ - 사용자가 수정을 원하면 반영 후 다시 확인
58
+
59
+ 5-B. **새 PR 생성 플로우**
48
60
  - **제목**: 한국어로 간결한 요약 (커밋 컨벤션이 있으면 따르기)
49
61
  - **설명**: 다음 섹션 포함:
50
62
  - `## 변경 사항` (변경사항 요약)
51
63
  - `## 변경된 파일` (주요 변경 파일 목록)
52
64
  - `## 테스트` (해당되는 경우 테스트 방법)
53
65
  - **"Generated with Claude Code" 또는 AI attribution footer 추가 금지**
66
+ - **생성한 title과 body를 사용자에게 보여주고 확인받기**
67
+ - 사용자가 수정을 원하면 반영 후 다시 확인
54
68
 
55
- 5. **PR 생성**
56
- - 먼저 브랜치가 remote에 push되었는지 확인
57
- - 생성된 title과 body로 `gh pr create` 사용
58
- - PR 이미 존재하면 사용자에게 알림
69
+ 6. **실행**
70
+ - **사용자가 승인한 후에만** 실행
71
+ - 먼저 브랜치가 remote에 push되었는지 확인 (안 되었으면 push 제안)
72
+ - PR: `gh pr create --title "title" --body "body"`
73
+ - 기존 PR 업데이트: `gh pr edit --title "title" --body "body"`
59
74
 
60
75
  ## 출력 형식
61
76
 
@@ -63,17 +78,14 @@ allowed-tools: Bash(git status:*), Bash(git diff:*), Bash(git log:*), Bash(git b
63
78
  - 현재 브랜치와 타겟 브랜치
64
79
  - 포함될 커밋 수
65
80
  - 변경사항 요약
81
+ - 기존 PR 존재 여부
66
82
 
67
- 다음 PR 생성 전 확인 요청, 제안된 title과 description 표시.
68
-
69
- 확인 후 실행:
70
- ```bash
71
- gh pr create --title "title" --body "body"
72
- ```
83
+ 다음:
84
+ - **새 PR**: 제안된 title과 body를 보여주고 사용자 확인 후 생성
85
+ - **기존 PR 업데이트**: 기존 내용 vs 새 내용 비교를 보여주고 사용자 확인 후 업데이트
73
86
 
74
87
  ## 에러 처리
75
88
 
76
89
  - GitHub CLI 로그인 안됨: `gh auth login` 실행 안내
77
90
  - 브랜치 미푸시: `git push -u origin <branch>`로 push 제안
78
- - PR 이미 존재: 기존 PR URL 표시
79
91
  - main 브랜치에서 실행: feature 브랜치 먼저 생성하라고 안내
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "binary-agents",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "description": "Claude Code subagents and slash commands collection with sync CLI tool",
5
5
  "type": "module",
6
6
  "main": "src/sync.js",