memento-mcp-server 1.16.1 → 1.16.2-a

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 (163) hide show
  1. package/dist/client/index.d.ts.map +1 -1
  2. package/dist/client/index.js +4 -3
  3. package/dist/client/index.js.map +1 -1
  4. package/dist/domains/anchor/services/anchor/anchor-interfaces.d.ts +2 -4
  5. package/dist/domains/anchor/services/anchor/anchor-interfaces.d.ts.map +1 -1
  6. package/dist/domains/anchor/services/anchor/anchor-interfaces.js.map +1 -1
  7. package/dist/domains/anchor/services/anchor/anchor-manager.d.ts +2 -2
  8. package/dist/domains/anchor/services/anchor/anchor-manager.d.ts.map +1 -1
  9. package/dist/domains/anchor/services/anchor/anchor-manager.js.map +1 -1
  10. package/dist/domains/anchor/services/anchor/anchor-search-service.d.ts +11 -34
  11. package/dist/domains/anchor/services/anchor/anchor-search-service.d.ts.map +1 -1
  12. package/dist/domains/anchor/services/anchor/anchor-search-service.js +66 -549
  13. package/dist/domains/anchor/services/anchor/anchor-search-service.js.map +1 -1
  14. package/dist/domains/anchor/services/anchor/database-types.d.ts +28 -0
  15. package/dist/domains/anchor/services/anchor/database-types.d.ts.map +1 -0
  16. package/dist/domains/anchor/services/anchor/database-types.js +6 -0
  17. package/dist/domains/anchor/services/anchor/database-types.js.map +1 -0
  18. package/dist/domains/anchor/services/anchor/embedding-types.d.ts +20 -0
  19. package/dist/domains/anchor/services/anchor/embedding-types.d.ts.map +1 -0
  20. package/dist/domains/anchor/services/anchor/embedding-types.js +6 -0
  21. package/dist/domains/anchor/services/anchor/embedding-types.js.map +1 -0
  22. package/dist/domains/anchor/services/anchor/fallback-search-service.d.ts +36 -0
  23. package/dist/domains/anchor/services/anchor/fallback-search-service.d.ts.map +1 -0
  24. package/dist/domains/anchor/services/anchor/fallback-search-service.js +85 -0
  25. package/dist/domains/anchor/services/anchor/fallback-search-service.js.map +1 -0
  26. package/dist/domains/anchor/services/anchor/fallback-strategy.d.ts +25 -0
  27. package/dist/domains/anchor/services/anchor/fallback-strategy.d.ts.map +1 -0
  28. package/dist/domains/anchor/services/anchor/fallback-strategy.js +35 -0
  29. package/dist/domains/anchor/services/anchor/fallback-strategy.js.map +1 -0
  30. package/dist/domains/anchor/services/anchor/local-search-service.d.ts +72 -0
  31. package/dist/domains/anchor/services/anchor/local-search-service.d.ts.map +1 -0
  32. package/dist/domains/anchor/services/anchor/local-search-service.js +129 -0
  33. package/dist/domains/anchor/services/anchor/local-search-service.js.map +1 -0
  34. package/dist/domains/anchor/services/anchor/n-hop-search-service.d.ts +90 -0
  35. package/dist/domains/anchor/services/anchor/n-hop-search-service.d.ts.map +1 -0
  36. package/dist/domains/anchor/services/anchor/n-hop-search-service.js +385 -0
  37. package/dist/domains/anchor/services/anchor/n-hop-search-service.js.map +1 -0
  38. package/dist/domains/anchor/services/anchor/n-hop-search-strategy.d.ts +24 -0
  39. package/dist/domains/anchor/services/anchor/n-hop-search-strategy.d.ts.map +1 -0
  40. package/dist/domains/anchor/services/anchor/n-hop-search-strategy.js +39 -0
  41. package/dist/domains/anchor/services/anchor/n-hop-search-strategy.js.map +1 -0
  42. package/dist/domains/anchor/services/anchor/query-filter-service.d.ts +52 -0
  43. package/dist/domains/anchor/services/anchor/query-filter-service.d.ts.map +1 -0
  44. package/dist/domains/anchor/services/anchor/query-filter-service.js +136 -0
  45. package/dist/domains/anchor/services/anchor/query-filter-service.js.map +1 -0
  46. package/dist/domains/anchor/services/anchor/query-filter-strategy.d.ts +24 -0
  47. package/dist/domains/anchor/services/anchor/query-filter-strategy.d.ts.map +1 -0
  48. package/dist/domains/anchor/services/anchor/query-filter-strategy.js +34 -0
  49. package/dist/domains/anchor/services/anchor/query-filter-strategy.js.map +1 -0
  50. package/dist/domains/anchor/services/anchor/search-strategy-interfaces.d.ts +52 -0
  51. package/dist/domains/anchor/services/anchor/search-strategy-interfaces.d.ts.map +1 -0
  52. package/dist/domains/anchor/services/anchor/search-strategy-interfaces.js +6 -0
  53. package/dist/domains/anchor/services/anchor/search-strategy-interfaces.js.map +1 -0
  54. package/dist/domains/anchor/services/anchor/vector-search-engine-types.d.ts +18 -0
  55. package/dist/domains/anchor/services/anchor/vector-search-engine-types.d.ts.map +1 -0
  56. package/dist/domains/anchor/services/anchor/vector-search-engine-types.js +11 -0
  57. package/dist/domains/anchor/services/anchor/vector-search-engine-types.js.map +1 -0
  58. package/dist/domains/memory/repositories/core-memory-database.interface.d.ts +47 -0
  59. package/dist/domains/memory/repositories/core-memory-database.interface.d.ts.map +1 -0
  60. package/dist/domains/memory/repositories/core-memory-database.interface.js +7 -0
  61. package/dist/domains/memory/repositories/core-memory-database.interface.js.map +1 -0
  62. package/dist/domains/memory/repositories/core-memory-repository.d.ts +7 -77
  63. package/dist/domains/memory/repositories/core-memory-repository.d.ts.map +1 -1
  64. package/dist/domains/memory/repositories/core-memory-repository.interface.d.ts +92 -0
  65. package/dist/domains/memory/repositories/core-memory-repository.interface.d.ts.map +1 -0
  66. package/dist/domains/memory/repositories/core-memory-repository.interface.js +6 -0
  67. package/dist/domains/memory/repositories/core-memory-repository.interface.js.map +1 -0
  68. package/dist/domains/memory/repositories/core-memory-repository.js +7 -259
  69. package/dist/domains/memory/repositories/core-memory-repository.js.map +1 -1
  70. package/dist/domains/memory/services/core-memory-cache-service.d.ts +55 -0
  71. package/dist/domains/memory/services/core-memory-cache-service.d.ts.map +1 -1
  72. package/dist/domains/memory/services/core-memory-cache-service.js +110 -8
  73. package/dist/domains/memory/services/core-memory-cache-service.js.map +1 -1
  74. package/dist/domains/memory/services/core-memory-service.d.ts +2 -2
  75. package/dist/domains/memory/services/core-memory-service.d.ts.map +1 -1
  76. package/dist/domains/memory/services/core-memory-service.js +43 -24
  77. package/dist/domains/memory/services/core-memory-service.js.map +1 -1
  78. package/dist/domains/memory/tools/recall-tool.d.ts.map +1 -1
  79. package/dist/domains/memory/tools/recall-tool.js +2 -2
  80. package/dist/domains/memory/tools/recall-tool.js.map +1 -1
  81. package/dist/domains/memory/tools/remember-tool.d.ts.map +1 -1
  82. package/dist/domains/memory/tools/remember-tool.js +2 -2
  83. package/dist/domains/memory/tools/remember-tool.js.map +1 -1
  84. package/dist/domains/monitoring/services/performance-monitor.d.ts +8 -0
  85. package/dist/domains/monitoring/services/performance-monitor.d.ts.map +1 -1
  86. package/dist/domains/monitoring/services/performance-monitor.js +16 -0
  87. package/dist/domains/monitoring/services/performance-monitor.js.map +1 -1
  88. package/dist/infrastructure/async-optimizer.d.ts.map +1 -1
  89. package/dist/infrastructure/async-optimizer.js +8 -7
  90. package/dist/infrastructure/async-optimizer.js.map +1 -1
  91. package/dist/infrastructure/database/adapters/sqlite-core-memory-adapter.d.ts +31 -0
  92. package/dist/infrastructure/database/adapters/sqlite-core-memory-adapter.d.ts.map +1 -0
  93. package/dist/infrastructure/database/adapters/sqlite-core-memory-adapter.js +112 -0
  94. package/dist/infrastructure/database/adapters/sqlite-core-memory-adapter.js.map +1 -0
  95. package/dist/infrastructure/database/database/init.d.ts.map +1 -1
  96. package/dist/infrastructure/database/database/init.js +23 -2
  97. package/dist/infrastructure/database/database/init.js.map +1 -1
  98. package/dist/infrastructure/database/database/migration/migrations/010-add-core-memory-version.d.ts +64 -0
  99. package/dist/infrastructure/database/database/migration/migrations/010-add-core-memory-version.d.ts.map +1 -0
  100. package/dist/infrastructure/database/database/migration/migrations/010-add-core-memory-version.js +174 -0
  101. package/dist/infrastructure/database/database/migration/migrations/010-add-core-memory-version.js.map +1 -0
  102. package/dist/infrastructure/database/database/migration/migrations/010-add-core-memory-version.sql +25 -0
  103. package/dist/infrastructure/database/database-lock-monitor.d.ts +105 -0
  104. package/dist/infrastructure/database/database-lock-monitor.d.ts.map +1 -0
  105. package/dist/infrastructure/database/database-lock-monitor.js +265 -0
  106. package/dist/infrastructure/database/database-lock-monitor.js.map +1 -0
  107. package/dist/infrastructure/database/factories/core-memory-repository.factory.d.ts +17 -0
  108. package/dist/infrastructure/database/factories/core-memory-repository.factory.d.ts.map +1 -0
  109. package/dist/infrastructure/database/factories/core-memory-repository.factory.js +43 -0
  110. package/dist/infrastructure/database/factories/core-memory-repository.factory.js.map +1 -0
  111. package/dist/infrastructure/database/repositories/core-memory-repository-sqlite.impl.d.ts +63 -0
  112. package/dist/infrastructure/database/repositories/core-memory-repository-sqlite.impl.d.ts.map +1 -0
  113. package/dist/infrastructure/database/repositories/core-memory-repository-sqlite.impl.js +281 -0
  114. package/dist/infrastructure/database/repositories/core-memory-repository-sqlite.impl.js.map +1 -0
  115. package/dist/infrastructure/database/wal-checkpoint-scheduler.d.ts +166 -0
  116. package/dist/infrastructure/database/wal-checkpoint-scheduler.d.ts.map +1 -0
  117. package/dist/infrastructure/database/wal-checkpoint-scheduler.js +285 -0
  118. package/dist/infrastructure/database/wal-checkpoint-scheduler.js.map +1 -0
  119. package/dist/npm-client/memento-client.d.ts.map +1 -1
  120. package/dist/npm-client/memento-client.js +5 -4
  121. package/dist/npm-client/memento-client.js.map +1 -1
  122. package/dist/npm-client/memory-manager.d.ts.map +1 -1
  123. package/dist/npm-client/memory-manager.js +4 -3
  124. package/dist/npm-client/memory-manager.js.map +1 -1
  125. package/dist/scripts/check-migration-status.d.ts.map +1 -1
  126. package/dist/scripts/check-migration-status.js +1 -0
  127. package/dist/scripts/check-migration-status.js.map +1 -1
  128. package/dist/server/bootstrap.d.ts +4 -0
  129. package/dist/server/bootstrap.d.ts.map +1 -1
  130. package/dist/server/bootstrap.js +27 -2
  131. package/dist/server/bootstrap.js.map +1 -1
  132. package/dist/server/http-server.d.ts.map +1 -1
  133. package/dist/server/http-server.js +59 -31
  134. package/dist/server/http-server.js.map +1 -1
  135. package/dist/server/index.js +32 -16
  136. package/dist/server/index.js.map +1 -1
  137. package/dist/server/simple-mcp-server.d.ts.map +1 -1
  138. package/dist/server/simple-mcp-server.js +15 -14
  139. package/dist/server/simple-mcp-server.js.map +1 -1
  140. package/dist/shared/config/environment.d.ts.map +1 -1
  141. package/dist/shared/config/environment.js +13 -1
  142. package/dist/shared/config/environment.js.map +1 -1
  143. package/dist/shared/config/index.d.ts.map +1 -1
  144. package/dist/shared/config/index.js +13 -1
  145. package/dist/shared/config/index.js.map +1 -1
  146. package/dist/shared/types/index.d.ts +10 -0
  147. package/dist/shared/types/index.d.ts.map +1 -1
  148. package/dist/tools/base-tool.d.ts.map +1 -1
  149. package/dist/tools/base-tool.js +5 -4
  150. package/dist/tools/base-tool.js.map +1 -1
  151. package/dist/tools/migrate-embeddings-tool.d.ts.map +1 -1
  152. package/dist/tools/migrate-embeddings-tool.js +2 -1
  153. package/dist/tools/migrate-embeddings-tool.js.map +1 -1
  154. package/dist/tools/tool-registry.d.ts.map +1 -1
  155. package/dist/tools/tool-registry.js +4 -3
  156. package/dist/tools/tool-registry.js.map +1 -1
  157. package/dist/workers/consolidation-score-worker.d.ts.map +1 -1
  158. package/dist/workers/consolidation-score-worker.js +5 -4
  159. package/dist/workers/consolidation-score-worker.js.map +1 -1
  160. package/package.json +1 -1
  161. package/scripts/check-file-sizes.ts +405 -0
  162. package/scripts/count-any-types.ts +375 -0
  163. package/scripts/count-console-logs.ts +451 -0
@@ -0,0 +1,375 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * any 타입 개수 측정 스크립트
4
+ *
5
+ * PRD 0017: 코드 품질 개선 - 타입 안정성 개선
6
+ *
7
+ * 사용법:
8
+ * tsx scripts/count-any-types.ts
9
+ * tsx scripts/count-any-types.ts --ci
10
+ * tsx scripts/count-any-types.ts --directory src/
11
+ * tsx scripts/count-any-types.ts --exclude "**/*.spec.ts"
12
+ *
13
+ * 목표:
14
+ * - 현재 any 타입 개수 측정
15
+ * - 목표 대비 출력 (186개 → 50개 이하)
16
+ * - CI/CD 통합 가능
17
+ */
18
+
19
+ import { readFileSync } from 'fs';
20
+ import { readdir } from 'fs/promises';
21
+ import { join, relative } from 'path';
22
+
23
+ /**
24
+ * CLI 옵션
25
+ */
26
+ interface CliOptions {
27
+ ci?: boolean;
28
+ directory?: string;
29
+ exclude?: string[];
30
+ target?: number;
31
+ allowSoftFail?: boolean;
32
+ }
33
+
34
+ /**
35
+ * any 타입 발견 위치
36
+ */
37
+ interface AnyTypeLocation {
38
+ file: string;
39
+ line: number;
40
+ column: number;
41
+ context: string;
42
+ }
43
+
44
+ /**
45
+ * 측정 결과
46
+ */
47
+ interface CountResult {
48
+ total: number;
49
+ locations: AnyTypeLocation[];
50
+ byFile: Map<string, number>;
51
+ }
52
+
53
+ /**
54
+ * 명령줄 인자 파싱
55
+ */
56
+ function parseArgs(): CliOptions {
57
+ const args = process.argv.slice(2);
58
+ const options: CliOptions = {
59
+ exclude: ['**/node_modules/**', '**/dist/**', '**/*.d.ts']
60
+ };
61
+
62
+ for (let i = 0; i < args.length; i++) {
63
+ const arg = args[i];
64
+ if (arg === '--ci') {
65
+ options.ci = true;
66
+ } else if (arg === '--directory' && args[i + 1]) {
67
+ options.directory = args[i + 1];
68
+ i++;
69
+ } else if (arg === '--exclude' && args[i + 1]) {
70
+ if (!options.exclude) {
71
+ options.exclude = [];
72
+ }
73
+ options.exclude.push(args[i + 1]);
74
+ i++;
75
+ } else if (arg === '--target' && args[i + 1]) {
76
+ options.target = parseInt(args[i + 1], 10);
77
+ i++;
78
+ } else if (arg === '--allow-soft-fail') {
79
+ options.allowSoftFail = true;
80
+ } else if (arg === '--help' || arg === '-h') {
81
+ printHelp();
82
+ process.exit(0);
83
+ }
84
+ }
85
+
86
+ return options;
87
+ }
88
+
89
+ /**
90
+ * 도움말 출력
91
+ */
92
+ function printHelp(): void {
93
+ console.log(`
94
+ any 타입 개수 측정 스크립트
95
+
96
+ 사용법:
97
+ tsx scripts/count-any-types.ts [options]
98
+
99
+ 옵션:
100
+ --ci CI 모드 (실패 시 exit code 1 반환)
101
+ --directory <path> 검사할 디렉토리 (기본값: src/)
102
+ --exclude <pattern> 제외할 파일 패턴 (여러 번 사용 가능)
103
+ --target <number> 목표 개수 (기본값: 50개)
104
+ --allow-soft-fail CI 모드에서 경고만 출력하고 통과
105
+ --help, -h 도움말 출력
106
+
107
+ 예제:
108
+ tsx scripts/count-any-types.ts
109
+ tsx scripts/count-any-types.ts --ci
110
+ tsx scripts/count-any-types.ts --target 50
111
+ tsx scripts/count-any-types.ts --directory src/ --exclude "**/*.spec.ts"
112
+ `);
113
+ }
114
+
115
+ /**
116
+ * 패턴 매칭 (간단한 glob 패턴 지원)
117
+ */
118
+ function matchesPattern(path: string, pattern: string): boolean {
119
+ if (pattern.includes('**/node_modules/**')) {
120
+ return path.includes('node_modules');
121
+ }
122
+ if (pattern.includes('**/dist/**')) {
123
+ return path.includes('dist');
124
+ }
125
+ if (pattern.includes('**/*.spec.ts')) {
126
+ return path.endsWith('.spec.ts');
127
+ }
128
+ if (pattern.includes('**/*.d.ts')) {
129
+ return path.endsWith('.d.ts');
130
+ }
131
+ return false;
132
+ }
133
+
134
+ /**
135
+ * 파일이 제외 패턴에 해당하는지 확인
136
+ */
137
+ function shouldExclude(filePath: string, exclude: string[]): boolean {
138
+ for (const pattern of exclude) {
139
+ if (matchesPattern(filePath, pattern)) {
140
+ return true;
141
+ }
142
+ }
143
+ return false;
144
+ }
145
+
146
+ /**
147
+ * 파일 검색 (재귀적)
148
+ */
149
+ async function findFiles(directory: string, exclude: string[]): Promise<string[]> {
150
+ const files: string[] = [];
151
+ const absoluteDir = join(process.cwd(), directory);
152
+
153
+ async function walkDir(dir: string): Promise<void> {
154
+ try {
155
+ const { readdir } = await import('fs/promises');
156
+ const entries = await readdir(dir, { withFileTypes: true });
157
+
158
+ for (const entry of entries) {
159
+ const fullPath = join(dir, entry.name);
160
+
161
+ if (shouldExclude(fullPath, exclude)) {
162
+ continue;
163
+ }
164
+
165
+ if (entry.isDirectory()) {
166
+ await walkDir(fullPath);
167
+ } else if (entry.isFile() && entry.name.endsWith('.ts')) {
168
+ files.push(fullPath);
169
+ }
170
+ }
171
+ } catch (error) {
172
+ // 디렉토리 읽기 실패 시 무시
173
+ }
174
+ }
175
+
176
+ await walkDir(absoluteDir);
177
+ return files;
178
+ }
179
+
180
+ /**
181
+ * 파일에서 any 타입 찾기
182
+ *
183
+ * @param filePath - 파일 경로
184
+ * @returns any 타입 위치 배열
185
+ */
186
+ function findAnyTypes(filePath: string): AnyTypeLocation[] {
187
+ const locations: AnyTypeLocation[] = [];
188
+
189
+ try {
190
+ const content = readFileSync(filePath, 'utf-8');
191
+ const lines = content.split('\n');
192
+
193
+ // 정규식: \bany\b (단어 경계를 사용하여 정확히 "any"만 매칭)
194
+ // 주석이나 문자열 내부는 제외하기 위해 간단한 휴리스틱 사용
195
+ const anyPattern = /\bany\b/g;
196
+
197
+ for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
198
+ const line = lines[lineIndex];
199
+
200
+ // 주석 제외 (// 또는 /* */)
201
+ if (line.trim().startsWith('//')) {
202
+ continue;
203
+ }
204
+
205
+ // 문자열 내부 제외 (간단한 휴리스틱)
206
+ const inString = (line.match(/['"]/g) || []).length % 2 === 1;
207
+ if (inString) {
208
+ continue;
209
+ }
210
+
211
+ // any 패턴 검색
212
+ let match;
213
+ while ((match = anyPattern.exec(line)) !== null) {
214
+ // 타입 정의나 타입 단언 컨텍스트인지 확인
215
+ const beforeMatch = line.substring(0, match.index);
216
+ const afterMatch = line.substring(match.index + match[0].length);
217
+
218
+ // : any, as any, <any, any>, any[] 등의 패턴만 카운트
219
+ const isTypeContext =
220
+ /:\s*$/.test(beforeMatch) || // : any
221
+ /\bas\s+$/.test(beforeMatch) || // as any
222
+ /<\s*$/.test(beforeMatch) || // <any
223
+ /,\s*$/.test(beforeMatch) || // , any
224
+ /\(\s*$/.test(beforeMatch) || // (any
225
+ /\s+$/.test(beforeMatch) && /^[,\[\])>]/.test(afterMatch) || // any, any], any>
226
+ /^\[\]/.test(afterMatch); // any[]
227
+
228
+ if (isTypeContext) {
229
+ locations.push({
230
+ file: filePath,
231
+ line: lineIndex + 1,
232
+ column: match.index + 1,
233
+ context: line.trim()
234
+ });
235
+ }
236
+ }
237
+ }
238
+ } catch (error) {
239
+ // 파일 읽기 실패 시 무시
240
+ }
241
+
242
+ return locations;
243
+ }
244
+
245
+ /**
246
+ * any 타입 개수 측정
247
+ *
248
+ * @param files - 검사할 파일 경로 배열
249
+ * @returns 측정 결과
250
+ */
251
+ function countAnyTypes(files: string[]): CountResult {
252
+ const locations: AnyTypeLocation[] = [];
253
+ const byFile = new Map<string, number>();
254
+
255
+ for (const file of files) {
256
+ const fileLocations = findAnyTypes(file);
257
+ locations.push(...fileLocations);
258
+
259
+ if (fileLocations.length > 0) {
260
+ byFile.set(file, fileLocations.length);
261
+ }
262
+ }
263
+
264
+ return {
265
+ total: locations.length,
266
+ locations,
267
+ byFile
268
+ };
269
+ }
270
+
271
+ /**
272
+ * 결과 출력
273
+ *
274
+ * @param result - 측정 결과
275
+ * @param target - 목표 개수
276
+ * @param projectRoot - 프로젝트 루트 경로
277
+ */
278
+ function printResults(
279
+ result: CountResult,
280
+ target: number,
281
+ projectRoot: string
282
+ ): void {
283
+ console.log('\n📊 any 타입 개수 측정 결과\n');
284
+ console.log(`현재 개수: ${result.total}개`);
285
+ console.log(`목표 개수: ${target}개 이하`);
286
+
287
+ const diff = result.total - target;
288
+ if (diff > 0) {
289
+ console.log(`⚠️ 목표 대비: ${diff}개 초과\n`);
290
+ } else {
291
+ console.log(`✅ 목표 달성: ${Math.abs(diff)}개 여유\n`);
292
+ }
293
+
294
+ // 파일별 통계
295
+ if (result.byFile.size > 0) {
296
+ console.log('📁 파일별 any 타입 개수 (상위 10개):');
297
+ const sortedFiles = Array.from(result.byFile.entries())
298
+ .sort((a, b) => b[1] - a[1])
299
+ .slice(0, 10);
300
+
301
+ for (const [file, count] of sortedFiles) {
302
+ const relativePath = relative(projectRoot, file);
303
+ console.log(` ${relativePath}: ${count}개`);
304
+ }
305
+ console.log('');
306
+ }
307
+
308
+ // 통계
309
+ console.log('📈 통계:');
310
+ console.log(` 검사된 파일 수: ${result.locations.length > 0 ? result.byFile.size : 0}개`);
311
+ console.log(` 총 any 타입 개수: ${result.total}개`);
312
+ console.log('');
313
+ }
314
+
315
+ /**
316
+ * 메인 함수
317
+ */
318
+ async function main(): Promise<void> {
319
+ const options = parseArgs();
320
+ const projectRoot = process.cwd();
321
+ const directory = options.directory || 'src/';
322
+ const exclude = options.exclude || ['**/node_modules/**', '**/dist/**', '**/*.d.ts'];
323
+ const target = options.target || 50;
324
+
325
+ try {
326
+ // 파일 검색
327
+ console.log(`🔍 파일 검색 중... (디렉토리: ${directory})`);
328
+ const files = await findFiles(directory, exclude);
329
+
330
+ if (files.length === 0) {
331
+ console.log('⚠️ 검사할 파일이 없습니다.');
332
+ process.exit(0);
333
+ }
334
+
335
+ console.log(` 발견된 파일: ${files.length}개\n`);
336
+
337
+ // any 타입 개수 측정
338
+ console.log('🔎 any 타입 검색 중...');
339
+ const result = countAnyTypes(files);
340
+
341
+ // 결과 출력
342
+ printResults(result, target, projectRoot);
343
+
344
+ // CI 모드: exit code 처리
345
+ if (options.ci) {
346
+ if (result.total > target) {
347
+ console.log(`❌ CI 실패: any 타입이 ${result.total}개로 목표(${target}개)를 초과했습니다.`);
348
+ process.exit(1);
349
+ } else {
350
+ console.log(`✅ CI 통과: any 타입이 ${result.total}개로 목표(${target}개) 이하입니다.`);
351
+ process.exit(0);
352
+ }
353
+ } else {
354
+ // 일반 모드: 정보만 출력
355
+ if (result.total > target) {
356
+ console.log('💡 팁: --ci 옵션을 사용하면 CI/CD 파이프라인에 통합할 수 있습니다.');
357
+ }
358
+ }
359
+ } catch (error) {
360
+ console.error('❌ 오류 발생:', error instanceof Error ? error.message : String(error));
361
+ if (error instanceof Error && error.stack) {
362
+ console.error(error.stack);
363
+ }
364
+ process.exit(1);
365
+ }
366
+ }
367
+
368
+ // 스크립트 직접 실행 시
369
+ if (import.meta.url === `file://${process.argv[1]}` || import.meta.url.endsWith(process.argv[1])) {
370
+ main().catch(error => {
371
+ console.error('❌ 치명적 오류:', error);
372
+ process.exit(1);
373
+ });
374
+ }
375
+