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,562 +0,0 @@
1
- /**
2
- * 페르소나 컨텍스트 적용 명령어
3
- * AI 페르소나 컨텍스트를 실제로 적용하고 관리하는 CLI 명령어
4
- */
5
-
6
- const fs = require('fs').promises;
7
- const path = require('path');
8
- const ContextRuleParser = require('../utils/context-rule-parser');
9
- const PromptInjector = require('../utils/prompt-injector');
10
- const PersonaBehaviorValidator = require('../utils/persona-behavior-validator');
11
- const ContextUpdateManager = require('../utils/context-update-manager');
12
- const ContextTokenMonitor = require('../utils/context-token-monitor');
13
- const PersonaQualityEvaluator = require('../utils/persona-quality-evaluator');
14
-
15
- class PersonaContextApplyCommand {
16
- constructor() {
17
- this.contextParser = new ContextRuleParser();
18
- this.promptInjector = new PromptInjector();
19
- this.behaviorValidator = new PersonaBehaviorValidator();
20
- this.updateManager = new ContextUpdateManager();
21
- this.tokenMonitor = new ContextTokenMonitor();
22
- this.qualityEvaluator = new PersonaQualityEvaluator();
23
- }
24
-
25
- /**
26
- * 명령어 정의
27
- * @returns {Object} 명령어 설정
28
- */
29
- static command() {
30
- return {
31
- command: 'persona-context <action>',
32
- description: 'AI 페르소나 컨텍스트 적용 및 관리',
33
- builder: (yargs) => {
34
- return yargs
35
- .positional('action', {
36
- describe: '수행할 작업',
37
- type: 'string',
38
- choices: ['apply', 'switch', 'validate', 'monitor', 'evaluate', 'watch', 'report']
39
- })
40
- .option('persona', {
41
- alias: 'p',
42
- describe: '대상 페르소나',
43
- type: 'string',
44
- choices: ['architect', 'frontend', 'backend', 'data_analyst', 'security']
45
- })
46
- .option('prompt', {
47
- describe: '적용할 프롬프트',
48
- type: 'string'
49
- })
50
- .option('response', {
51
- describe: '검증할 응답',
52
- type: 'string'
53
- })
54
- .option('output', {
55
- alias: 'o',
56
- describe: '결과 출력 형식',
57
- type: 'string',
58
- choices: ['json', 'table', 'detailed'],
59
- default: 'table'
60
- })
61
- .option('save', {
62
- alias: 's',
63
- describe: '결과를 파일로 저장',
64
- type: 'boolean',
65
- default: false
66
- });
67
- },
68
- handler: async (argv) => {
69
- const command = new PersonaContextApplyCommand();
70
- await command.execute(argv);
71
- }
72
- };
73
- }
74
-
75
- /**
76
- * 명령어 실행
77
- * @param {Object} argv - 명령어 인자
78
- */
79
- async execute(argv) {
80
- const { action, persona, prompt, response, output, save } = argv;
81
-
82
- try {
83
- switch (action) {
84
- case 'apply':
85
- await this.applyContext(persona, prompt, output, save);
86
- break;
87
-
88
- case 'switch':
89
- await this.switchPersona(persona);
90
- break;
91
-
92
- case 'validate':
93
- await this.validateResponse(persona, response, prompt, output);
94
- break;
95
-
96
- case 'monitor':
97
- await this.monitorTokenUsage(persona, output);
98
- break;
99
-
100
- case 'evaluate':
101
- await this.evaluateQuality(persona, prompt, response, output);
102
- break;
103
-
104
- case 'watch':
105
- await this.watchContextChanges();
106
- break;
107
-
108
- case 'report':
109
- await this.generateReport(persona, output, save);
110
- break;
111
-
112
- default:
113
- console.error(`알 수 없는 작업: ${action}`);
114
- process.exit(1);
115
- }
116
- } catch (error) {
117
- console.error('오류 발생:', error.message);
118
- process.exit(1);
119
- }
120
- }
121
-
122
- /**
123
- * 컨텍스트 적용
124
- * @param {string} persona - 페르소나 이름
125
- * @param {string} prompt - 프롬프트
126
- * @param {string} outputFormat - 출력 형식
127
- * @param {boolean} save - 저장 여부
128
- */
129
- async applyContext(persona, prompt, outputFormat, save) {
130
- if (!persona || !prompt) {
131
- throw new Error('페르소나와 프롬프트를 모두 지정해야 합니다.');
132
- }
133
-
134
- console.log(`\n📋 페르소나 컨텍스트 적용: ${persona}`);
135
- console.log('━'.repeat(50));
136
-
137
- // 컨텍스트 적용
138
- const result = await this.promptInjector.injectContext(prompt, persona);
139
-
140
- if (!result.success) {
141
- throw new Error(`컨텍스트 적용 실패: ${result.error}`);
142
- }
143
-
144
- // 토큰 사용량 추적
145
- const tokenUsage = await this.tokenMonitor.trackContextUsage(result);
146
-
147
- // 결과 출력
148
- this.displayApplyResult(result, tokenUsage, outputFormat);
149
-
150
- // 저장
151
- if (save) {
152
- await this.saveResult({
153
- type: 'context_application',
154
- persona,
155
- result,
156
- tokenUsage
157
- });
158
- }
159
- }
160
-
161
- /**
162
- * 페르소나 전환
163
- * @param {string} persona - 새 페르소나
164
- */
165
- async switchPersona(persona) {
166
- if (!persona) {
167
- throw new Error('전환할 페르소나를 지정해야 합니다.');
168
- }
169
-
170
- console.log(`\n🔄 페르소나 전환: ${persona}`);
171
- console.log('━'.repeat(50));
172
-
173
- const switchResult = await this.promptInjector.switchPersona(persona);
174
-
175
- console.log(`이전 페르소나: ${switchResult.previousPersona || '없음'}`);
176
- console.log(`현재 페르소나: ${switchResult.currentPersona}`);
177
- console.log(`전환 시각: ${switchResult.switchedAt}`);
178
-
179
- // 새 컨텍스트 정보 표시
180
- if (switchResult.context) {
181
- console.log('\n새 페르소나 컨텍스트:');
182
- console.log(`- 분석 접근법: ${switchResult.context.analysis_approach}`);
183
- console.log(`- 소통 스타일: ${switchResult.context.communication_style}`);
184
- if (switchResult.context.design_principles) {
185
- console.log(`- 설계 원칙: ${switchResult.context.design_principles.join(', ')}`);
186
- }
187
- }
188
- }
189
-
190
- /**
191
- * 응답 검증
192
- * @param {string} persona - 페르소나
193
- * @param {string} response - 응답
194
- * @param {string} prompt - 원본 프롬프트
195
- * @param {string} outputFormat - 출력 형식
196
- */
197
- async validateResponse(persona, response, prompt, outputFormat) {
198
- if (!persona || !response) {
199
- throw new Error('페르소나와 응답을 모두 지정해야 합니다.');
200
- }
201
-
202
- console.log(`\n✅ 페르소나 행동 패턴 검증: ${persona}`);
203
- console.log('━'.repeat(50));
204
-
205
- const validation = this.behaviorValidator.validateResponse(
206
- response,
207
- persona,
208
- prompt || '검증용 프롬프트'
209
- );
210
-
211
- this.displayValidationResult(validation, outputFormat);
212
- }
213
-
214
- /**
215
- * 토큰 사용량 모니터링
216
- * @param {string} persona - 페르소나 (선택)
217
- * @param {string} outputFormat - 출력 형식
218
- */
219
- async monitorTokenUsage(persona, outputFormat) {
220
- console.log(`\n📊 토큰 사용량 모니터링${persona ? `: ${persona}` : ''}`);
221
- console.log('━'.repeat(50));
222
-
223
- const report = this.tokenMonitor.generateReport({
224
- personaName: persona,
225
- format: outputFormat === 'detailed' ? 'detailed' : 'summary'
226
- });
227
-
228
- this.displayTokenReport(report, outputFormat);
229
-
230
- // 최적화 제안
231
- if (persona) {
232
- const suggestions = this.tokenMonitor.getOptimizationSuggestions(persona);
233
- if (suggestions.suggestions && suggestions.suggestions.length > 0) {
234
- console.log('\n💡 최적화 제안:');
235
- suggestions.suggestions.forEach((suggestion, idx) => {
236
- console.log(`${idx + 1}. ${suggestion.message}`);
237
- });
238
- }
239
- }
240
- }
241
-
242
- /**
243
- * 품질 평가
244
- * @param {string} persona - 페르소나
245
- * @param {string} prompt - 프롬프트
246
- * @param {string} response - 응답
247
- * @param {string} outputFormat - 출력 형식
248
- */
249
- async evaluateQuality(persona, prompt, response, outputFormat) {
250
- if (!persona || !prompt || !response) {
251
- throw new Error('페르소나, 프롬프트, 응답을 모두 지정해야 합니다.');
252
- }
253
-
254
- console.log(`\n⭐ 응답 품질 평가: ${persona}`);
255
- console.log('━'.repeat(50));
256
-
257
- // 컨텍스트 로드
258
- const context = await this.contextParser.parseContextRules(persona);
259
-
260
- // 품질 평가
261
- const evaluation = await this.qualityEvaluator.evaluateResponse({
262
- prompt,
263
- response,
264
- personaName: persona,
265
- context
266
- });
267
-
268
- this.displayQualityEvaluation(evaluation, outputFormat);
269
- }
270
-
271
- /**
272
- * 컨텍스트 변경 감시
273
- */
274
- async watchContextChanges() {
275
- console.log('\n👁️ 컨텍스트 파일 실시간 감시 시작');
276
- console.log('━'.repeat(50));
277
-
278
- // 이벤트 핸들러 설정
279
- this.updateManager.on('contextUpdated', (data) => {
280
- console.log(`\n[${new Date().toISOString()}] 컨텍스트 업데이트 감지`);
281
- console.log(`- 페르소나: ${data.persona}`);
282
- console.log(`- 업데이트 유형: ${data.updateType}`);
283
- });
284
-
285
- this.updateManager.on('error', (data) => {
286
- console.error(`\n[오류] ${data.error.message}`);
287
- });
288
-
289
- // 감시 시작
290
- this.updateManager.startWatching();
291
-
292
- console.log('모든 페르소나 컨텍스트 파일을 감시 중입니다.');
293
- console.log('종료하려면 Ctrl+C를 누르세요.');
294
-
295
- // 프로세스 종료 처리
296
- process.on('SIGINT', () => {
297
- console.log('\n감시 중지 중...');
298
- this.updateManager.stopWatching();
299
- process.exit(0);
300
- });
301
-
302
- // 계속 실행
303
- await new Promise(() => {});
304
- }
305
-
306
- /**
307
- * 종합 리포트 생성
308
- * @param {string} persona - 페르소나 (선택)
309
- * @param {string} outputFormat - 출력 형식
310
- * @param {boolean} save - 저장 여부
311
- */
312
- async generateReport(persona, outputFormat, save) {
313
- console.log(`\n📑 종합 리포트 생성${persona ? `: ${persona}` : ''}`);
314
- console.log('━'.repeat(50));
315
-
316
- // 검증 통계
317
- const validationStats = this.behaviorValidator.generateStatistics(persona);
318
-
319
- // 품질 평가 통계
320
- const qualityStats = this.qualityEvaluator.generateStatistics(persona);
321
-
322
- // 토큰 사용량 리포트
323
- const tokenReport = this.tokenMonitor.generateReport({
324
- personaName: persona,
325
- format: 'summary'
326
- });
327
-
328
- const report = {
329
- generatedAt: new Date().toISOString(),
330
- persona: persona || 'all',
331
- validation: validationStats,
332
- quality: qualityStats,
333
- tokenUsage: tokenReport
334
- };
335
-
336
- this.displayComprehensiveReport(report, outputFormat);
337
-
338
- if (save) {
339
- const filename = `persona-report-${persona || 'all'}-${Date.now()}.json`;
340
- await this.saveResult(report, filename);
341
- }
342
- }
343
-
344
- /**
345
- * 적용 결과 표시
346
- * @param {Object} result - 적용 결과
347
- * @param {Object} tokenUsage - 토큰 사용량
348
- * @param {string} format - 출력 형식
349
- */
350
- displayApplyResult(result, tokenUsage, format) {
351
- if (format === 'json') {
352
- console.log(JSON.stringify({ result, tokenUsage }, null, 2));
353
- return;
354
- }
355
-
356
- console.log('\n✅ 컨텍스트 적용 완료');
357
- console.log(`페르소나: ${result.personaName}`);
358
- console.log(`원본 프롬프트 토큰: ${tokenUsage.originalTokens}`);
359
- console.log(`컨텍스트 토큰: ${tokenUsage.contextTokens}`);
360
- console.log(`전체 토큰: ${tokenUsage.totalTokens}`);
361
- console.log(`토큰 증가율: ${tokenUsage.percentageIncrease}`);
362
-
363
- if (tokenUsage.alert) {
364
- console.log(`\n⚠️ 알림: ${tokenUsage.alert.message}`);
365
- }
366
-
367
- if (format === 'detailed') {
368
- console.log('\n주입된 프롬프트:');
369
- console.log('─'.repeat(40));
370
- console.log(result.injectedPrompt);
371
- console.log('─'.repeat(40));
372
- }
373
- }
374
-
375
- /**
376
- * 검증 결과 표시
377
- * @param {Object} validation - 검증 결과
378
- * @param {string} format - 출력 형식
379
- */
380
- displayValidationResult(validation, format) {
381
- if (format === 'json') {
382
- console.log(JSON.stringify(validation, null, 2));
383
- return;
384
- }
385
-
386
- console.log(`\n검증 결과: ${validation.valid ? '✅ 유효' : '❌ 무효'}`);
387
- console.log(`전체 점수: ${(validation.overallScore * 100).toFixed(1)}%`);
388
-
389
- console.log('\n세부 점수:');
390
- console.log(`- 키워드 일치도: ${(validation.scores.keywordMatch * 100).toFixed(1)}%`);
391
- console.log(`- 구조 일치도: ${(validation.scores.structureMatch * 100).toFixed(1)}%`);
392
- console.log(`- 소통 스타일: ${(validation.scores.communicationMatch * 100).toFixed(1)}%`);
393
- console.log(`- 관심 영역: ${(validation.scores.focusMatch * 100).toFixed(1)}%`);
394
- }
395
-
396
- /**
397
- * 토큰 리포트 표시
398
- * @param {Object} report - 토큰 리포트
399
- * @param {string} format - 출력 형식
400
- */
401
- displayTokenReport(report, format) {
402
- if (format === 'json') {
403
- console.log(JSON.stringify(report, null, 2));
404
- return;
405
- }
406
-
407
- if (report.message) {
408
- console.log(report.message);
409
- return;
410
- }
411
-
412
- console.log(`\n기간: ${report.period.start} ~ ${report.period.end}`);
413
- console.log(`총 사용 횟수: ${report.totalUsages}`);
414
- console.log(`총 컨텍스트 토큰: ${report.tokenStats.total}`);
415
- console.log(`평균 컨텍스트 토큰: ${report.tokenStats.average}`);
416
-
417
- if (report.personaSummary) {
418
- console.log('\n페르소나별 요약:');
419
- Object.entries(report.personaSummary).forEach(([persona, stats]) => {
420
- console.log(`\n${persona}:`);
421
- console.log(` - 사용 횟수: ${stats.count}`);
422
- console.log(` - 총 토큰: ${stats.totalTokens}`);
423
- console.log(` - 평균 토큰: ${Math.round(stats.totalTokens / stats.count)}`);
424
- if (stats.alerts.warning > 0 || stats.alerts.critical > 0) {
425
- console.log(` - 알림: 경고 ${stats.alerts.warning}, 위험 ${stats.alerts.critical}`);
426
- }
427
- });
428
- }
429
-
430
- if (format === 'detailed' && report.trendAnalysis) {
431
- console.log(`\n트렌드: ${report.trendAnalysis.direction} (${report.trendAnalysis.changePercentage})`);
432
- if (report.trendAnalysis.prediction !== null) {
433
- console.log(`예상 다음 사용량: ${report.trendAnalysis.prediction} 토큰`);
434
- }
435
- }
436
- }
437
-
438
- /**
439
- * 품질 평가 표시
440
- * @param {Object} evaluation - 평가 결과
441
- * @param {string} format - 출력 형식
442
- */
443
- displayQualityEvaluation(evaluation, format) {
444
- if (format === 'json') {
445
- console.log(JSON.stringify(evaluation, null, 2));
446
- return;
447
- }
448
-
449
- console.log(`\n품질 수준: ${this.getQualityEmoji(evaluation.quality)} ${evaluation.quality}`);
450
- console.log(`최종 점수: ${(evaluation.scores.final * 100).toFixed(1)}%`);
451
-
452
- console.log('\n평가 항목:');
453
- Object.entries(evaluation.scores.individual).forEach(([metric, score]) => {
454
- const emoji = score >= 0.8 ? '✅' : score >= 0.6 ? '⚠️' : '❌';
455
- console.log(`${emoji} ${this.getMetricName(metric)}: ${(score * 100).toFixed(1)}%`);
456
- });
457
-
458
- if (evaluation.feedback && evaluation.feedback.length > 0) {
459
- console.log('\n피드백:');
460
- evaluation.feedback.forEach((fb) => {
461
- console.log(`- ${fb.message}`);
462
- });
463
- }
464
-
465
- if (evaluation.recommendations && evaluation.recommendations.length > 0) {
466
- console.log('\n권장사항:');
467
- evaluation.recommendations.forEach((rec) => {
468
- const priorityEmoji = rec.priority === 'high' ? '🔴' : '🟡';
469
- console.log(`${priorityEmoji} [${rec.area}] ${rec.suggestion}`);
470
- });
471
- }
472
- }
473
-
474
- /**
475
- * 종합 리포트 표시
476
- * @param {Object} report - 종합 리포트
477
- * @param {string} format - 출력 형식
478
- */
479
- displayComprehensiveReport(report, format) {
480
- if (format === 'json') {
481
- console.log(JSON.stringify(report, null, 2));
482
- return;
483
- }
484
-
485
- console.log('\n=== 행동 패턴 검증 통계 ===');
486
- if (report.validation.message) {
487
- console.log(report.validation.message);
488
- } else {
489
- console.log(`검증 횟수: ${report.validation.totalValidations}`);
490
- console.log(`유효율: ${report.validation.validationRate}`);
491
- console.log(`평균 점수: ${report.validation.averageScore}`);
492
- }
493
-
494
- console.log('\n=== 응답 품질 평가 통계 ===');
495
- if (report.quality.message) {
496
- console.log(report.quality.message);
497
- } else {
498
- console.log(`평가 횟수: ${report.quality.evaluationCount}`);
499
- console.log(`평균 최종 점수: ${report.quality.averageScores.final}`);
500
- console.log(`최고 성과 지표: ${this.getMetricName(report.quality.bestPerformingMetric)}`);
501
- console.log(`개선 필요 지표: ${this.getMetricName(report.quality.worstPerformingMetric)}`);
502
- }
503
-
504
- console.log('\n=== 토큰 사용량 요약 ===');
505
- if (report.tokenUsage.message) {
506
- console.log(report.tokenUsage.message);
507
- } else {
508
- console.log(`총 사용 횟수: ${report.tokenUsage.totalUsages}`);
509
- console.log(`평균 컨텍스트 토큰: ${report.tokenUsage.tokenStats.average}`);
510
- console.log(`알림 발생: 경고 ${report.tokenUsage.alerts.warning}, 위험 ${report.tokenUsage.alerts.critical}`);
511
- }
512
- }
513
-
514
- /**
515
- * 결과 저장
516
- * @param {Object} data - 저장할 데이터
517
- * @param {string} filename - 파일명 (선택)
518
- */
519
- async saveResult(data, filename) {
520
- const reportsDir = path.join(process.cwd(), '.aiwf', 'reports', 'persona-context');
521
- await fs.mkdir(reportsDir, { recursive: true });
522
-
523
- const defaultFilename = `${data.type || 'report'}-${Date.now()}.json`;
524
- const filepath = path.join(reportsDir, filename || defaultFilename);
525
-
526
- await fs.writeFile(filepath, JSON.stringify(data, null, 2), 'utf-8');
527
- console.log(`\n💾 결과 저장됨: ${filepath}`);
528
- }
529
-
530
- /**
531
- * 품질 수준 이모지 반환
532
- * @param {string} quality - 품질 수준
533
- * @returns {string} 이모지
534
- */
535
- getQualityEmoji(quality) {
536
- const emojis = {
537
- excellent: '🌟',
538
- good: '✨',
539
- fair: '⭐',
540
- poor: '💫'
541
- };
542
- return emojis[quality] || '❓';
543
- }
544
-
545
- /**
546
- * 지표 이름 한글 변환
547
- * @param {string} metric - 지표 키
548
- * @returns {string} 한글 이름
549
- */
550
- getMetricName(metric) {
551
- const names = {
552
- relevance: '관련성',
553
- consistency: '일관성',
554
- completeness: '완전성',
555
- clarity: '명확성',
556
- actionability: '실행가능성'
557
- };
558
- return names[metric] || metric;
559
- }
560
- }
561
-
562
- module.exports = PersonaContextApplyCommand;