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,484 +0,0 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import { TokenStorage } from './token-storage.js';
4
-
5
- /**
6
- * 토큰 사용량 모니터링 및 임계값 알림을 관리하는 클래스
7
- */
8
- export class TokenMonitor {
9
- constructor() {
10
- this.storage = new TokenStorage();
11
- this.configFile = '.aiwf/token-data/monitor-config.json';
12
- this.alertsFile = '.aiwf/token-data/alerts.json';
13
- this.isEnabled = false;
14
- this.thresholds = this.loadConfig();
15
- this.alerts = this.loadAlerts();
16
-
17
- this.ensureConfigExists();
18
- }
19
-
20
- /**
21
- * 모니터링 설정을 로드합니다
22
- * @returns {Object} 모니터링 설정
23
- */
24
- loadConfig() {
25
- try {
26
- if (fs.existsSync(this.configFile)) {
27
- const config = JSON.parse(fs.readFileSync(this.configFile, 'utf8'));
28
- this.isEnabled = config.enabled || false;
29
- return config.thresholds || this.getDefaultThresholds();
30
- }
31
- } catch (error) {
32
- console.error('모니터링 설정 로드 중 오류 발생:', error);
33
- }
34
-
35
- return this.getDefaultThresholds();
36
- }
37
-
38
- /**
39
- * 기본 임계값 설정을 반환합니다
40
- * @returns {Object} 기본 임계값
41
- */
42
- getDefaultThresholds() {
43
- return {
44
- dailyTokenLimit: 10000,
45
- sessionTokenLimit: 2000,
46
- warningThreshold: 80, // 80%에서 경고
47
- criticalThreshold: 95, // 95%에서 위험 경고
48
- sessionsPerDayLimit: 20,
49
- tokensPerCommandLimit: 500
50
- };
51
- }
52
-
53
- /**
54
- * 알림 히스토리를 로드합니다
55
- * @returns {Array<Object>} 알림 목록
56
- */
57
- loadAlerts() {
58
- try {
59
- if (fs.existsSync(this.alertsFile)) {
60
- return JSON.parse(fs.readFileSync(this.alertsFile, 'utf8'));
61
- }
62
- } catch (error) {
63
- console.error('알림 히스토리 로드 중 오류 발생:', error);
64
- }
65
-
66
- return [];
67
- }
68
-
69
- /**
70
- * 설정 파일이 존재하는지 확인하고 생성합니다
71
- */
72
- ensureConfigExists() {
73
- try {
74
- const configDir = path.dirname(this.configFile);
75
- if (!fs.existsSync(configDir)) {
76
- fs.mkdirSync(configDir, { recursive: true });
77
- }
78
-
79
- if (!fs.existsSync(this.configFile)) {
80
- this.saveConfig();
81
- }
82
- } catch (error) {
83
- console.error('설정 파일 생성 중 오류 발생:', error);
84
- }
85
- }
86
-
87
- /**
88
- * 설정을 저장합니다
89
- */
90
- saveConfig() {
91
- try {
92
- const config = {
93
- enabled: this.isEnabled,
94
- thresholds: this.thresholds,
95
- lastUpdated: Date.now()
96
- };
97
-
98
- fs.writeFileSync(this.configFile, JSON.stringify(config, null, 2));
99
- } catch (error) {
100
- console.error('설정 저장 중 오류 발생:', error);
101
- }
102
- }
103
-
104
- /**
105
- * 알림을 저장합니다
106
- */
107
- saveAlerts() {
108
- try {
109
- fs.writeFileSync(this.alertsFile, JSON.stringify(this.alerts, null, 2));
110
- } catch (error) {
111
- console.error('알림 저장 중 오류 발생:', error);
112
- }
113
- }
114
-
115
- /**
116
- * 모니터링을 활성화/비활성화합니다
117
- * @param {boolean} enabled - 활성화 여부
118
- */
119
- setEnabled(enabled) {
120
- this.isEnabled = enabled;
121
- this.saveConfig();
122
- console.log(`토큰 모니터링이 ${enabled ? '활성화' : '비활성화'}되었습니다.`);
123
- }
124
-
125
- /**
126
- * 임계값을 설정합니다
127
- * @param {Object} newThresholds - 새 임계값 설정
128
- */
129
- setThresholds(newThresholds) {
130
- this.thresholds = { ...this.thresholds, ...newThresholds };
131
- this.saveConfig();
132
- console.log('임계값이 업데이트되었습니다.');
133
- }
134
-
135
- /**
136
- * 현재 토큰 사용량을 확인하고 임계값을 검사합니다
137
- * @returns {Array<Object>} 임계값 위반 목록
138
- */
139
- checkThresholds() {
140
- if (!this.isEnabled) {
141
- return [];
142
- }
143
-
144
- try {
145
- const violations = this.storage.checkThresholds(this.thresholds);
146
-
147
- // 새로운 위반사항에 대해 알림 생성
148
- for (const violation of violations) {
149
- if (!this.hasRecentAlert(violation.type)) {
150
- this.createAlert(violation);
151
- }
152
- }
153
-
154
- return violations;
155
- } catch (error) {
156
- console.error('임계값 확인 중 오류 발생:', error);
157
- return [];
158
- }
159
- }
160
-
161
- /**
162
- * 최근 알림이 있는지 확인합니다
163
- * @param {string} type - 알림 타입
164
- * @returns {boolean} 최근 알림 존재 여부
165
- */
166
- hasRecentAlert(type) {
167
- const oneHour = 60 * 60 * 1000;
168
- const cutoff = Date.now() - oneHour;
169
-
170
- return this.alerts.some(alert =>
171
- alert.type === type && alert.timestamp > cutoff
172
- );
173
- }
174
-
175
- /**
176
- * 새 알림을 생성합니다
177
- * @param {Object} violation - 위반 정보
178
- */
179
- createAlert(violation) {
180
- try {
181
- const alert = {
182
- id: this.generateAlertId(),
183
- type: violation.type,
184
- level: this.getAlertLevel(violation),
185
- message: violation.message,
186
- threshold: violation.threshold,
187
- current: violation.current,
188
- timestamp: Date.now(),
189
- acknowledged: false
190
- };
191
-
192
- this.alerts.push(alert);
193
- this.saveAlerts();
194
-
195
- // 알림 출력
196
- this.displayAlert(alert);
197
-
198
- // 중요한 알림의 경우 추가 처리
199
- if (alert.level === 'critical') {
200
- this.handleCriticalAlert(alert);
201
- }
202
- } catch (error) {
203
- console.error('알림 생성 중 오류 발생:', error);
204
- }
205
- }
206
-
207
- /**
208
- * 알림 ID를 생성합니다
209
- * @returns {string} 알림 ID
210
- */
211
- generateAlertId() {
212
- return `alert_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
213
- }
214
-
215
- /**
216
- * 알림 레벨을 결정합니다
217
- * @param {Object} violation - 위반 정보
218
- * @returns {string} 알림 레벨
219
- */
220
- getAlertLevel(violation) {
221
- const currentPercentage = (violation.current / violation.threshold) * 100;
222
-
223
- if (currentPercentage >= this.thresholds.criticalThreshold) {
224
- return 'critical';
225
- } else if (currentPercentage >= this.thresholds.warningThreshold) {
226
- return 'warning';
227
- } else {
228
- return 'info';
229
- }
230
- }
231
-
232
- /**
233
- * 알림을 화면에 표시합니다
234
- * @param {Object} alert - 알림 정보
235
- */
236
- displayAlert(alert) {
237
- const levelEmoji = {
238
- info: 'ℹ️',
239
- warning: '⚠️',
240
- critical: '🚨'
241
- };
242
-
243
- const emoji = levelEmoji[alert.level] || 'ℹ️';
244
- const timestamp = new Date(alert.timestamp).toLocaleString();
245
-
246
- console.log(`\n${emoji} [${alert.level.toUpperCase()}] ${timestamp}`);
247
- console.log(`${alert.message}`);
248
- console.log(`현재: ${alert.current.toLocaleString()}, 임계값: ${alert.threshold.toLocaleString()}`);
249
-
250
- if (alert.level === 'critical') {
251
- console.log('🛑 즉시 조치가 필요합니다!');
252
- }
253
-
254
- console.log('─'.repeat(50));
255
- }
256
-
257
- /**
258
- * 위험 알림을 처리합니다
259
- * @param {Object} alert - 알림 정보
260
- */
261
- handleCriticalAlert(alert) {
262
- try {
263
- // 위험 알림 로그 파일 생성
264
- const criticalLogFile = '.aiwf/token-data/critical-alerts.log';
265
- const logEntry = `[${new Date(alert.timestamp).toISOString()}] ${alert.message}\n`;
266
-
267
- fs.appendFileSync(criticalLogFile, logEntry);
268
-
269
- // 자동 압축 제안
270
- if (alert.type === 'daily_token_limit') {
271
- console.log('\n🔧 자동 압축을 실행하여 토큰 사용량을 줄이시겠습니까?');
272
- console.log('명령어: aiwf compress --mode aggressive');
273
- }
274
-
275
- // 세션 정리 제안
276
- if (alert.type === 'daily_session_limit') {
277
- console.log('\n🧹 오래된 세션을 정리하시겠습니까?');
278
- console.log('명령어: aiwf cleanup-sessions --older-than 7d');
279
- }
280
- } catch (error) {
281
- console.error('위험 알림 처리 중 오류 발생:', error);
282
- }
283
- }
284
-
285
- /**
286
- * 실시간 모니터링을 시작합니다
287
- * @param {number} interval - 모니터링 간격 (밀리초)
288
- */
289
- startMonitoring(interval = 60000) { // 기본 1분
290
- if (!this.isEnabled) {
291
- console.log('모니터링이 비활성화되어 있습니다.');
292
- return;
293
- }
294
-
295
- console.log(`토큰 모니터링을 시작합니다 (${interval/1000}초 간격)`);
296
-
297
- this.monitoringInterval = setInterval(() => {
298
- this.checkThresholds();
299
- }, interval);
300
- }
301
-
302
- /**
303
- * 실시간 모니터링을 중지합니다
304
- */
305
- stopMonitoring() {
306
- if (this.monitoringInterval) {
307
- clearInterval(this.monitoringInterval);
308
- this.monitoringInterval = null;
309
- console.log('토큰 모니터링을 중지했습니다.');
310
- }
311
- }
312
-
313
- /**
314
- * 알림을 확인 처리합니다
315
- * @param {string} alertId - 알림 ID
316
- */
317
- acknowledgeAlert(alertId) {
318
- try {
319
- const alert = this.alerts.find(a => a.id === alertId);
320
- if (alert) {
321
- alert.acknowledged = true;
322
- alert.acknowledgedAt = Date.now();
323
- this.saveAlerts();
324
- console.log(`알림 ${alertId}를 확인 처리했습니다.`);
325
- } else {
326
- console.log(`알림 ${alertId}를 찾을 수 없습니다.`);
327
- }
328
- } catch (error) {
329
- console.error('알림 확인 처리 중 오류 발생:', error);
330
- }
331
- }
332
-
333
- /**
334
- * 모든 알림을 확인 처리합니다
335
- */
336
- acknowledgeAllAlerts() {
337
- try {
338
- let count = 0;
339
- for (const alert of this.alerts) {
340
- if (!alert.acknowledged) {
341
- alert.acknowledged = true;
342
- alert.acknowledgedAt = Date.now();
343
- count++;
344
- }
345
- }
346
-
347
- this.saveAlerts();
348
- console.log(`${count}개의 알림을 확인 처리했습니다.`);
349
- } catch (error) {
350
- console.error('모든 알림 확인 처리 중 오류 발생:', error);
351
- }
352
- }
353
-
354
- /**
355
- * 미확인 알림을 조회합니다
356
- * @returns {Array<Object>} 미확인 알림 목록
357
- */
358
- getUnacknowledgedAlerts() {
359
- return this.alerts.filter(alert => !alert.acknowledged);
360
- }
361
-
362
- /**
363
- * 알림 히스토리를 조회합니다
364
- * @param {number} limit - 조회할 알림 수
365
- * @returns {Array<Object>} 알림 목록
366
- */
367
- getAlertHistory(limit = 50) {
368
- return this.alerts
369
- .sort((a, b) => b.timestamp - a.timestamp)
370
- .slice(0, limit);
371
- }
372
-
373
- /**
374
- * 알림 통계를 조회합니다
375
- * @returns {Object} 알림 통계
376
- */
377
- getAlertStats() {
378
- try {
379
- const stats = {
380
- total: this.alerts.length,
381
- byLevel: { info: 0, warning: 0, critical: 0 },
382
- byType: {},
383
- acknowledged: 0,
384
- recent: 0 // 최근 24시간
385
- };
386
-
387
- const dayAgo = Date.now() - (24 * 60 * 60 * 1000);
388
-
389
- for (const alert of this.alerts) {
390
- stats.byLevel[alert.level]++;
391
- stats.byType[alert.type] = (stats.byType[alert.type] || 0) + 1;
392
-
393
- if (alert.acknowledged) {
394
- stats.acknowledged++;
395
- }
396
-
397
- if (alert.timestamp > dayAgo) {
398
- stats.recent++;
399
- }
400
- }
401
-
402
- return stats;
403
- } catch (error) {
404
- console.error('알림 통계 조회 중 오류 발생:', error);
405
- return null;
406
- }
407
- }
408
-
409
- /**
410
- * 오래된 알림을 정리합니다
411
- * @param {number} daysToKeep - 보관할 일수
412
- */
413
- cleanupOldAlerts(daysToKeep = 30) {
414
- try {
415
- const cutoff = Date.now() - (daysToKeep * 24 * 60 * 60 * 1000);
416
- const originalCount = this.alerts.length;
417
-
418
- this.alerts = this.alerts.filter(alert => alert.timestamp > cutoff);
419
-
420
- const removedCount = originalCount - this.alerts.length;
421
- if (removedCount > 0) {
422
- this.saveAlerts();
423
- console.log(`${removedCount}개의 오래된 알림을 정리했습니다.`);
424
- }
425
- } catch (error) {
426
- console.error('알림 정리 중 오류 발생:', error);
427
- }
428
- }
429
-
430
- /**
431
- * 모니터링 상태를 조회합니다
432
- * @returns {Object} 모니터링 상태
433
- */
434
- getStatus() {
435
- return {
436
- enabled: this.isEnabled,
437
- thresholds: this.thresholds,
438
- unacknowledgedAlerts: this.getUnacknowledgedAlerts().length,
439
- totalAlerts: this.alerts.length,
440
- isRunning: !!this.monitoringInterval,
441
- lastCheck: this.lastCheck || null
442
- };
443
- }
444
-
445
- /**
446
- * 모니터링 대시보드를 출력합니다
447
- */
448
- displayDashboard() {
449
- console.log('\n=== 토큰 모니터링 대시보드 ===');
450
-
451
- const status = this.getStatus();
452
- const stats = this.getAlertStats();
453
-
454
- console.log(`상태: ${status.enabled ? '✅ 활성화' : '❌ 비활성화'}`);
455
- console.log(`실행 중: ${status.isRunning ? '✅ 예' : '❌ 아니오'}`);
456
-
457
- console.log('\n--- 임계값 설정 ---');
458
- console.log(`일일 토큰 한도: ${status.thresholds.dailyTokenLimit.toLocaleString()}`);
459
- console.log(`세션 토큰 한도: ${status.thresholds.sessionTokenLimit.toLocaleString()}`);
460
- console.log(`경고 임계값: ${status.thresholds.warningThreshold}%`);
461
- console.log(`위험 임계값: ${status.thresholds.criticalThreshold}%`);
462
-
463
- console.log('\n--- 알림 통계 ---');
464
- console.log(`총 알림: ${stats.total}`);
465
- console.log(`미확인 알림: ${status.unacknowledgedAlerts}`);
466
- console.log(`최근 24시간: ${stats.recent}`);
467
- console.log(`위험 알림: ${stats.byLevel.critical}`);
468
- console.log(`경고 알림: ${stats.byLevel.warning}`);
469
-
470
- const unacknowledged = this.getUnacknowledgedAlerts();
471
- if (unacknowledged.length > 0) {
472
- console.log('\n--- 미확인 알림 ---');
473
- unacknowledged.slice(0, 5).forEach(alert => {
474
- const emoji = alert.level === 'critical' ? '🚨' :
475
- alert.level === 'warning' ? '⚠️' : 'ℹ️';
476
- console.log(`${emoji} ${alert.message}`);
477
- });
478
- }
479
-
480
- console.log('\n========================\n');
481
- }
482
- }
483
-
484
- export default TokenMonitor;