muno-claude-plugin 1.7.0 → 1.8.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.
@@ -0,0 +1,699 @@
1
+ ---
2
+ name: swagger-docs-generator
3
+ description: |
4
+ Swagger/OpenAPI 문서를 읽어서 개발자가 읽기 쉬운 Markdown API 명세로 변환합니다.
5
+ "API 문서 만들어줘", "Swagger 문서 변환", "API 명세 생성", "OpenAPI 문서" 등의 요청에 사용합니다.
6
+ 서버가 제공하는 Swagger JSON을 자동으로 파싱하여 체계적인 문서를 생성합니다.
7
+ allowed-tools: Read, Write, WebFetch, Grep, Glob
8
+ ---
9
+
10
+ # Swagger Docs Generator
11
+
12
+ ## 페르소나
13
+
14
+ @.claude/personas/dev.md
15
+
16
+ > **Swagger Docs Generator의 역할**: 서버의 Swagger/OpenAPI 문서를 읽어서 개발자 친화적인 Markdown 문서로 변환합니다.
17
+ > API 엔드포인트, 요청/응답 스키마, 에러 코드 등을 명확하게 정리합니다.
18
+
19
+ ---
20
+
21
+ ## 기본 설정
22
+
23
+ ### 기본 주소
24
+
25
+ ```
26
+ Host: localhost (또는 자동 감지된 로컬 IP)
27
+ Port: 8080
28
+ Swagger Docs Path: /v3/api-docs
29
+
30
+ Full URL: http://localhost:8080/v3/api-docs
31
+ 또는: http://192.168.x.x:8080/v3/api-docs (로컬 IP 자동 감지)
32
+ ```
33
+
34
+ ### 로컬 IP 자동 감지
35
+
36
+ 사용자가 주소를 제공하지 않으면 자동으로 로컬 IP를 감지합니다:
37
+
38
+ **Bash 스크립트**:
39
+ ```bash
40
+ # macOS/Linux
41
+ LOCAL_IP=$(ifconfig | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | head -n 1)
42
+
43
+ # 또는 더 정확하게
44
+ LOCAL_IP=$(ipconfig getifaddr en0) # macOS WiFi
45
+ LOCAL_IP=$(ipconfig getifaddr en1) # macOS Ethernet
46
+
47
+ # Linux
48
+ LOCAL_IP=$(hostname -I | awk '{print $1}')
49
+ ```
50
+
51
+ **감지 우선순위**:
52
+ 1. WiFi 인터페이스 (en0, wlan0)
53
+ 2. Ethernet 인터페이스 (en1, eth0)
54
+ 3. localhost (127.0.0.1)
55
+
56
+ **예시 출력**:
57
+ ```
58
+ 🔍 로컬 IP 자동 감지 중...
59
+
60
+ 감지된 IP 주소:
61
+ 1. 192.168.0.100 (WiFi - en0)
62
+ 2. 172.16.0.50 (Ethernet - en1)
63
+ 3. 127.0.0.1 (localhost)
64
+
65
+ 어떤 주소를 사용하시겠습니까? (기본: 1)
66
+ ```
67
+
68
+ ### 지원 형식
69
+
70
+ - OpenAPI 3.0.x
71
+ - Swagger 2.0
72
+ - JSON 형식
73
+
74
+ ---
75
+
76
+ ## 워크플로우
77
+
78
+ ```mermaid
79
+ flowchart TD
80
+ A[사용자 요청] --> B{호스트 정보 제공?}
81
+ B -->|Yes| C[제공된 주소 사용]
82
+ B -->|No| D[기본 주소 사용<br/>localhost:8080/v3/api-docs]
83
+ C --> E[Swagger JSON 가져오기]
84
+ D --> E
85
+ E --> F{JSON 로드 성공?}
86
+ F -->|No| G[에러: 연결 실패<br/>주소 확인 요청]
87
+ F -->|Yes| H[OpenAPI 버전 확인]
88
+ H --> I[API 정보 파싱]
89
+ I --> J[엔드포인트별 정리]
90
+ J --> K[스키마 정의 추출]
91
+ K --> L[Markdown 문서 생성]
92
+ L --> M[파일 저장<br/>documents/api/]
93
+ M --> N[사용자에게 결과 전달]
94
+ ```
95
+
96
+ ---
97
+
98
+ ## 사용 방법
99
+
100
+ ### 1. 기본 사용 (로컬 서버)
101
+
102
+ ```
103
+ /swagger-docs-generator
104
+
105
+ 로컬 서버의 API 문서를 생성해주세요.
106
+ ```
107
+
108
+ 자동 감지 프로세스:
109
+ 1. 로컬 IP 감지 (192.168.x.x)
110
+ 2. 감지된 IP가 여러 개면 선택 요청
111
+ 3. 선택된 IP + 기본 포트(8080) + 기본 경로(/v3/api-docs) 조합
112
+ 4. `http://192.168.0.100:8080/v3/api-docs` 접근
113
+
114
+ 로컬 IP 감지 실패 시 `http://localhost:8080/v3/api-docs` 사용
115
+
116
+ ### 2. 커스텀 호스트/포트
117
+
118
+ ```
119
+ /swagger-docs-generator
120
+
121
+ http://localhost:3000/v3/api-docs 의 API 문서를 생성해주세요.
122
+ ```
123
+
124
+ ### 3. 원격 서버
125
+
126
+ ```
127
+ /swagger-docs-generator
128
+
129
+ https://api.example.com/v3/api-docs 의 API 문서를 생성해주세요.
130
+ ```
131
+
132
+ ### 4. 다른 Swagger 경로
133
+
134
+ ```
135
+ /swagger-docs-generator
136
+
137
+ http://localhost:8080/api-docs 의 API 문서를 생성해주세요.
138
+ ```
139
+
140
+ ---
141
+
142
+ ## 정보 수집
143
+
144
+ ### 필수 정보
145
+
146
+ 1. **Swagger 문서 URL**
147
+ - 제공되지 않으면 기본값 사용
148
+ - 형식: `http(s)://host:port/path`
149
+
150
+ 2. **서비스 이름** (선택)
151
+ - 파일명에 사용
152
+ - 제공되지 않으면 swagger JSON의 `info.title` 사용
153
+
154
+ ### 질문 예시
155
+
156
+ ```
157
+ 사용자가 주소를 제공하지 않은 경우:
158
+
159
+ "Swagger 문서 주소를 알려주세요.
160
+ 기본값은 http://localhost:8080/v3/api-docs 입니다.
161
+ 그대로 사용하시겠습니까?"
162
+ ```
163
+
164
+ ---
165
+
166
+ ## Swagger JSON 파싱
167
+
168
+ ### OpenAPI 3.0 구조
169
+
170
+ ```json
171
+ {
172
+ "openapi": "3.0.1",
173
+ "info": {
174
+ "title": "서비스 이름",
175
+ "description": "서비스 설명",
176
+ "version": "1.0.0"
177
+ },
178
+ "servers": [
179
+ {
180
+ "url": "http://localhost:8080",
181
+ "description": "Local server"
182
+ }
183
+ ],
184
+ "paths": {
185
+ "/api/users": {
186
+ "get": {
187
+ "summary": "사용자 목록 조회",
188
+ "tags": ["User"],
189
+ "parameters": [...],
190
+ "responses": {...}
191
+ },
192
+ "post": {...}
193
+ }
194
+ },
195
+ "components": {
196
+ "schemas": {...}
197
+ }
198
+ }
199
+ ```
200
+
201
+ ### Swagger 2.0 구조
202
+
203
+ ```json
204
+ {
205
+ "swagger": "2.0",
206
+ "info": {
207
+ "title": "서비스 이름",
208
+ "version": "1.0.0"
209
+ },
210
+ "host": "localhost:8080",
211
+ "basePath": "/api",
212
+ "paths": {...},
213
+ "definitions": {...}
214
+ }
215
+ ```
216
+
217
+ ---
218
+
219
+ ## Markdown 문서 구조
220
+
221
+ ### 템플릿
222
+
223
+ ```markdown
224
+ # [서비스 이름] API 문서
225
+
226
+ > Generated from Swagger/OpenAPI
227
+ > Version: [version]
228
+ > Base URL: [baseUrl]
229
+
230
+ ## 개요
231
+
232
+ [description]
233
+
234
+ ---
235
+
236
+ ## 서버 정보
237
+
238
+ - **Base URL**: `[baseUrl]`
239
+ - **환경**: [environment]
240
+
241
+ ---
242
+
243
+ ## 인증
244
+
245
+ [인증 방식 설명]
246
+
247
+ ---
248
+
249
+ ## API 엔드포인트
250
+
251
+ ### [Tag Name]
252
+
253
+ #### `[METHOD] [PATH]`
254
+
255
+ **Summary**: [summary]
256
+
257
+ **Description**: [description]
258
+
259
+ **Parameters**:
260
+
261
+ | Name | In | Type | Required | Description |
262
+ |------|-----|------|----------|-------------|
263
+ | id | path | integer | ✅ | User ID |
264
+ | page | query | integer | ❌ | Page number (default: 1) |
265
+
266
+ **Request Body**:
267
+
268
+ ```json
269
+ {
270
+ "name": "string",
271
+ "email": "string"
272
+ }
273
+ ```
274
+
275
+ **Responses**:
276
+
277
+ - **200 OK**
278
+ ```json
279
+ {
280
+ "id": 1,
281
+ "name": "John Doe",
282
+ "email": "john@example.com"
283
+ }
284
+ ```
285
+
286
+ - **400 Bad Request**
287
+ ```json
288
+ {
289
+ "error": "Invalid input"
290
+ }
291
+ ```
292
+
293
+ - **404 Not Found**
294
+ ```json
295
+ {
296
+ "error": "User not found"
297
+ }
298
+ ```
299
+
300
+ ---
301
+
302
+ ## 데이터 모델
303
+
304
+ ### User
305
+
306
+ ```json
307
+ {
308
+ "id": "integer",
309
+ "name": "string",
310
+ "email": "string",
311
+ "createdAt": "string (date-time)"
312
+ }
313
+ ```
314
+
315
+ **Properties**:
316
+
317
+ | Field | Type | Required | Description |
318
+ |-------|------|----------|-------------|
319
+ | id | integer | ✅ | User ID |
320
+ | name | string | ✅ | User name |
321
+ | email | string | ✅ | User email |
322
+ | createdAt | string | ✅ | ISO 8601 date-time |
323
+
324
+ ---
325
+
326
+ ## 에러 코드
327
+
328
+ | Code | Message | Description |
329
+ |------|---------|-------------|
330
+ | 400 | Bad Request | Invalid input parameters |
331
+ | 401 | Unauthorized | Missing or invalid authentication |
332
+ | 403 | Forbidden | Insufficient permissions |
333
+ | 404 | Not Found | Resource not found |
334
+ | 500 | Internal Server Error | Server error |
335
+ ```
336
+
337
+ ---
338
+
339
+ ## 파싱 로직
340
+
341
+ ### 1. 기본 정보 추출
342
+
343
+ ```javascript
344
+ {
345
+ title: swagger.info.title,
346
+ version: swagger.info.version,
347
+ description: swagger.info.description,
348
+ baseUrl: swagger.servers?.[0]?.url || swagger.host + swagger.basePath
349
+ }
350
+ ```
351
+
352
+ ### 2. 엔드포인트 파싱
353
+
354
+ 각 `paths` 객체를 순회하며:
355
+
356
+ ```javascript
357
+ for (path in swagger.paths) {
358
+ for (method in swagger.paths[path]) {
359
+ endpoint = {
360
+ method: method.toUpperCase(),
361
+ path: path,
362
+ summary: operation.summary,
363
+ description: operation.description,
364
+ tags: operation.tags,
365
+ parameters: operation.parameters,
366
+ requestBody: operation.requestBody,
367
+ responses: operation.responses
368
+ }
369
+ }
370
+ }
371
+ ```
372
+
373
+ ### 3. 태그별 그룹핑
374
+
375
+ ```javascript
376
+ const groupedByTag = endpoints.reduce((acc, endpoint) => {
377
+ const tag = endpoint.tags?.[0] || 'Default';
378
+ if (!acc[tag]) acc[tag] = [];
379
+ acc[tag].push(endpoint);
380
+ return acc;
381
+ }, {});
382
+ ```
383
+
384
+ ### 4. 스키마 참조 해석
385
+
386
+ ```javascript
387
+ // $ref: "#/components/schemas/User"
388
+ // 또는 $ref: "#/definitions/User"
389
+
390
+ function resolveRef(ref, swagger) {
391
+ const path = ref.replace('#/', '').split('/');
392
+ let schema = swagger;
393
+ for (const key of path) {
394
+ schema = schema[key];
395
+ }
396
+ return schema;
397
+ }
398
+ ```
399
+
400
+ ---
401
+
402
+ ## 특별 처리
403
+
404
+ ### 1. 인증 정보
405
+
406
+ ```javascript
407
+ // OpenAPI 3.0
408
+ if (swagger.components?.securitySchemes) {
409
+ // Bearer, OAuth2, API Key 등 파싱
410
+ }
411
+
412
+ // Swagger 2.0
413
+ if (swagger.securityDefinitions) {
414
+ // 인증 방식 파싱
415
+ }
416
+ ```
417
+
418
+ ### 2. 예제 데이터
419
+
420
+ ```javascript
421
+ // 우선순위:
422
+ // 1. example (단일 예제)
423
+ // 2. examples (여러 예제)
424
+ // 3. 스키마로부터 자동 생성
425
+
426
+ if (schema.example) {
427
+ return schema.example;
428
+ } else if (schema.examples) {
429
+ return Object.values(schema.examples)[0];
430
+ } else {
431
+ return generateExampleFromSchema(schema);
432
+ }
433
+ ```
434
+
435
+ ### 3. Enum 값
436
+
437
+ ```javascript
438
+ if (schema.enum) {
439
+ // Enum 값 표시
440
+ return `enum: [${schema.enum.join(', ')}]`;
441
+ }
442
+ ```
443
+
444
+ ### 4. Array 타입
445
+
446
+ ```javascript
447
+ if (schema.type === 'array') {
448
+ const itemType = schema.items.type || schema.items.$ref;
449
+ return `array<${itemType}>`;
450
+ }
451
+ ```
452
+
453
+ ---
454
+
455
+ ## 저장 위치
456
+
457
+ ```
458
+ documents/api/
459
+ ├── [service-name]-api-docs.md # 전체 API 문서
460
+ └── [service-name]-postman.json # Postman Collection (선택)
461
+ ```
462
+
463
+ ### 파일명 규칙
464
+
465
+ 1. Swagger의 `info.title`을 kebab-case로 변환
466
+ - "User Service" → `user-service-api-docs.md`
467
+ 2. 사용자가 서비스 이름 제공 시 사용
468
+ 3. 기본값: `api-docs.md`
469
+
470
+ ---
471
+
472
+ ## 에러 처리
473
+
474
+ ### 1. 연결 실패
475
+
476
+ ```markdown
477
+ ❌ Swagger 문서를 가져올 수 없습니다.
478
+
479
+ **주소**: http://localhost:8080/v3/api-docs
480
+
481
+ **가능한 원인**:
482
+ - 서버가 실행되지 않음
483
+ - 포트가 다름
484
+ - Swagger 경로가 다름
485
+
486
+ **해결 방법**:
487
+ 1. 서버가 실행 중인지 확인
488
+ 2. 올바른 포트 확인 (기본: 8080)
489
+ 3. Swagger 문서 경로 확인 (/v3/api-docs, /swagger-ui/api-docs 등)
490
+ ```
491
+
492
+ ### 2. JSON 파싱 실패
493
+
494
+ ```markdown
495
+ ❌ Swagger 문서 형식이 올바르지 않습니다.
496
+
497
+ 반환된 데이터가 JSON이 아니거나 Swagger/OpenAPI 형식이 아닙니다.
498
+ ```
499
+
500
+ ### 3. 빈 문서
501
+
502
+ ```markdown
503
+ ⚠️ API 엔드포인트가 없습니다.
504
+
505
+ Swagger 문서에 정의된 경로(paths)가 없습니다.
506
+ 서버 설정을 확인해주세요.
507
+ ```
508
+
509
+ ---
510
+
511
+ ## 고급 기능
512
+
513
+ ### 1. 여러 서버의 문서 통합
514
+
515
+ ```
516
+ /swagger-docs-generator
517
+
518
+ 다음 서버들의 API 문서를 통합해주세요:
519
+ - Auth Service: http://localhost:8080/v3/api-docs
520
+ - User Service: http://localhost:8081/v3/api-docs
521
+ - Order Service: http://localhost:8082/v3/api-docs
522
+ ```
523
+
524
+ 각 서비스별로 섹션 분리하여 하나의 문서 생성
525
+
526
+ ### 2. Postman Collection 생성 (선택)
527
+
528
+ Swagger JSON을 Postman Collection v2.1 형식으로 변환:
529
+
530
+ ```json
531
+ {
532
+ "info": {
533
+ "name": "User Service API",
534
+ "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
535
+ },
536
+ "item": [
537
+ {
538
+ "name": "Users",
539
+ "item": [
540
+ {
541
+ "name": "Get Users",
542
+ "request": {
543
+ "method": "GET",
544
+ "url": "{{baseUrl}}/api/users"
545
+ }
546
+ }
547
+ ]
548
+ }
549
+ ]
550
+ }
551
+ ```
552
+
553
+ ### 3. cURL 예제 생성
554
+
555
+ 각 엔드포인트에 cURL 예제 추가:
556
+
557
+ ```bash
558
+ # Get user by ID
559
+ curl -X GET "http://localhost:8080/api/users/1" \
560
+ -H "Authorization: Bearer {token}" \
561
+ -H "Content-Type: application/json"
562
+
563
+ # Create user
564
+ curl -X POST "http://localhost:8080/api/users" \
565
+ -H "Content-Type: application/json" \
566
+ -d '{
567
+ "name": "John Doe",
568
+ "email": "john@example.com"
569
+ }'
570
+ ```
571
+
572
+ ---
573
+
574
+ ## 실행 예시
575
+
576
+ ### Input
577
+
578
+ ```
579
+ /swagger-docs-generator
580
+
581
+ http://localhost:8080/v3/api-docs 의 API 문서를 생성해주세요.
582
+ 서비스 이름은 "User Service" 입니다.
583
+ ```
584
+
585
+ ### Process
586
+
587
+ 1. WebFetch로 `http://localhost:8080/v3/api-docs` 요청
588
+ 2. JSON 파싱
589
+ 3. 엔드포인트 추출 및 태그별 그룹핑
590
+ 4. 스키마 정의 추출
591
+ 5. Markdown 문서 생성
592
+ 6. `documents/api/user-service-api-docs.md` 저장
593
+
594
+ ### Output
595
+
596
+ ```markdown
597
+ ✅ API 문서가 생성되었습니다.
598
+
599
+ **파일**: documents/api/user-service-api-docs.md
600
+
601
+ **내용**:
602
+ - 서비스 정보
603
+ - 12개 API 엔드포인트
604
+ - 5개 데이터 모델
605
+ - 인증 방식: Bearer Token
606
+
607
+ **엔드포인트 요약**:
608
+ - GET /api/users - 사용자 목록 조회
609
+ - GET /api/users/{id} - 사용자 조회
610
+ - POST /api/users - 사용자 생성
611
+ - PUT /api/users/{id} - 사용자 수정
612
+ - DELETE /api/users/{id} - 사용자 삭제
613
+ ...
614
+ ```
615
+
616
+ ---
617
+
618
+ ## 추측 금지 원칙
619
+
620
+ ```
621
+ 정보가 충분하면 → 바로 생성
622
+ 정보가 부족하면 → 추측하지 말고 질문
623
+
624
+ ✅ 질문해야 할 때:
625
+ • Swagger 문서 주소를 모를 때
626
+ • 서버에 접근할 수 없을 때
627
+ • 여러 서버 중 어떤 것인지 불명확할 때
628
+
629
+ ❌ 질문하지 말아야 할 때:
630
+ • 기본 포트(8080) 사용 시
631
+ • 표준 Swagger 경로(/v3/api-docs) 사용 시
632
+ • Swagger JSON 형식이 표준일 때
633
+ ```
634
+
635
+ ---
636
+
637
+ ## 참고 템플릿
638
+
639
+ 상세한 Markdown 템플릿은 다음 파일 참고:
640
+ - `reference/api-docs-template.md`
641
+
642
+ ---
643
+
644
+ ## 개발자를 위한 팁
645
+
646
+ ### Swagger UI 확인
647
+
648
+ 생성된 문서와 함께 Swagger UI 링크 제공:
649
+
650
+ ```markdown
651
+ 🔗 **Swagger UI**: http://localhost:8080/swagger-ui.html
652
+ ```
653
+
654
+ ### API 테스트
655
+
656
+ 각 엔드포인트에 "Try it out" 섹션 추가:
657
+
658
+ ```markdown
659
+ #### 테스트
660
+
661
+ **cURL**:
662
+ ```bash
663
+ curl -X GET "http://localhost:8080/api/users/1"
664
+ ```
665
+
666
+ **JavaScript (fetch)**:
667
+ ```javascript
668
+ fetch('http://localhost:8080/api/users/1')
669
+ .then(res => res.json())
670
+ .then(data => console.log(data));
671
+ ```
672
+
673
+ **Python (requests)**:
674
+ ```python
675
+ import requests
676
+ response = requests.get('http://localhost:8080/api/users/1')
677
+ print(response.json())
678
+ ```
679
+ ```
680
+
681
+ ---
682
+
683
+ ## 버전 관리
684
+
685
+ API 문서를 버전별로 관리:
686
+
687
+ ```
688
+ documents/api/
689
+ ├── user-service-api-docs.md # Latest
690
+ ├── v1/
691
+ │ └── user-service-api-docs.md
692
+ └── v2/
693
+ └── user-service-api-docs.md
694
+ ```
695
+
696
+ 버전 정보를 파일명에 포함:
697
+ ```
698
+ documents/api/user-service-v2-api-docs.md
699
+ ```