aiwf 0.3.21 → 0.3.23

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 (140) hide show
  1. package/package.json +3 -2
  2. package/src/cli/index.js +39 -336
  3. package/src/lib/installer.js +310 -90
  4. package/src/utils/messages.js +24 -0
  5. package/src/DEPENDENCY_MAP.md +0 -90
  6. package/src/cli/cache-cli.js +0 -459
  7. package/src/cli/checkpoint-cli.js +0 -417
  8. package/src/cli/language-cli.js +0 -286
  9. package/src/cli/sprint-cli.js +0 -287
  10. package/src/commands/ai-tool.js +0 -383
  11. package/src/commands/compress.js +0 -60
  12. package/src/commands/create-project.js +0 -160
  13. package/src/commands/evaluate.js +0 -459
  14. package/src/commands/persona.js +0 -309
  15. package/src/commands/sprint-task.js +0 -262
  16. package/src/commands/token.js +0 -312
  17. package/src/lib/ai-persona-manager.js +0 -711
  18. package/src/lib/cache-system.js +0 -332
  19. package/src/lib/context-engine.js +0 -568
  20. package/src/lib/github-integration.js +0 -402
  21. package/src/lib/memory-profiler.js +0 -471
  22. package/src/lib/metrics-collector.js +0 -885
  23. package/src/lib/offline-detector.js +0 -386
  24. package/src/lib/resource-loader-enhanced.js +0 -399
  25. package/src/lib/resource-loader.js +0 -250
  26. package/src/lib/resources/commands/ai-persona.js +0 -602
  27. package/src/lib/resources/commands/compress-context.js +0 -389
  28. package/src/lib/resources/commands/evaluate.js +0 -246
  29. package/src/lib/resources/commands/persona-context-apply.js +0 -562
  30. package/src/lib/resources/commands/token-tracking.js +0 -443
  31. package/src/lib/resources/config/commit-patterns.js +0 -103
  32. package/src/lib/resources/config/language.json +0 -6
  33. package/src/lib/resources/personas/PERSONA_INDEX.md +0 -57
  34. package/src/lib/resources/personas/analyst.json +0 -44
  35. package/src/lib/resources/personas/architect/best_practices.md +0 -136
  36. package/src/lib/resources/personas/architect/knowledge_base.md +0 -377
  37. package/src/lib/resources/personas/architect.json +0 -44
  38. package/src/lib/resources/personas/backend/best_practices.md +0 -766
  39. package/src/lib/resources/personas/backend/knowledge_base.md +0 -1070
  40. package/src/lib/resources/personas/data_analyst/best_practices.md +0 -594
  41. package/src/lib/resources/personas/data_analyst/knowledge_base.md +0 -1057
  42. package/src/lib/resources/personas/developer.json +0 -44
  43. package/src/lib/resources/personas/developer.md +0 -37
  44. package/src/lib/resources/personas/evaluation_criteria.json +0 -137
  45. package/src/lib/resources/personas/frontend/best_practices.md +0 -445
  46. package/src/lib/resources/personas/frontend/knowledge_base.md +0 -729
  47. package/src/lib/resources/personas/persona-index.json +0 -31
  48. package/src/lib/resources/personas/reviewer.json +0 -44
  49. package/src/lib/resources/personas/security/best_practices.md +0 -307
  50. package/src/lib/resources/personas/security/knowledge_base.md +0 -498
  51. package/src/lib/resources/personas/tester.json +0 -44
  52. package/src/lib/resources/templates/README.md +0 -78
  53. package/src/lib/resources/templates/api-server/config.json +0 -64
  54. package/src/lib/resources/templates/api-server/template/.aiwf/config.json +0 -56
  55. package/src/lib/resources/templates/api-server/template/.aiwf/feature-ledger.json +0 -42
  56. package/src/lib/resources/templates/api-server/template/.aiwf/personas/backend-engineer.json +0 -40
  57. package/src/lib/resources/templates/api-server/template/.aiwf/scripts/cli.js +0 -111
  58. package/src/lib/resources/templates/api-server/template/.env.example +0 -29
  59. package/src/lib/resources/templates/api-server/template/.eslintrc.json +0 -23
  60. package/src/lib/resources/templates/api-server/template/README.md +0 -171
  61. package/src/lib/resources/templates/api-server/template/jest.config.js +0 -26
  62. package/src/lib/resources/templates/api-server/template/nodemon.json +0 -9
  63. package/src/lib/resources/templates/api-server/template/package.json +0 -61
  64. package/src/lib/resources/templates/api-server/template/src/app.ts +0 -60
  65. package/src/lib/resources/templates/api-server/template/src/config/swagger.ts +0 -38
  66. package/src/lib/resources/templates/api-server/template/src/controllers/aiwfController.ts +0 -54
  67. package/src/lib/resources/templates/api-server/template/src/controllers/authController.ts +0 -128
  68. package/src/lib/resources/templates/api-server/template/src/controllers/statusController.ts +0 -28
  69. package/src/lib/resources/templates/api-server/template/src/index.ts +0 -28
  70. package/src/lib/resources/templates/api-server/template/src/middleware/aiwfMiddleware.ts +0 -50
  71. package/src/lib/resources/templates/api-server/template/src/middleware/authMiddleware.ts +0 -41
  72. package/src/lib/resources/templates/api-server/template/src/middleware/errorHandler.ts +0 -42
  73. package/src/lib/resources/templates/api-server/template/src/middleware/notFoundHandler.ts +0 -14
  74. package/src/lib/resources/templates/api-server/template/src/middleware/requestLogger.ts +0 -20
  75. package/src/lib/resources/templates/api-server/template/src/routes/aiwf.ts +0 -31
  76. package/src/lib/resources/templates/api-server/template/src/routes/index.ts +0 -13
  77. package/src/lib/resources/templates/api-server/template/src/routes/v1/index.ts +0 -67
  78. package/src/lib/resources/templates/api-server/template/src/utils/logger.ts +0 -37
  79. package/src/lib/resources/templates/api-server/template/tests/app.test.ts +0 -40
  80. package/src/lib/resources/templates/api-server/template/tsconfig.json +0 -43
  81. package/src/lib/resources/templates/npm-library/config.json +0 -61
  82. package/src/lib/resources/templates/npm-library/template/LICENSE +0 -21
  83. package/src/lib/resources/templates/npm-library/template/README.md +0 -201
  84. package/src/lib/resources/templates/npm-library/template/package.json +0 -78
  85. package/src/lib/resources/templates/web-app/config.json +0 -53
  86. package/src/lib/resources/templates/web-app/template/.aiwf/config.json +0 -54
  87. package/src/lib/resources/templates/web-app/template/.aiwf/feature-ledger.json +0 -37
  88. package/src/lib/resources/templates/web-app/template/.aiwf/personas/fullstack-developer.json +0 -40
  89. package/src/lib/resources/templates/web-app/template/.aiwf/scripts/cli.js +0 -110
  90. package/src/lib/resources/templates/web-app/template/.eslintrc.cjs +0 -20
  91. package/src/lib/resources/templates/web-app/template/README.md +0 -151
  92. package/src/lib/resources/templates/web-app/template/index.html +0 -14
  93. package/src/lib/resources/templates/web-app/template/package.json +0 -44
  94. package/src/lib/resources/templates/web-app/template/postcss.config.js +0 -6
  95. package/src/lib/resources/templates/web-app/template/public/vite.svg +0 -1
  96. package/src/lib/resources/templates/web-app/template/src/App.tsx +0 -21
  97. package/src/lib/resources/templates/web-app/template/src/components/Layout.tsx +0 -57
  98. package/src/lib/resources/templates/web-app/template/src/components/aiwf/ContextStatus.tsx +0 -107
  99. package/src/lib/resources/templates/web-app/template/src/components/aiwf/TokenUsage.tsx +0 -71
  100. package/src/lib/resources/templates/web-app/template/src/index.css +0 -60
  101. package/src/lib/resources/templates/web-app/template/src/main.tsx +0 -10
  102. package/src/lib/resources/templates/web-app/template/src/pages/AiwfDashboard.tsx +0 -57
  103. package/src/lib/resources/templates/web-app/template/src/pages/HomePage.tsx +0 -89
  104. package/src/lib/resources/templates/web-app/template/src/pages/NotFound.tsx +0 -25
  105. package/src/lib/resources/templates/web-app/template/src/stores/aiwfStore.ts +0 -126
  106. package/src/lib/resources/templates/web-app/template/src/types/global.d.ts +0 -9
  107. package/src/lib/resources/templates/web-app/template/src/vite-env.d.ts +0 -1
  108. package/src/lib/resources/templates/web-app/template/tailwind.config.js +0 -30
  109. package/src/lib/resources/templates/web-app/template/tsconfig.json +0 -37
  110. package/src/lib/resources/templates/web-app/template/tsconfig.node.json +0 -10
  111. package/src/lib/resources/templates/web-app/template/vite.config.ts +0 -23
  112. package/src/lib/resources/utils/background-monitor.js +0 -223
  113. package/src/lib/resources/utils/compression-metrics.js +0 -1031
  114. package/src/lib/resources/utils/compression-strategies.js +0 -557
  115. package/src/lib/resources/utils/content-normalizer.js +0 -455
  116. package/src/lib/resources/utils/context-compressor.js +0 -583
  117. package/src/lib/resources/utils/context-rule-parser.js +0 -180
  118. package/src/lib/resources/utils/context-token-monitor.js +0 -463
  119. package/src/lib/resources/utils/context-update-manager.js +0 -502
  120. package/src/lib/resources/utils/git-utils.js +0 -220
  121. package/src/lib/resources/utils/importance-classifier.js +0 -645
  122. package/src/lib/resources/utils/information-filter.js +0 -710
  123. package/src/lib/resources/utils/persona-aware-compressor.js +0 -598
  124. package/src/lib/resources/utils/prompt-injector.js +0 -242
  125. package/src/lib/resources/utils/simplified-evaluator.js +0 -119
  126. package/src/lib/resources/utils/text-summarizer.js +0 -492
  127. package/src/lib/resources/utils/token-counter.js +0 -177
  128. package/src/lib/resources/utils/token-monitor.js +0 -484
  129. package/src/lib/resources/utils/token-reporter.js +0 -452
  130. package/src/lib/resources/utils/token-storage.js +0 -433
  131. package/src/lib/resources/utils/token-tracker.js +0 -283
  132. package/src/lib/state/priority-calculator.js +0 -217
  133. package/src/lib/state/state-index.js +0 -155
  134. package/src/lib/state/task-scanner.js +0 -328
  135. package/src/lib/task-analyzer.js +0 -599
  136. package/src/lib/template-cache-system.js +0 -559
  137. package/src/lib/template-downloader.js +0 -467
  138. package/src/lib/template-version-manager.js +0 -491
  139. package/src/lib/token-optimizer.js +0 -517
  140. package/src/utils/engineering-guard.js +0 -399
@@ -1,491 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import fs from 'fs/promises';
4
- import path from 'path';
5
- import { createHash } from 'crypto';
6
-
7
- /**
8
- * 템플릿 버전 관리 시스템
9
- * - 템플릿 버전 추적 및 비교
10
- * - 자동 업데이트 확인
11
- * - 버전 충돌 해결
12
- * - 롤백 기능
13
- */
14
- class TemplateVersionManager {
15
- constructor(options = {}) {
16
- this.options = {
17
- versionsFile: options.versionsFile || path.join(process.env.HOME || process.env.USERPROFILE, '.aiwf', 'cache', 'versions.json'),
18
- updateCheckInterval: options.updateCheckInterval || 24 * 60 * 60 * 1000, // 24시간
19
- maxVersionsToKeep: options.maxVersionsToKeep || 5,
20
- autoUpdate: options.autoUpdate || false,
21
- notifications: options.notifications !== false
22
- };
23
-
24
- this.versions = null;
25
- this.cache = null;
26
- this.downloader = null;
27
- this.offlineDetector = null;
28
- }
29
-
30
- /**
31
- * 의존성 주입
32
- */
33
- setCache(cache) {
34
- this.cache = cache;
35
- }
36
-
37
- setDownloader(downloader) {
38
- this.downloader = downloader;
39
- }
40
-
41
- setOfflineDetector(detector) {
42
- this.offlineDetector = detector;
43
- }
44
-
45
- /**
46
- * 버전 관리자 초기화
47
- */
48
- async init() {
49
- await this.loadVersions();
50
-
51
- // 자동 업데이트 체크 스케줄링
52
- if (this.options.autoUpdate) {
53
- this.scheduleUpdateCheck();
54
- }
55
-
56
- console.log('Template version manager initialized');
57
- }
58
-
59
- /**
60
- * 버전 정보 로드
61
- */
62
- async loadVersions() {
63
- try {
64
- const versionsData = await fs.readFile(this.options.versionsFile, 'utf8');
65
- this.versions = JSON.parse(versionsData);
66
- } catch (error) {
67
- // 버전 파일이 없으면 새로 생성
68
- this.versions = {
69
- metadata: {
70
- version: '1.0.0',
71
- created_at: new Date().toISOString(),
72
- last_check: null
73
- },
74
- templates: {
75
- 'ai-tools': {},
76
- 'projects': {}
77
- },
78
- update_history: []
79
- };
80
- await this.saveVersions();
81
- }
82
- }
83
-
84
- /**
85
- * 버전 정보 저장
86
- */
87
- async saveVersions() {
88
- const versionsDir = path.dirname(this.options.versionsFile);
89
- await fs.mkdir(versionsDir, { recursive: true });
90
- await fs.writeFile(this.options.versionsFile, JSON.stringify(this.versions, null, 2));
91
- }
92
-
93
- /**
94
- * 현재 템플릿 버전 등록
95
- */
96
- async registerTemplateVersion(type, name, version, metadata = {}) {
97
- const templateKey = `${type}/${name}`;
98
-
99
- if (!this.versions.templates[type]) {
100
- this.versions.templates[type] = {};
101
- }
102
-
103
- if (!this.versions.templates[type][name]) {
104
- this.versions.templates[type][name] = {
105
- versions: [],
106
- current_version: null,
107
- last_updated: null
108
- };
109
- }
110
-
111
- const templateInfo = this.versions.templates[type][name];
112
- const versionInfo = {
113
- version,
114
- timestamp: new Date().toISOString(),
115
- checksum: metadata.checksum || null,
116
- size: metadata.size || null,
117
- cached: metadata.cached || false,
118
- metadata: metadata.metadata || {}
119
- };
120
-
121
- // 중복 버전 확인
122
- const existingIndex = templateInfo.versions.findIndex(v => v.version === version);
123
- if (existingIndex !== -1) {
124
- templateInfo.versions[existingIndex] = versionInfo;
125
- } else {
126
- templateInfo.versions.push(versionInfo);
127
- }
128
-
129
- // 버전 정렬 (최신 순)
130
- templateInfo.versions.sort((a, b) => this.compareVersions(b.version, a.version));
131
-
132
- // 최대 보관 버전 수 제한
133
- if (templateInfo.versions.length > this.options.maxVersionsToKeep) {
134
- templateInfo.versions = templateInfo.versions.slice(0, this.options.maxVersionsToKeep);
135
- }
136
-
137
- // 현재 버전 업데이트
138
- templateInfo.current_version = version;
139
- templateInfo.last_updated = new Date().toISOString();
140
-
141
- await this.saveVersions();
142
-
143
- return versionInfo;
144
- }
145
-
146
- /**
147
- * 템플릿 버전 조회
148
- */
149
- getTemplateVersion(type, name, version = null) {
150
- const templateInfo = this.versions.templates[type]?.[name];
151
-
152
- if (!templateInfo) {
153
- return null;
154
- }
155
-
156
- if (version) {
157
- return templateInfo.versions.find(v => v.version === version);
158
- }
159
-
160
- return {
161
- current: templateInfo.current_version,
162
- versions: templateInfo.versions,
163
- lastUpdated: templateInfo.last_updated
164
- };
165
- }
166
-
167
- /**
168
- * 사용 가능한 업데이트 확인
169
- */
170
- async checkForUpdates() {
171
- if (!this.downloader) {
172
- throw new Error('Template downloader not configured');
173
- }
174
-
175
- const updates = await this.downloader.checkForUpdates();
176
- const updateInfo = {
177
- timestamp: new Date().toISOString(),
178
- updates: [],
179
- errors: []
180
- };
181
-
182
- for (const update of updates) {
183
- try {
184
- const currentVersion = this.getTemplateVersion(update.type, update.name);
185
-
186
- updateInfo.updates.push({
187
- ...update,
188
- currentVersionInfo: currentVersion,
189
- needsUpdate: !currentVersion ||
190
- this.compareVersions(update.availableVersion, currentVersion.current) > 0
191
- });
192
- } catch (error) {
193
- updateInfo.errors.push({
194
- template: `${update.type}/${update.name}`,
195
- error: error.message
196
- });
197
- }
198
- }
199
-
200
- // 업데이트 기록 저장
201
- this.versions.metadata.last_check = updateInfo.timestamp;
202
- this.versions.update_history.unshift(updateInfo);
203
-
204
- // 업데이트 히스토리 제한
205
- if (this.versions.update_history.length > 10) {
206
- this.versions.update_history = this.versions.update_history.slice(0, 10);
207
- }
208
-
209
- await this.saveVersions();
210
-
211
- return updateInfo;
212
- }
213
-
214
- /**
215
- * 버전 비교 (semantic versioning)
216
- */
217
- compareVersions(version1, version2) {
218
- const parseVersion = (version) => {
219
- return version.split('.').map(num => parseInt(num, 10));
220
- };
221
-
222
- const v1Parts = parseVersion(version1);
223
- const v2Parts = parseVersion(version2);
224
- const maxLength = Math.max(v1Parts.length, v2Parts.length);
225
-
226
- for (let i = 0; i < maxLength; i++) {
227
- const v1Part = v1Parts[i] || 0;
228
- const v2Part = v2Parts[i] || 0;
229
-
230
- if (v1Part > v2Part) return 1;
231
- if (v1Part < v2Part) return -1;
232
- }
233
-
234
- return 0;
235
- }
236
-
237
- /**
238
- * 템플릿 업데이트 실행
239
- */
240
- async updateTemplate(type, name, version = null) {
241
- if (!this.downloader) {
242
- throw new Error('Template downloader not configured');
243
- }
244
-
245
- try {
246
- const currentVersion = this.getTemplateVersion(type, name);
247
-
248
- // 버전 지정하지 않으면 최신 버전 사용
249
- if (!version) {
250
- const availableTemplates = await this.downloader.scanAvailableTemplates();
251
- const templateInfo = availableTemplates[type]?.[name];
252
-
253
- if (!templateInfo) {
254
- throw new Error(`Template ${type}/${name} not found`);
255
- }
256
-
257
- version = templateInfo.version;
258
- }
259
-
260
- // 이미 최신 버전인지 확인
261
- if (currentVersion && currentVersion.current === version) {
262
- return {
263
- success: false,
264
- message: `Template ${type}/${name} is already at version ${version}`,
265
- currentVersion: currentVersion.current
266
- };
267
- }
268
-
269
- // 이전 버전 백업
270
- const backupInfo = currentVersion ? {
271
- version: currentVersion.current,
272
- timestamp: new Date().toISOString()
273
- } : null;
274
-
275
- // 새 버전 다운로드
276
- const downloadResult = await this.downloader.downloadSingleTemplate(type, name, version);
277
-
278
- // 버전 정보 등록
279
- await this.registerTemplateVersion(type, name, version, {
280
- checksum: downloadResult.checksum,
281
- size: downloadResult.size,
282
- cached: true,
283
- metadata: {
284
- backup: backupInfo,
285
- download_result: downloadResult
286
- }
287
- });
288
-
289
- return {
290
- success: true,
291
- message: `Template ${type}/${name} updated to version ${version}`,
292
- previousVersion: currentVersion?.current || null,
293
- newVersion: version,
294
- downloadResult
295
- };
296
-
297
- } catch (error) {
298
- console.error(`Failed to update template ${type}/${name}:`, error.message);
299
- throw error;
300
- }
301
- }
302
-
303
- /**
304
- * 템플릿 롤백
305
- */
306
- async rollbackTemplate(type, name, targetVersion = null) {
307
- const templateInfo = this.versions.templates[type]?.[name];
308
-
309
- if (!templateInfo) {
310
- throw new Error(`Template ${type}/${name} not found`);
311
- }
312
-
313
- // 롤백 대상 버전 결정
314
- let rollbackVersion;
315
- if (targetVersion) {
316
- rollbackVersion = templateInfo.versions.find(v => v.version === targetVersion);
317
- if (!rollbackVersion) {
318
- throw new Error(`Version ${targetVersion} not found for template ${type}/${name}`);
319
- }
320
- } else {
321
- // 이전 버전으로 롤백
322
- const currentIndex = templateInfo.versions.findIndex(v => v.version === templateInfo.current_version);
323
- if (currentIndex === -1 || currentIndex === templateInfo.versions.length - 1) {
324
- throw new Error(`No previous version available for rollback`);
325
- }
326
- rollbackVersion = templateInfo.versions[currentIndex + 1];
327
- }
328
-
329
- // 롤백 실행
330
- if (rollbackVersion.cached) {
331
- // 캐시된 버전 사용
332
- templateInfo.current_version = rollbackVersion.version;
333
- templateInfo.last_updated = new Date().toISOString();
334
-
335
- await this.saveVersions();
336
-
337
- return {
338
- success: true,
339
- message: `Template ${type}/${name} rolled back to version ${rollbackVersion.version}`,
340
- rolledBackFrom: templateInfo.current_version,
341
- rolledBackTo: rollbackVersion.version
342
- };
343
- } else {
344
- throw new Error(`Version ${rollbackVersion.version} is not cached, cannot rollback`);
345
- }
346
- }
347
-
348
- /**
349
- * 버전 히스토리 조회
350
- */
351
- getVersionHistory(type, name) {
352
- const templateInfo = this.versions.templates[type]?.[name];
353
-
354
- if (!templateInfo) {
355
- return null;
356
- }
357
-
358
- return {
359
- current: templateInfo.current_version,
360
- lastUpdated: templateInfo.last_updated,
361
- versions: templateInfo.versions.map(v => ({
362
- version: v.version,
363
- timestamp: v.timestamp,
364
- cached: v.cached,
365
- size: v.size,
366
- checksum: v.checksum
367
- }))
368
- };
369
- }
370
-
371
- /**
372
- * 자동 업데이트 체크 스케줄링
373
- */
374
- scheduleUpdateCheck() {
375
- setInterval(async () => {
376
- if (this.offlineDetector && !await this.offlineDetector.isOnline()) {
377
- console.log('Skipping update check - offline');
378
- return;
379
- }
380
-
381
- try {
382
- const updateInfo = await this.checkForUpdates();
383
- const availableUpdates = updateInfo.updates.filter(u => u.needsUpdate);
384
-
385
- if (availableUpdates.length > 0 && this.options.notifications) {
386
- console.log(`📦 ${availableUpdates.length} template updates available`);
387
-
388
- if (this.options.autoUpdate) {
389
- console.log('🔄 Auto-updating templates...');
390
- await this.updateAllTemplates();
391
- }
392
- }
393
- } catch (error) {
394
- console.error('Failed to check for updates:', error.message);
395
- }
396
- }, this.options.updateCheckInterval);
397
- }
398
-
399
- /**
400
- * 모든 템플릿 업데이트
401
- */
402
- async updateAllTemplates() {
403
- const updateInfo = await this.checkForUpdates();
404
- const availableUpdates = updateInfo.updates.filter(u => u.needsUpdate);
405
- const results = [];
406
-
407
- for (const update of availableUpdates) {
408
- try {
409
- const result = await this.updateTemplate(update.type, update.name, update.availableVersion);
410
- results.push({
411
- ...update,
412
- success: true,
413
- result
414
- });
415
- } catch (error) {
416
- results.push({
417
- ...update,
418
- success: false,
419
- error: error.message
420
- });
421
- }
422
- }
423
-
424
- const successCount = results.filter(r => r.success).length;
425
- const failCount = results.filter(r => !r.success).length;
426
-
427
- console.log(`✅ ${successCount} templates updated successfully`);
428
- if (failCount > 0) {
429
- console.log(`❌ ${failCount} templates failed to update`);
430
- }
431
-
432
- return results;
433
- }
434
-
435
- /**
436
- * 버전 관리 통계
437
- */
438
- getStats() {
439
- const stats = {
440
- totalTemplates: 0,
441
- totalVersions: 0,
442
- cachedVersions: 0,
443
- lastCheck: this.versions.metadata.last_check,
444
- updateHistory: this.versions.update_history.length
445
- };
446
-
447
- for (const type of ['ai-tools', 'projects']) {
448
- const templates = this.versions.templates[type];
449
-
450
- for (const [name, templateInfo] of Object.entries(templates)) {
451
- stats.totalTemplates++;
452
- stats.totalVersions += templateInfo.versions.length;
453
- stats.cachedVersions += templateInfo.versions.filter(v => v.cached).length;
454
- }
455
- }
456
-
457
- return stats;
458
- }
459
-
460
- /**
461
- * 버전 정보 정리
462
- */
463
- async cleanup() {
464
- let removedVersions = 0;
465
-
466
- for (const type of ['ai-tools', 'projects']) {
467
- const templates = this.versions.templates[type];
468
-
469
- for (const [name, templateInfo] of Object.entries(templates)) {
470
- const before = templateInfo.versions.length;
471
-
472
- // 캐시되지 않은 오래된 버전 제거
473
- templateInfo.versions = templateInfo.versions.filter((v, index) => {
474
- if (index < 2) return true; // 최신 2개 버전은 유지
475
- return v.cached; // 캐시된 버전만 유지
476
- });
477
-
478
- removedVersions += before - templateInfo.versions.length;
479
- }
480
- }
481
-
482
- await this.saveVersions();
483
-
484
- return {
485
- removedVersions,
486
- message: `Cleaned up ${removedVersions} old version entries`
487
- };
488
- }
489
- }
490
-
491
- export { TemplateVersionManager };