algokit-mcp 1.0.2 → 1.0.3

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.
Files changed (102) hide show
  1. package/README.md +138 -16
  2. package/dist/api/boj-scraper.js +1 -1
  3. package/dist/api/boj-scraper.js.map +1 -1
  4. package/dist/api/programmers-scraper.d.ts +0 -5
  5. package/dist/api/programmers-scraper.d.ts.map +1 -1
  6. package/dist/api/programmers-scraper.js +59 -90
  7. package/dist/api/programmers-scraper.js.map +1 -1
  8. package/dist/index.js +38 -35
  9. package/dist/index.js.map +1 -1
  10. package/dist/tools/boj/analyze-code-submission-boj.d.ts +67 -0
  11. package/dist/tools/boj/analyze-code-submission-boj.d.ts.map +1 -0
  12. package/dist/tools/boj/analyze-code-submission-boj.js +91 -0
  13. package/dist/tools/boj/analyze-code-submission-boj.js.map +1 -0
  14. package/dist/tools/boj/analyze-problem-boj.d.ts +48 -0
  15. package/dist/tools/boj/analyze-problem-boj.d.ts.map +1 -0
  16. package/dist/tools/boj/analyze-problem-boj.js +52 -0
  17. package/dist/tools/boj/analyze-problem-boj.js.map +1 -0
  18. package/dist/tools/boj/fetch-problem-content-boj.d.ts +49 -0
  19. package/dist/tools/boj/fetch-problem-content-boj.d.ts.map +1 -0
  20. package/dist/tools/boj/fetch-problem-content-boj.js +95 -0
  21. package/dist/tools/boj/fetch-problem-content-boj.js.map +1 -0
  22. package/dist/tools/boj/generate-hint-boj.d.ts +42 -0
  23. package/dist/tools/boj/generate-hint-boj.d.ts.map +1 -0
  24. package/dist/tools/boj/generate-hint-boj.js +82 -0
  25. package/dist/tools/boj/generate-hint-boj.js.map +1 -0
  26. package/dist/tools/boj/generate-review-template-boj.d.ts +48 -0
  27. package/dist/tools/boj/generate-review-template-boj.d.ts.map +1 -0
  28. package/dist/tools/boj/generate-review-template-boj.js +52 -0
  29. package/dist/tools/boj/generate-review-template-boj.js.map +1 -0
  30. package/dist/tools/boj/get-problem-boj.d.ts +22 -0
  31. package/dist/tools/boj/get-problem-boj.d.ts.map +1 -0
  32. package/dist/tools/boj/get-problem-boj.js +89 -0
  33. package/dist/tools/boj/get-problem-boj.js.map +1 -0
  34. package/dist/tools/boj/search-problems-boj.d.ts +42 -0
  35. package/dist/tools/boj/search-problems-boj.d.ts.map +1 -0
  36. package/dist/tools/boj/search-problems-boj.js +143 -0
  37. package/dist/tools/boj/search-problems-boj.js.map +1 -0
  38. package/dist/tools/boj/search-tags-boj.d.ts +22 -0
  39. package/dist/tools/boj/search-tags-boj.d.ts.map +1 -0
  40. package/dist/tools/boj/search-tags-boj.js +70 -0
  41. package/dist/tools/boj/search-tags-boj.js.map +1 -0
  42. package/dist/tools/get-problem-boj.d.ts +22 -0
  43. package/dist/tools/get-problem-boj.d.ts.map +1 -0
  44. package/dist/tools/get-problem-boj.js +89 -0
  45. package/dist/tools/get-problem-boj.js.map +1 -0
  46. package/dist/tools/programmers/analyze-code-submission-programmers.d.ts +60 -0
  47. package/dist/tools/programmers/analyze-code-submission-programmers.d.ts.map +1 -0
  48. package/dist/tools/programmers/analyze-code-submission-programmers.js +85 -0
  49. package/dist/tools/programmers/analyze-code-submission-programmers.js.map +1 -0
  50. package/dist/tools/programmers/analyze-problem-programmers.d.ts +48 -0
  51. package/dist/tools/programmers/analyze-problem-programmers.d.ts.map +1 -0
  52. package/dist/tools/programmers/analyze-problem-programmers.js +53 -0
  53. package/dist/tools/programmers/analyze-problem-programmers.js.map +1 -0
  54. package/dist/tools/programmers/fetch-problem-content-programmers.d.ts +46 -0
  55. package/dist/tools/programmers/fetch-problem-content-programmers.d.ts.map +1 -0
  56. package/dist/tools/programmers/fetch-problem-content-programmers.js +76 -0
  57. package/dist/tools/programmers/fetch-problem-content-programmers.js.map +1 -0
  58. package/dist/tools/programmers/generate-hint-programmers.d.ts +42 -0
  59. package/dist/tools/programmers/generate-hint-programmers.d.ts.map +1 -0
  60. package/dist/tools/programmers/generate-hint-programmers.js +80 -0
  61. package/dist/tools/programmers/generate-hint-programmers.js.map +1 -0
  62. package/dist/tools/programmers/generate-review-template-programmers.d.ts +48 -0
  63. package/dist/tools/programmers/generate-review-template-programmers.d.ts.map +1 -0
  64. package/dist/tools/programmers/generate-review-template-programmers.js +53 -0
  65. package/dist/tools/programmers/generate-review-template-programmers.js.map +1 -0
  66. package/dist/tools/programmers/get-problem-programmers.d.ts +53 -0
  67. package/dist/tools/programmers/get-problem-programmers.d.ts.map +1 -0
  68. package/dist/tools/programmers/get-problem-programmers.js +163 -0
  69. package/dist/tools/programmers/get-problem-programmers.js.map +1 -0
  70. package/dist/tools/programmers/search-problems-programmers.d.ts +73 -0
  71. package/dist/tools/programmers/search-problems-programmers.d.ts.map +1 -0
  72. package/dist/tools/programmers/search-problems-programmers.js +173 -0
  73. package/dist/tools/programmers/search-problems-programmers.js.map +1 -0
  74. package/dist/tools/search-problems-boj.d.ts +42 -0
  75. package/dist/tools/search-problems-boj.d.ts.map +1 -0
  76. package/dist/tools/search-problems-boj.js +143 -0
  77. package/dist/tools/search-problems-boj.js.map +1 -0
  78. package/dist/tools/search-tags-boj.d.ts +22 -0
  79. package/dist/tools/search-tags-boj.d.ts.map +1 -0
  80. package/dist/tools/search-tags-boj.js +70 -0
  81. package/dist/tools/search-tags-boj.js.map +1 -0
  82. package/dist/utils/agent-skill-installer.d.ts +9 -0
  83. package/dist/utils/agent-skill-installer.d.ts.map +1 -0
  84. package/dist/utils/agent-skill-installer.js +94 -0
  85. package/dist/utils/agent-skill-installer.js.map +1 -0
  86. package/dist/utils/claudecode-skill-installer.d.ts +6 -0
  87. package/dist/utils/claudecode-skill-installer.d.ts.map +1 -0
  88. package/dist/utils/claudecode-skill-installer.js +70 -0
  89. package/dist/utils/claudecode-skill-installer.js.map +1 -0
  90. package/dist/utils/skill-installer.d.ts +6 -0
  91. package/dist/utils/skill-installer.d.ts.map +1 -0
  92. package/dist/utils/skill-installer.js +70 -0
  93. package/dist/utils/skill-installer.js.map +1 -0
  94. package/dist/utils/tier-converter.d.ts.map +1 -1
  95. package/dist/utils/tier-converter.js +3 -0
  96. package/dist/utils/tier-converter.js.map +1 -1
  97. package/package.json +3 -4
  98. package/skills/algo:code-review/SKILL.md +134 -0
  99. package/skills/algo:fetch/SKILL.md +102 -0
  100. package/skills/algo:hint/SKILL.md +111 -0
  101. package/skills/algo:review/SKILL.md +123 -0
  102. package/skills/algo:search/SKILL.md +122 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # AlgoKit-mcp
2
2
 
3
- **백준(BOJ)과 프로그래머스 알고리즘 문제 학습을 돕는 MCP 서버 + Skill**
3
+ **AI 에이전트와 함께하는 알고리즘 학습 MCP 툴킷 (백준, 프로그래머스 지원)**
4
4
 
5
5
  AI 기반 힌트 생성, 문제 분석, 복습 템플릿 제공으로 효율적인 알고리즘 학습을 지원합니다.
6
6
 
@@ -12,9 +12,117 @@ AI 기반 힌트 생성, 문제 분석, 복습 템플릿 제공으로 효율적
12
12
  - 📝 **복습 템플릿**: 자동 생성되는 마크다운 복습 문서
13
13
  - 🧪 **코드 분석**: 제출 코드의 시간/공간 복잡도 분석 및 개선 제안
14
14
 
15
+ ## 플랫폼별 설정 경로
16
+
17
+ | 항목 | Claude Code | Codex | Gemini CLI |
18
+ |------|-------------|-------|------------|
19
+ | **Skills 기능명** | Skills | Agent Skills | Agent Skills |
20
+ | **Skills 호출** | `/skill-name` | `$skill-name` or 자동 | 모델 자율 판단 |
21
+ | **MCP 설정 (프로젝트)** | `.mcp.json` | `.codex/config.toml` | `.gemini/settings.json` |
22
+ | **MCP 설정 (전역)** | `~/.claude.json` | `~/.codex/config.toml` | `~/.gemini/settings.json` |
23
+ | **Skills (프로젝트)** | `.claude/skills/` | `.codex/skills/` | `.gemini/skills/` |
24
+ | **Skills (전역)** | `~/.claude/skills/` | `~/.codex/skills/` | `~/.gemini/skills/` |
25
+
26
+ > Skills는 MCP 서버 첫 기동 시 감지된 플랫폼에 자동 설치됩니다.
27
+
28
+ ---
29
+
15
30
  ## 설치
16
31
 
17
- ### Claude Code (추천)
32
+ > **Skills 자동 설치**: MCP 서버 첫 기동 시 설치된 AI 에이전트를 자동으로 감지하여 Skills를 설치합니다.
33
+
34
+ ### Claude Code
35
+
36
+ #### 자동 설치
37
+
38
+ ```bash
39
+ # 전역 설정 (모든 프로젝트에서 사용)
40
+ claude mcp add --scope user algokit -- npx -y algokit-mcp
41
+
42
+ # 프로젝트 설정 (.mcp.json 생성)
43
+ claude mcp add --scope project algokit -- npx -y algokit-mcp
44
+
45
+
46
+ ```
47
+
48
+ #### 수동 설치
49
+
50
+ `~/.claude.json` (전역) 편집:
51
+
52
+ ```json
53
+ {
54
+ "mcpServers": {
55
+ "algokit": {
56
+ "command": "npx",
57
+ "args": ["-y", "algokit-mcp"]
58
+ }
59
+ }
60
+ }
61
+ ```
62
+
63
+ 또는 프로젝트 루트에 `.mcp.json` 생성 ([예시](.claude/examples/claude-code-config.json)):
64
+
65
+ ```json
66
+ {
67
+ "mcpServers": {
68
+ "algokit": {
69
+ "command": "npx",
70
+ "args": ["-y", "algokit-mcp"]
71
+ }
72
+ }
73
+ }
74
+ ```
75
+
76
+ #### Skills 위치
77
+
78
+ | 등록 방식 | Skills 위치 |
79
+ |----------|------------|
80
+ | `--scope user` (전역) | `~/.claude/skills/` |
81
+ | `--scope project` (`.mcp.json` 있음) | `<프로젝트>/.claude/skills/` |
82
+
83
+
84
+ ---
85
+
86
+ ### Codex
87
+
88
+ #### 자동 설치
89
+
90
+ ```bash
91
+ # 전역 설치
92
+ codex mcp add algokit -- npx -y algokit-mcp
93
+ ```
94
+
95
+ #### 수동 설치
96
+
97
+ `~/.codex/config.toml` (전역) 또는 `.codex/config.toml` (프로젝트) 편집 ([예시](.claude/examples/codex-config.toml)):
98
+
99
+ ```toml
100
+ [mcp.servers.algokit]
101
+ command = "npx"
102
+ args = ["-y", "algokit-mcp"]
103
+ ```
104
+
105
+ #### Skills 위치
106
+
107
+ | 등록 방식 | Skills 위치 |
108
+ |----------|------------|
109
+ | 프로젝트 (`.codex/` 있음) | `<프로젝트>/.codex/skills/` |
110
+ | 전역 (`~/.codex/` 있음) | `~/.codex/skills/` |
111
+
112
+ ---
113
+
114
+ ### Gemini CLI
115
+
116
+ #### 자동 설치
117
+
118
+ ```bash
119
+ # 전역 설치
120
+ gemini mcp add algokit -- npx -y algokit-mcp
121
+ ```
122
+
123
+ #### 수동 설치
124
+
125
+ `~/.gemini/settings.json` (전역) 또는 `.gemini/settings.json` (프로젝트) 편집 ([예시](.claude/examples/gemini-config.json)):
18
126
 
19
127
  ```json
20
128
  {
@@ -27,15 +135,22 @@ AI 기반 힌트 생성, 문제 분석, 복습 템플릿 제공으로 효율적
27
135
  }
28
136
  ```
29
137
 
138
+ #### Skills 위치
139
+
140
+ | 등록 방식 | Skills 위치 |
141
+ |----------|------------|
142
+ | 프로젝트 (`.gemini/` 있음) | `<프로젝트>/.gemini/skills/` |
143
+ | 전역 (`~/.gemini/` 있음) | `~/.gemini/skills/` |
144
+
30
145
  ## MCP 도구
31
146
 
32
147
  ### 백준 (BOJ)
33
148
 
34
149
  | 도구 | 설명 |
35
150
  |------|------|
36
- | `search_problems` | 문제 검색 (티어, 태그, 키워드) |
37
- | `get_problem` | 문제 상세 조회 |
38
- | `search_tags` | 알고리즘 태그 검색 |
151
+ | `search_problems_boj` | 문제 검색 (티어, 태그, 키워드) |
152
+ | `get_problem_boj` | 문제 상세 조회 |
153
+ | `search_tags_boj` | 알고리즘 태그 검색 |
39
154
  | `fetch_problem_content_boj` | 문제 본문 스크래핑 |
40
155
  | `analyze_problem_boj` | 문제 분석 및 힌트 가이드 |
41
156
  | `generate_hint_boj` | 3단계 힌트 생성 |
@@ -46,28 +161,35 @@ AI 기반 힌트 생성, 문제 분석, 복습 템플릿 제공으로 효율적
46
161
 
47
162
  | 도구 | 설명 |
48
163
  |------|------|
49
- | `search_programmers_problems` | 문제 검색 (난이도, 카테고리) |
50
- | `get_programmers_problem` | 문제 상세 조회 |
164
+ | `search_problems_programmers` | 문제 검색 (난이도, 카테고리) |
165
+ | `get_problem_programmers` | 문제 상세 조회 |
51
166
  | `fetch_problem_content_programmers` | 문제 본문 스크래핑 |
52
167
  | `analyze_problem_programmers` | 문제 분석 |
53
168
  | `generate_hint_programmers` | 힌트 생성 |
54
169
  | `generate_review_template_programmers` | 복습 템플릿 |
55
170
  | `analyze_code_submission_programmers` | 코드 분석 |
56
171
 
57
- ## MCP Skill (Claude Code 전용)
172
+ ## Skills
58
173
 
59
- **Skill 이름**: `algo:`
174
+ **Skill 이름**: `algo:` (BOJ/프로그래머스 자동 선택)
60
175
 
61
- 플랫폼(BOJ/프로그래머스)을 자동으로 선택하여 자연스러운 학습 경험을 제공합니다.
176
+ Claude Code, Codex, Gemini CLI 모두 동일한 `algo:` Skills를 지원합니다.
177
+ MCP 서버 첫 기동 시 감지된 에이전트에 자동으로 설치되며, 수동으로도 설치할 수 있습니다.
62
178
 
63
- ### 설치 방법
179
+ ### 수동 설치
64
180
 
65
181
  ```bash
66
- # Skill 파일 복사 (프로젝트별)
67
- cp skills/* /your/project/.claude/skills/
182
+ # Claude Code
183
+ cp -r skills/* ~/.claude/skills/ # 전역
184
+ cp -r skills/* .claude/skills/ # 프로젝트
185
+
186
+ # Codex
187
+ cp -r skills/* ~/.codex/skills/ # 전역
188
+ cp -r skills/* .codex/skills/ # 프로젝트
68
189
 
69
- # 또는 전역 설정
70
- cp skills/* ~/.claude/skills/
190
+ # Gemini CLI
191
+ cp -r skills/* ~/.gemini/skills/ # 전역
192
+ cp -r skills/* .gemini/skills/ # 프로젝트
71
193
  ```
72
194
 
73
195
  ### 사용 예시
@@ -269,7 +391,7 @@ MIT
269
391
 
270
392
  <div align="center">
271
393
 
272
- **[GitHub](https://github.com/itsme-shawn/AlgoKit-mcp)** • **[Issues](https://github.com/itsme-shawn/algoKit-mcp/issues)** • **[NPM](https://www.npmjs.com/package/algokit-mcp-server)**
394
+ **[GitHub](https://github.com/itsme-shawn/AlgoKit-mcp)** • **[Issues](https://github.com/itsme-shawn/algoKit-mcp/issues)** • **[NPM](https://www.npmjs.com/package/algokit-mcp)**
273
395
 
274
396
 
275
397
  </div>
@@ -79,7 +79,7 @@ export class BOJScraper {
79
79
  // 캐시 확인
80
80
  const cached = this.cache.get(problemId);
81
81
  if (cached !== undefined) {
82
- console.log(`[BOJScraper] 캐시 히트: 문제 ${problemId}`);
82
+ process.stderr.write(`[BOJScraper] 캐시 히트: 문제 ${problemId}\n`);
83
83
  return cached;
84
84
  }
85
85
  // Rate Limiting (백업 보호, 캐시 미스 시에만)
@@ -1 +1 @@
1
- {"version":3,"file":"boj-scraper.js","sourceRoot":"","sources":["../../src/api/boj-scraper.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD;;GAEG;AACH,MAAM,UAAU,GAAG;IACjB,yBAAyB;IACzB,QAAQ,EAAE,iCAAiC;IAC3C,6CAA6C;IAC7C,UAAU,EAAE,iHAAiH;IAC7H,iBAAiB;IACjB,OAAO,EAAE,KAAK;IACd,aAAa;IACb,WAAW,EAAE,CAAC;IACd,iCAAiC;IACjC,gBAAgB,EAAE,IAAI;CACd,CAAC;AAEX;;GAEG;AACH,MAAM,OAAO,aAAc,SAAQ,KAAK;IAG7B;IACA;IAHT,YACE,OAAe,EACR,IAA+D,EAC/D,aAAuB;QAE9B,KAAK,CAAC,OAAO,CAAC,CAAC;QAHR,SAAI,GAAJ,IAAI,CAA2D;QAC/D,kBAAa,GAAb,aAAa,CAAU;QAG9B,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,UAAU;IACrB,qCAAqC;IAC7B,eAAe,GAAG,CAAC,CAAC;IAE5B,2BAA2B;IACnB,WAAW,CAAc;IAEjC,wBAAwB;IAChB,KAAK,CAA2B;IAExC;QACE,0CAA0C;QAC1C,IAAI,CAAC,WAAW,GAAG,IAAI,WAAW,CAAC;YACjC,QAAQ,EAAE,CAAC;YACX,UAAU,EAAE,CAAC;YACb,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;QAEH,2BAA2B;QAC3B,IAAI,CAAC,KAAK,GAAG,IAAI,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1D,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,gBAAgB,CAAC,SAAiB;QACtC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;YACnD,MAAM,IAAI,aAAa,CACrB,kBAAkB,SAAS,EAAE,EAC7B,aAAa,CACd,CAAC;QACJ,CAAC;QAED,QAAQ;QACR,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,0BAA0B,SAAS,EAAE,CAAC,CAAC;YACnD,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,mCAAmC;QACnC,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;QAEjC,mCAAmC;QACnC,MAAM,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAEpC,MAAM,GAAG,GAAG,GAAG,UAAU,CAAC,QAAQ,IAAI,SAAS,EAAE,CAAC;QAClD,IAAI,SAAkB,CAAC;QAEvB,SAAS;QACT,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,UAAU,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;YACnE,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;gBAE/C,mBAAmB;gBACnB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAElC,SAAS;gBACT,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;gBAEhC,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,SAAS,GAAG,KAAK,CAAC;gBAElB,eAAe;gBACf,IAAI,KAAK,YAAY,aAAa,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;oBACjE,MAAM,KAAK,CAAC;gBACd,CAAC;gBAED,kBAAkB;gBAClB,IAAI,OAAO,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;oBACrC,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC,uBAAuB;oBACvE,SAAS;gBACX,CAAC;YACH,CAAC;QACH,CAAC;QAED,YAAY;QACZ,MAAM,IAAI,aAAa,CACrB,MAAM,SAAS,MAAM,UAAU,CAAC,WAAW,GAAG,CAAC,iBAAiB,EAChE,eAAe,EACf,SAAS,CACV,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,iBAAiB,CAAC,GAAW;QACzC,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;QAE3E,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,MAAM,EAAE,UAAU,CAAC,MAAM;gBACzB,OAAO,EAAE;oBACP,YAAY,EAAE,UAAU,CAAC,UAAU;oBACnC,QAAQ,EAAE,WAAW;oBACrB,iBAAiB,EAAE,qCAAqC;iBACzD;aACF,CAAC,CAAC;YAEH,YAAY,CAAC,SAAS,CAAC,CAAC;YAExB,SAAS;YACT,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5B,MAAM,IAAI,aAAa,CACrB,kBAAkB,GAAG,EAAE,EACvB,WAAW,CACZ,CAAC;YACJ,CAAC;YAED,aAAa;YACb,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,aAAa,CACrB,WAAW,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,EACpD,eAAe,CAChB,CAAC;YACJ,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAEnC,UAAU;YACV,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;gBAC/B,MAAM,IAAI,aAAa,CACrB,mBAAmB,EACnB,aAAa,CACd,CAAC;YACJ,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,YAAY,CAAC,SAAS,CAAC,CAAC;YAExB,8BAA8B;YAC9B,IAAI,KAAK,YAAY,aAAa,EAAE,CAAC;gBACnC,MAAM,KAAK,CAAC;YACd,CAAC;YAED,mBAAmB;YACnB,IAAK,KAAe,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC3C,MAAM,IAAI,aAAa,CACrB,kBAAkB,UAAU,CAAC,OAAO,QAAQ,EAC5C,SAAS,EACT,KAAK,CACN,CAAC;YACJ,CAAC;YAED,aAAa;YACb,MAAM,IAAI,aAAa,CACrB,eAAgB,KAAe,CAAC,OAAO,EAAE,EACzC,eAAe,EACf,KAAK,CACN,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,sBAAsB;QAClC,IAAI,IAAI,CAAC,eAAe,KAAK,CAAC,EAAE,CAAC;YAC/B,cAAc;YACd,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC;QAClD,MAAM,SAAS,GAAG,UAAU,CAAC,gBAAgB,GAAG,OAAO,CAAC;QAExD,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YAClB,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED;;OAEG;IACK,MAAM,CAAC,EAAU;QACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED;;;;OAIG;IACH,aAAa;QACX,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,UAAU;QACR,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;CACF"}
1
+ {"version":3,"file":"boj-scraper.js","sourceRoot":"","sources":["../../src/api/boj-scraper.ts"],"names":[],"mappings":"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"}
@@ -11,7 +11,6 @@ export declare class ProgrammersScrapeError extends Error {
11
11
  * 프로그래머스 스크래퍼
12
12
  */
13
13
  export declare class ProgrammersScraper {
14
- private browserPool;
15
14
  private rateLimiter;
16
15
  private searchCache;
17
16
  private problemCache;
@@ -25,10 +24,6 @@ export declare class ProgrammersScraper {
25
24
  * @throws {ProgrammersScrapeError}
26
25
  */
27
26
  searchProblems(options?: ProgrammersSearchOptions): Promise<ProgrammersProblemSummary[]>;
28
- /**
29
- * 검색 URL 생성
30
- */
31
- private buildSearchUrl;
32
27
  /**
33
28
  * 문제 상세 페이지 HTML 가져오기 (fetch 기반, BOJScraper 패턴)
34
29
  *
@@ -1 +1 @@
1
- {"version":3,"file":"programmers-scraper.d.ts","sourceRoot":"","sources":["../../src/api/programmers-scraper.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,wBAAwB,EACzB,MAAM,yBAAyB,CAAC;AAGjC;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IAGtC,IAAI,EACP,SAAS,GACT,oBAAoB,GACpB,kBAAkB,GAClB,aAAa;IACV,aAAa,CAAC,EAAE,OAAO;gBAN9B,OAAO,EAAE,MAAM,EACR,IAAI,EACP,SAAS,GACT,oBAAoB,GACpB,kBAAkB,GAClB,aAAa,EACV,aAAa,CAAC,EAAE,OAAO,YAAA;CAKjC;AAED;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,WAAW,CAAgD;IACnE,OAAO,CAAC,YAAY,CAA6C;IACjE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsC;;IAe9D;;;;;;OAMG;IACG,cAAc,CAClB,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,yBAAyB,EAAE,CAAC;IA4JvC;;OAEG;IACH,OAAO,CAAC,cAAc;IAsBtB;;;;;;OAMG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA8C1D;;OAEG;YACW,iBAAiB;IAsE/B;;OAEG;IACH,OAAO,CAAC,MAAM;IAId;;;;OAIG;IACH,aAAa;;;;IAOb;;OAEG;IACH,UAAU,IAAI,IAAI;IAKlB;;;;;;OAMG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC;CA2BvE"}
1
+ {"version":3,"file":"programmers-scraper.d.ts","sourceRoot":"","sources":["../../src/api/programmers-scraper.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,wBAAwB,EACzB,MAAM,yBAAyB,CAAC;AAGjC;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IAGtC,IAAI,EACP,SAAS,GACT,oBAAoB,GACpB,kBAAkB,GAClB,aAAa;IACV,aAAa,CAAC,EAAE,OAAO;gBAN9B,OAAO,EAAE,MAAM,EACR,IAAI,EACP,SAAS,GACT,oBAAoB,GACpB,kBAAkB,GAClB,aAAa,EACV,aAAa,CAAC,EAAE,OAAO,YAAA;CAKjC;AAED;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,WAAW,CAAgD;IACnE,OAAO,CAAC,YAAY,CAA6C;IACjE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsC;;IAc9D;;;;;;OAMG;IACG,cAAc,CAClB,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,yBAAyB,EAAE,CAAC;IAgJvC;;;;;;OAMG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA8C1D;;OAEG;YACW,iBAAiB;IAsE/B;;OAEG;IACH,OAAO,CAAC,MAAM;IAId;;;;OAIG;IACH,aAAa;;;;IAOb;;OAEG;IACH,UAAU,IAAI,IAAI;IAKlB;;;;;;OAMG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC;CA2BvE"}
@@ -1,4 +1,9 @@
1
- import { BrowserPool } from '../utils/browser-pool.js';
1
+ /**
2
+ * 프로그래머스 웹 스크래핑 클라이언트
3
+ *
4
+ * 검색: 프로그래머스 내부 JSON API (fetch 기반)
5
+ * 상세 페이지: cheerio (fetch 기반)
6
+ */
2
7
  import { RateLimiter } from '../utils/rate-limiter.js';
3
8
  import { LRUCache } from '../utils/lru-cache.js';
4
9
  import { parseProgrammersProblemContent } from '../utils/html-parser.js';
@@ -19,13 +24,11 @@ export class ProgrammersScrapeError extends Error {
19
24
  * 프로그래머스 스크래퍼
20
25
  */
21
26
  export class ProgrammersScraper {
22
- browserPool;
23
27
  rateLimiter;
24
28
  searchCache;
25
29
  problemCache;
26
30
  baseUrl = 'https://school.programmers.co.kr';
27
31
  constructor() {
28
- this.browserPool = BrowserPool.getInstance();
29
32
  // 초당 1회 요청 (보수적)
30
33
  this.rateLimiter = new RateLimiter({
31
34
  capacity: 2,
@@ -50,121 +53,87 @@ export class ProgrammersScraper {
50
53
  // 캐시 확인
51
54
  const cached = this.searchCache.get(cacheKey);
52
55
  if (cached !== undefined) {
53
- console.log('[ProgrammersScraper] 캐시 히트: 검색 결과');
56
+ process.stderr.write('[ProgrammersScraper] 캐시 히트: 검색 결과\n');
54
57
  // limit 적용 후 반환
55
58
  return limit && limit > 0 ? cached.slice(0, limit) : cached;
56
59
  }
57
60
  // Rate limiting (캐시 미스 시에만)
58
61
  await this.rateLimiter.acquire();
59
- let browser = null;
60
62
  try {
61
- // 1. BrowserPool에서 브라우저 획득
62
- browser = await this.browserPool.acquire();
63
- const browserPage = await browser.newPage();
64
- // 2. 검색 URL 생성
65
- const searchUrl = this.buildSearchUrl({
66
- levels,
67
- order,
68
- page,
69
- query,
70
- });
71
- console.log(`[ProgrammersScraper] 검색 URL: ${searchUrl}`);
72
- // 3. 페이지 이동 및 로딩 대기
73
- try {
74
- await browserPage.goto(searchUrl, {
75
- waitUntil: 'networkidle2',
76
- timeout: 30000,
77
- });
63
+ // 1. 프로그래머스 내부 API URL 생성
64
+ const params = new URLSearchParams();
65
+ params.set('page', String(page));
66
+ params.set('perPage', '20');
67
+ params.set('order', order);
68
+ for (const level of levels) {
69
+ params.append('levels[]', String(level));
78
70
  }
79
- catch (error) {
80
- throw new ProgrammersScrapeError(`페이지 로딩 실패: ${searchUrl}`, 'NAVIGATION_ERROR', error);
71
+ if (query) {
72
+ params.set('search', query);
81
73
  }
82
- // 4. JavaScript 렌더링 대기
74
+ const apiUrl = `${this.baseUrl}/api/v2/school/challenges/?${params.toString()}`;
75
+ process.stderr.write(`[ProgrammersScraper] API URL: ${apiUrl}\n`);
76
+ // 2. API 호출
77
+ const controller = new AbortController();
78
+ const timeoutId = setTimeout(() => controller.abort(), 10000);
79
+ let apiResponse;
83
80
  try {
84
- await browserPage.waitForSelector('table tbody tr', {
85
- timeout: 10000,
81
+ const response = await fetch(apiUrl, {
82
+ signal: controller.signal,
83
+ headers: {
84
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
85
+ Accept: 'application/json',
86
+ 'Accept-Language': 'ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7',
87
+ },
86
88
  });
89
+ clearTimeout(timeoutId);
90
+ if (!response.ok) {
91
+ throw new ProgrammersScrapeError(`API 요청 실패: HTTP ${response.status}`, 'NAVIGATION_ERROR');
92
+ }
93
+ apiResponse = await response.json();
87
94
  }
88
95
  catch (error) {
89
- // 빈 결과일 수 있으므로 스크린샷 저장 후 빈 배열 반환
90
- await browserPage.screenshot({
91
- path: 'programmers-search-empty.png',
92
- });
93
- const rowCount = await browserPage.$$eval('table tbody tr', (rows) => rows.length);
94
- if (rowCount === 0) {
95
- console.log('[ProgrammersScraper] 검색 결과 없음');
96
- await browserPage.close();
97
- return [];
96
+ clearTimeout(timeoutId);
97
+ if (error instanceof ProgrammersScrapeError) {
98
+ throw error;
99
+ }
100
+ if (error.name === 'AbortError') {
101
+ throw new ProgrammersScrapeError('요청이 타임아웃되었습니다 (10000ms 초과)', 'TIMEOUT', error);
98
102
  }
99
- throw new ProgrammersScrapeError('table tbody tr selector를 찾을 수 없습니다', 'SELECTOR_NOT_FOUND', error);
103
+ throw new ProgrammersScrapeError(`API 요청 실패: ${error.message}`, 'NAVIGATION_ERROR', error);
100
104
  }
101
- // 5. 문제 목록 추출
105
+ // 3. API 응답 → ProgrammersProblemSummary 매핑
102
106
  let problems;
103
107
  try {
104
- problems = await browserPage.$$eval('table tbody tr', (rows) => {
105
- return rows.map((row) => {
106
- const titleLink = row.querySelector('td.title a[href*="/lessons/"]');
107
- const categoryEl = row.querySelector('td.title small.part-title');
108
- const levelSpan = row.querySelector('td.level span[class*="level-"]');
109
- const finishedEl = row.querySelector('td.finished-count');
110
- const rateEl = row.querySelector('td.acceptance-rate');
111
- const href = titleLink?.getAttribute('href') || '';
112
- const problemId = href.match(/lessons\/(\d+)/)?.[1] || '';
113
- const title = titleLink?.textContent?.trim() || '';
114
- const category = categoryEl?.textContent?.trim() || '기타';
115
- const levelClass = levelSpan?.className || '';
116
- const level = parseInt(levelClass.match(/level-(\d+)/)?.[1] || '0');
117
- const finishedText = finishedEl?.textContent?.trim() || '0명';
118
- const finishedCount = parseInt(finishedText.replace(/,/g, '').replace('명', '') || '0');
119
- const rateText = rateEl?.textContent?.trim() || '0%';
120
- const acceptanceRate = parseInt(rateText.replace('%', '') || '0');
121
- return {
122
- problemId,
123
- title,
124
- level,
125
- category,
126
- url: `https://school.programmers.co.kr${href}`,
127
- finishedCount,
128
- acceptanceRate,
129
- };
130
- });
131
- });
108
+ problems = (apiResponse.result ?? []).map((item) => ({
109
+ problemId: String(item.id),
110
+ title: item.title,
111
+ level: item.level,
112
+ category: item.partTitle,
113
+ finishedCount: item.finishedCount,
114
+ acceptanceRate: item.acceptanceRate,
115
+ url: `${this.baseUrl}/learn/courses/30/lessons/${item.id}`,
116
+ }));
132
117
  }
133
118
  catch (error) {
134
119
  throw new ProgrammersScrapeError('문제 목록 파싱 실패', 'PARSE_ERROR', error);
135
120
  }
136
- await browserPage.close();
137
- // 6. 캐시에 저장 (limit 적용 전 전체 결과 저장)
121
+ // 4. 캐시에 저장 (limit 적용 전 전체 결과 저장)
138
122
  this.searchCache.set(cacheKey, problems);
139
- // 7. limit 적용
123
+ // 5. limit 적용
140
124
  if (limit && limit > 0) {
141
125
  problems = problems.slice(0, limit);
142
126
  }
143
- console.log(`[ProgrammersScraper] ${problems.length}개 문제 검색 완료`);
127
+ process.stderr.write(`[ProgrammersScraper] ${problems.length}개 문제 검색 완료\n`);
144
128
  return problems;
145
129
  }
146
- finally {
147
- // 7. 브라우저 반환 (필수!)
148
- if (browser) {
149
- await this.browserPool.release(browser);
130
+ catch (error) {
131
+ if (error instanceof ProgrammersScrapeError) {
132
+ throw error;
150
133
  }
134
+ throw new ProgrammersScrapeError(`검색 실패: ${error.message}`, 'NAVIGATION_ERROR', error);
151
135
  }
152
136
  }
153
- /**
154
- * 검색 URL 생성
155
- */
156
- buildSearchUrl(options) {
157
- const params = new URLSearchParams();
158
- params.set('order', options.order);
159
- params.set('page', options.page.toString());
160
- if (options.levels.length > 0) {
161
- params.set('levels', options.levels.join(','));
162
- }
163
- if (options.query) {
164
- params.set('query', options.query);
165
- }
166
- return `${this.baseUrl}/learn/challenges?${params.toString()}`;
167
- }
168
137
  /**
169
138
  * 문제 상세 페이지 HTML 가져오기 (fetch 기반, BOJScraper 패턴)
170
139
  *
@@ -283,7 +252,7 @@ export class ProgrammersScraper {
283
252
  // 캐시 확인
284
253
  const cached = this.problemCache.get(problemId);
285
254
  if (cached !== undefined) {
286
- console.log(`[ProgrammersScraper] 캐시 히트: 문제 ${problemId}`);
255
+ process.stderr.write(`[ProgrammersScraper] 캐시 히트: 문제 ${problemId}\n`);
287
256
  return cached;
288
257
  }
289
258
  // 1. HTML 가져오기 (캐시 미스 시에만)
@@ -1 +1 @@
1
- {"version":3,"file":"programmers-scraper.js","sourceRoot":"","sources":["../../src/api/programmers-scraper.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"programmers-scraper.js","sourceRoot":"","sources":["../../src/api/programmers-scraper.ts"],"names":[],"mappings":"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"}