syr-d2c-workflow-mcp 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -115,14 +115,16 @@ AI가 다음 키워드를 감지하면 이 MCP를 사용합니다:
115
115
  }
116
116
  ```
117
117
 
118
- ### `d2c_compare_with_design`
119
- Figma 디자인과 렌더링 결과를 비교 분석합니다.
118
+ ### `d2c_log_step`
119
+ 워크플로우 진행 상황을 실시간으로 출력합니다.
120
120
 
121
121
  ```typescript
122
122
  {
123
- designDescription: string; // 원본 디자인 설명
124
- renderedDescription: string; // 렌더링 결과 설명
125
- differences?: string[]; // 발견된 차이점
123
+ step: number; // 현재 단계 번호 (1-6)
124
+ stepName: string; // 단계 이름
125
+ status: "start" | "done" | "error";
126
+ message?: string; // 추가 메시지
127
+ iteration?: number; // 반복 횟수
126
128
  }
127
129
  ```
128
130
 
@@ -156,7 +158,73 @@ Figma 디자인과 렌더링 결과를 비교 분석합니다.
156
158
  - `d2c://rules/default` - 기본 디자인 규칙
157
159
  - `d2c://templates/react` - React 컴포넌트 템플릿
158
160
 
159
- ## 워크플로우
161
+ ## 3단계 Phase 워크플로우
162
+
163
+ v0.3.0부터 객관적인 성공률 측정을 위한 3단계 Phase 시스템을 지원합니다.
164
+
165
+ | Phase | 목표 성공률 | 비교 방법 | 수정 주체 |
166
+ |-------|-----------|----------|----------|
167
+ | **Phase 1** | 60% | Playwright 스크린샷 비교 | Figma MCP (재추출) |
168
+ | **Phase 2** | 70% | Playwright 이미지 diff | LLM (코드 수정) |
169
+ | **Phase 3** | 90% | Playwright DOM 비교 | LLM (코드 수정) |
170
+
171
+ ### 워크플로우 개요
172
+
173
+ ```mermaid
174
+ flowchart TD
175
+ Start[Figma 디자인] --> Preflight[사전 검사]
176
+ Preflight --> FigmaGet[Figma 디자인 가져오기]
177
+
178
+ subgraph Phase1 [Phase 1: Figma MCP 추출 - 60%]
179
+ P1_Extract[Figma MCP로 코드 추출]
180
+ P1_Render[Playwright 렌더링]
181
+ P1_Compare[스크린샷 비교]
182
+ P1_Check{성공률 >= 60%?}
183
+ P1_HITL[HITL: 계속?]
184
+
185
+ P1_Extract --> P1_Render --> P1_Compare --> P1_Check
186
+ P1_Check -->|No| P1_HITL
187
+ P1_HITL -->|Yes| P1_Extract
188
+ P1_HITL -->|Manual| P1_Render
189
+ end
190
+
191
+ FigmaGet --> Phase1
192
+ P1_Check -->|Yes| Phase2
193
+
194
+ subgraph Phase2 [Phase 2: LLM 이미지 Diff - 70%]
195
+ P2_Diff[이미지 Diff 분석]
196
+ P2_LLM[LLM 코드 수정]
197
+ P2_Render[Playwright 렌더링]
198
+ P2_Compare[스크린샷 비교]
199
+ P2_Check{성공률 >= 70%?}
200
+ P2_HITL[HITL: 계속?]
201
+
202
+ P2_Diff --> P2_LLM --> P2_Render --> P2_Compare --> P2_Check
203
+ P2_Check -->|No| P2_HITL
204
+ P2_HITL -->|Yes| P2_Diff
205
+ P2_HITL -->|Manual| P2_Render
206
+ end
207
+
208
+ P2_Check -->|Yes| Phase3
209
+
210
+ subgraph Phase3 [Phase 3: LLM DOM 비교 - 90%]
211
+ P3_DOM[DOM 스냅샷 비교]
212
+ P3_LLM[LLM 코드 수정]
213
+ P3_Render[Playwright 렌더링]
214
+ P3_Compare[DOM 비교]
215
+ P3_Check{성공률 >= 90%?}
216
+ P3_HITL[HITL: 계속?]
217
+
218
+ P3_DOM --> P3_LLM --> P3_Render --> P3_Compare --> P3_Check
219
+ P3_Check -->|No| P3_HITL
220
+ P3_HITL -->|Yes| P3_DOM
221
+ P3_HITL -->|Manual| P3_Render
222
+ end
223
+
224
+ P3_Check -->|Yes| Done[완료]
225
+ ```
226
+
227
+ ### 시퀀스 다이어그램
160
228
 
161
229
  ```mermaid
162
230
  sequenceDiagram
@@ -168,26 +236,319 @@ sequenceDiagram
168
236
 
169
237
  User->>AI: "syr로 이 Figma 변환해줘"
170
238
 
239
+ Note over AI,D2C: Step 1: 사전 검사
171
240
  AI->>D2C: d2c_preflight_check()
172
241
  AI->>Figma: get_design_context() 확인
173
242
  AI->>PW: browser_snapshot() 확인
174
243
 
175
- AI->>D2C: d2c_get_design_rules()
244
+ Note over AI,Figma: Step 2: Figma 디자인 가져오기
176
245
  AI->>Figma: get_design_context(figmaUrl)
177
246
  AI->>Figma: get_screenshot()
178
247
 
179
- AI->>D2C: d2c_get_component_template()
180
- AI->>AI: 코드 생성
181
- AI->>D2C: d2c_validate_component()
248
+ rect rgb(255, 240, 240)
249
+ Note over AI,PW: Phase 1: Figma MCP 추출 (목표 60%)
250
+ loop 성공률 < 60% && HITL 승인
251
+ AI->>Figma: 코드 재추출
252
+ AI->>PW: browser_navigate() + screenshot
253
+ AI->>D2C: d2c_phase1_compare(successRate, iteration)
254
+ AI->>User: HITL 확인 요청
255
+ end
256
+ end
257
+
258
+ rect rgb(240, 255, 240)
259
+ Note over AI,PW: Phase 2: LLM 이미지 Diff (목표 70%)
260
+ loop 성공률 < 70% && HITL 승인
261
+ AI->>PW: 이미지 diff 분석
262
+ AI->>AI: LLM 코드 수정
263
+ AI->>PW: browser_navigate() + screenshot
264
+ AI->>D2C: d2c_phase2_image_diff(successRate, diffAreas)
265
+ AI->>User: HITL 확인 요청
266
+ end
267
+ end
268
+
269
+ rect rgb(240, 240, 255)
270
+ Note over AI,PW: Phase 3: LLM DOM 비교 (목표 90%)
271
+ loop 성공률 < 90% && HITL 승인
272
+ AI->>PW: DOM 스냅샷 비교
273
+ AI->>AI: LLM 코드 수정
274
+ AI->>PW: browser_navigate() + DOM 비교
275
+ AI->>D2C: d2c_phase3_dom_compare(successRate, domDiffs)
276
+ AI->>User: HITL 확인 요청
277
+ end
278
+ end
279
+
280
+ AI->>D2C: d2c_workflow_status(phase1, phase2, phase3)
281
+ AI-->>User: 완성된 컴포넌트 + 최종 리포트
282
+ ```
283
+
284
+ ### HITL (Human-in-the-Loop)
285
+
286
+ 모든 Phase에서 사용자 개입이 가능합니다:
287
+
288
+ - **[Y]** 계속 - 자동 수정 후 반복
289
+ - **[N]** 완료 - 현재 상태로 다음 단계 진행
290
+ - **[M]** 수동 수정 - 사용자가 직접 코드 수정 후 재비교
291
+ - **[S]** 중단 - 워크플로우 종료
292
+
293
+ ## OpenSpec 규칙 통합
294
+
295
+ v0.4.0부터 사용자 프로젝트의 OpenSpec 규칙을 자동으로 탐지하고 워크플로우에 적용합니다.
296
+
297
+ ### OpenSpec 규칙 구조
298
+
299
+ ```
300
+ your-project/
301
+ ├── openspec/
302
+ │ └── specs/
303
+ │ ├── figma-standard/ ← Figma 변환 규칙
304
+ │ │ └── spec.md
305
+ │ ├── design-rules/ ← 디자인 규칙
306
+ │ │ └── spec.md
307
+ │ └── custom-rules/ ← 커스텀 규칙
308
+ │ └── spec.md
309
+ └── src/
310
+ ```
311
+
312
+ ### 탐지 경로
313
+
314
+ 다음 경로에서 OpenSpec 규칙을 자동으로 탐지합니다:
315
+
316
+ 1. `./openspec/specs/*/spec.md`
317
+ 2. `./.cursor/openspec/specs/*/spec.md`
318
+ 3. `./docs/openspec/specs/*/spec.md`
319
+
320
+ ### OpenSpec 도구
321
+
322
+ #### `d2c_load_openspec_rules`
323
+ 프로젝트의 OpenSpec 규칙을 탐지하고 로드합니다.
324
+
325
+ ```typescript
326
+ {
327
+ forceReload?: boolean; // 캐시 무시하고 다시 로드
328
+ specNames?: string[]; // 특정 spec만 필터링
329
+ }
330
+ ```
331
+
332
+ **반환값 예시:**
333
+ ```
334
+ 📋 OpenSpec 규칙 로드 결과
335
+
336
+ ## 발견된 규칙 (2개)
337
+
338
+ ### figma-standard
339
+ - 경로: `openspec/specs/figma-standard/spec.md`
340
+ - Requirements (3개):
341
+ - 컴포넌트 네이밍 규칙 (2개 시나리오)
342
+ - Props 인터페이스 정의 (1개 시나리오)
343
+ - 접근성 속성 (2개 시나리오)
344
+
345
+ ### design-rules
346
+ - 경로: `openspec/specs/design-rules/spec.md`
347
+ - Requirements (2개):
348
+ - 색상 시스템 (1개 시나리오)
349
+ - 타이포그래피 (1개 시나리오)
350
+ ```
351
+
352
+ #### `d2c_get_workflow_tasks`
353
+ 현재 Phase에 맞는 체크리스트를 반환합니다.
354
+
355
+ ```typescript
356
+ {
357
+ phase: 1 | 2 | 3; // 현재 Phase
358
+ completedTasks?: string[]; // 완료된 task ID 목록
359
+ includeRules?: boolean; // 적용 규칙 목록 포함
360
+ }
361
+ ```
362
+
363
+ **반환값 예시:**
364
+ ```markdown
365
+ ## Phase 1: Figma MCP 추출 (목표 60%)
366
+
367
+ ### 진행률: 33% (2/6)
368
+ ███░░░░░░░
369
+
370
+ ### Tasks
371
+ - [x] 1.1 Figma 디자인 컨텍스트 가져오기
372
+ - [x] 1.2 Figma MCP로 코드 추출
373
+ - [ ] 1.3 Playwright 렌더링
374
+ - [ ] 1.4 스크린샷 비교 (toHaveScreenshot)
375
+ - [ ] 1.5 d2c_phase1_compare 호출
376
+ - [ ] 1.6 HITL 확인
377
+
378
+ ### 적용 규칙
379
+ - **figma-standard**: 컴포넌트 네이밍 규칙, Props 인터페이스 정의, 접근성 속성
380
+ - **design-rules**: 색상 시스템, 타이포그래피
381
+ ```
382
+
383
+ #### `d2c_validate_against_spec`
384
+ 생성된 코드가 OpenSpec 규칙을 준수하는지 검증합니다.
385
+
386
+ ```typescript
387
+ {
388
+ code: string; // 검증할 코드
389
+ specName?: string; // 특정 spec만 검증
390
+ componentName?: string; // 컴포넌트 이름
391
+ }
392
+ ```
393
+
394
+ **반환값 예시:**
395
+ ```
396
+ 📋 OpenSpec 규칙 검증 결과
397
+
398
+ ## 요약
399
+ - 통과: 3개 ✅
400
+ - 실패: 1개 ❌
401
+ - 경고: 1개 ⚠️
402
+ - 준수율: 60%
403
+
404
+ ██████░░░░ 60%
405
+
406
+ ## 상세 결과
407
+
408
+ ✅ **컴포넌트 네이밍 규칙** (default)
409
+ ButtonPrimary은(는) PascalCase 준수
410
+
411
+ ✅ **Props 인터페이스 정의** (default)
412
+ TypeScript Props 인터페이스 정의됨
413
+
414
+ ❌ **색상 시스템** (design-rules)
415
+ 검증 필요: 디자인 시스템 색상 사용
416
+
417
+ ## 수정 필요 항목
418
+ - 색상 시스템: 디자인 시스템 색상 사용
419
+ ```
420
+
421
+ ### OpenSpec 워크플로우 통합 다이어그램
422
+
423
+ ```mermaid
424
+ flowchart TD
425
+ Start[워크플로우 시작] --> LoadRules[d2c_load_openspec_rules]
426
+ LoadRules --> CheckRules{규칙 발견?}
427
+
428
+ CheckRules -->|Yes| ApplyRules[규칙 적용]
429
+ CheckRules -->|No| DefaultRules[기본 규칙 사용]
430
+
431
+ ApplyRules --> Phase1
432
+ DefaultRules --> Phase1
433
+
434
+ subgraph Phase1 [Phase 1]
435
+ P1_Tasks[d2c_get_workflow_tasks - phase:1]
436
+ P1_Work[Figma MCP 추출]
437
+ P1_Validate[d2c_validate_against_spec]
438
+ P1_Compare[d2c_phase1_compare]
439
+
440
+ P1_Tasks --> P1_Work --> P1_Validate --> P1_Compare
441
+ end
442
+
443
+ subgraph Phase2 [Phase 2]
444
+ P2_Tasks[d2c_get_workflow_tasks - phase:2]
445
+ P2_Work[LLM 이미지 Diff 수정]
446
+ P2_Validate[d2c_validate_against_spec]
447
+ P2_Compare[d2c_phase2_image_diff]
448
+
449
+ P2_Tasks --> P2_Work --> P2_Validate --> P2_Compare
450
+ end
182
451
 
183
- loop 완성될 때까지
184
- AI->>PW: browser_navigate()
185
- AI->>PW: browser_snapshot()
186
- AI->>D2C: d2c_compare_with_design()
187
- AI->>AI: 수정
452
+ subgraph Phase3 [Phase 3]
453
+ P3_Tasks[d2c_get_workflow_tasks - phase:3]
454
+ P3_Work[LLM DOM 비교 수정]
455
+ P3_Validate[d2c_validate_against_spec - 최종]
456
+ P3_Compare[d2c_phase3_dom_compare]
457
+
458
+ P3_Tasks --> P3_Work --> P3_Validate --> P3_Compare
188
459
  end
189
460
 
190
- AI-->>User: 완성된 컴포넌트
461
+ Phase1 --> Phase2 --> Phase3 --> Done[완료]
462
+ ```
463
+
464
+ ### OpenSpec 규칙 예시
465
+
466
+ `openspec/specs/figma-standard/spec.md`:
467
+
468
+ ```markdown
469
+ # Capability: Figma 변환 표준
470
+
471
+ ## ADDED Requirements
472
+
473
+ ### Requirement: 컴포넌트 네이밍 규칙
474
+
475
+ 컴포넌트 이름은 PascalCase를 따라야 합니다(SHALL).
476
+
477
+ #### Scenario: PascalCase 검증
478
+
479
+ - **GIVEN** Figma에서 추출한 컴포넌트가 있을 때
480
+ - **WHEN** 컴포넌트 이름을 생성하면
481
+ - **THEN** PascalCase 형식이어야 한다 (예: ButtonPrimary)
482
+
483
+ ### Requirement: Props 인터페이스 정의
484
+
485
+ 모든 컴포넌트는 TypeScript Props 인터페이스를 정의해야 합니다(SHALL).
486
+
487
+ #### Scenario: Props 인터페이스 존재
488
+
489
+ - **GIVEN** React 컴포넌트가 생성될 때
490
+ - **WHEN** Props를 받는 경우
491
+ - **THEN** interface ComponentNameProps {} 형태로 정의한다
492
+ ```
493
+
494
+ ### Phase별 도구
495
+
496
+ #### `d2c_phase1_compare`
497
+ Phase 1 스크린샷 비교 결과를 처리합니다.
498
+
499
+ ```typescript
500
+ {
501
+ successRate: number; // Playwright 비교 성공률 (0-100)
502
+ targetRate?: number; // 목표 성공률 (기본: 60)
503
+ iteration: number; // 현재 반복 횟수
504
+ maxIterations?: number; // 최대 반복 (기본: 5)
505
+ diffDetails?: string; // 차이점 설명
506
+ }
507
+ ```
508
+
509
+ #### `d2c_phase2_image_diff`
510
+ Phase 2 이미지 diff 결과를 처리합니다.
511
+
512
+ ```typescript
513
+ {
514
+ successRate: number; // Playwright 비교 성공률 (0-100)
515
+ targetRate?: number; // 목표 성공률 (기본: 70)
516
+ iteration: number; // 현재 반복 횟수
517
+ diffAreas?: Array<{ // 차이 영역들
518
+ area: string; // 영역 (예: "header", "button")
519
+ type: string; // 유형 (color, layout, spacing)
520
+ severity: "high" | "medium" | "low";
521
+ }>;
522
+ }
523
+ ```
524
+
525
+ #### `d2c_phase3_dom_compare`
526
+ Phase 3 DOM 비교 결과를 처리합니다.
527
+
528
+ ```typescript
529
+ {
530
+ successRate: number; // DOM 비교 성공률 (0-100)
531
+ targetRate?: number; // 목표 성공률 (기본: 90)
532
+ iteration: number; // 현재 반복 횟수
533
+ domDiffs?: Array<{ // DOM 차이점들
534
+ selector: string; // 요소 선택자
535
+ type: string; // missing, extra, attribute, text
536
+ expected?: string; // 예상 값
537
+ actual?: string; // 실제 값
538
+ }>;
539
+ }
540
+ ```
541
+
542
+ #### `d2c_workflow_status`
543
+ 전체 워크플로우 진행 상황을 표시합니다.
544
+
545
+ ```typescript
546
+ {
547
+ currentPhase: 1 | 2 | 3;
548
+ phase1?: { status: string; successRate: number; iterations: number; };
549
+ phase2?: { status: string; successRate: number; iterations: number; };
550
+ phase3?: { status: string; successRate: number; iterations: number; };
551
+ }
191
552
  ```
192
553
 
193
554
  ## 개발