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,89 +0,0 @@
1
- export default function HomePage() {
2
- return (
3
- <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
4
- <div className="text-center">
5
- <h2 className="text-3xl font-extrabold tracking-tight text-gray-900 dark:text-white sm:text-4xl">
6
- {{projectName}}에 오신 것을 환영합니다
7
- </h2>
8
- <p className="mt-4 max-w-2xl mx-auto text-xl text-gray-500 dark:text-gray-400">
9
- AIWF가 통합된 React + TypeScript 웹 애플리케이션입니다.
10
- </p>
11
- </div>
12
-
13
- <div className="mt-10">
14
- <dl className="space-y-10 md:space-y-0 md:grid md:grid-cols-2 md:gap-x-8 md:gap-y-10">
15
- <div className="relative">
16
- <dt>
17
- <div className="absolute flex items-center justify-center h-12 w-12 rounded-md bg-primary text-white">
18
- <svg className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
19
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" />
20
- </svg>
21
- </div>
22
- <p className="ml-16 text-lg leading-6 font-medium text-gray-900 dark:text-white">
23
- 빠른 개발
24
- </p>
25
- </dt>
26
- <dd className="mt-2 ml-16 text-base text-gray-500 dark:text-gray-400">
27
- Vite를 사용한 빠른 HMR과 빌드 속도
28
- </dd>
29
- </div>
30
-
31
- <div className="relative">
32
- <dt>
33
- <div className="absolute flex items-center justify-center h-12 w-12 rounded-md bg-primary text-white">
34
- <svg className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
35
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 6l3 1m0 0l-3 9a5.002 5.002 0 006.001 0M6 7l3 9M6 7l6-2m6 2l3-1m-3 1l-3 9a5.002 5.002 0 006.001 0M18 7l3 9m-3-9l-6-2m0-2v2m0 16V5m0 16H9m3 0h3" />
36
- </svg>
37
- </div>
38
- <p className="ml-16 text-lg leading-6 font-medium text-gray-900 dark:text-white">
39
- 타입 안정성
40
- </p>
41
- </dt>
42
- <dd className="mt-2 ml-16 text-base text-gray-500 dark:text-gray-400">
43
- TypeScript로 견고한 타입 시스템 구축
44
- </dd>
45
- </div>
46
-
47
- <div className="relative">
48
- <dt>
49
- <div className="absolute flex items-center justify-center h-12 w-12 rounded-md bg-primary text-white">
50
- <svg className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
51
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z" />
52
- </svg>
53
- </div>
54
- <p className="ml-16 text-lg leading-6 font-medium text-gray-900 dark:text-white">
55
- AIWF 통합
56
- </p>
57
- </dt>
58
- <dd className="mt-2 ml-16 text-base text-gray-500 dark:text-gray-400">
59
- AI 지원 개발 워크플로우 내장
60
- </dd>
61
- </div>
62
-
63
- <div className="relative">
64
- <dt>
65
- <div className="absolute flex items-center justify-center h-12 w-12 rounded-md bg-primary text-white">
66
- <svg className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
67
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 3v4M3 5h4M6 17v4m-2-2h4m5-16l2.286 6.857L21 12l-5.714 2.143L13 21l-2.286-6.857L5 12l5.714-2.143L13 3z" />
68
- </svg>
69
- </div>
70
- <p className="ml-16 text-lg leading-6 font-medium text-gray-900 dark:text-white">
71
- 모던 스타일링
72
- </p>
73
- </dt>
74
- <dd className="mt-2 ml-16 text-base text-gray-500 dark:text-gray-400">
75
- Tailwind CSS로 빠른 UI 개발
76
- </dd>
77
- </div>
78
- </dl>
79
- </div>
80
-
81
- <div className="mt-10 text-center">
82
- <h3 className="text-lg font-medium text-gray-900 dark:text-white">시작하기</h3>
83
- <div className="mt-3 text-base text-gray-500 dark:text-gray-400">
84
- <code className="bg-gray-100 dark:bg-gray-800 px-2 py-1 rounded">npm run dev</code>로 개발 서버를 시작하세요.
85
- </div>
86
- </div>
87
- </div>
88
- )
89
- }
@@ -1,25 +0,0 @@
1
- import { Link } from 'react-router-dom'
2
-
3
- export default function NotFound() {
4
- return (
5
- <div className="min-h-[60vh] flex items-center justify-center px-4 sm:px-6 lg:px-8">
6
- <div className="text-center">
7
- <p className="text-base font-semibold text-primary">404</p>
8
- <h1 className="mt-2 text-4xl font-bold text-gray-900 dark:text-white tracking-tight sm:text-5xl">
9
- 페이지를 찾을 수 없습니다
10
- </h1>
11
- <p className="mt-2 text-base text-gray-500 dark:text-gray-400">
12
- 요청하신 페이지가 존재하지 않습니다.
13
- </p>
14
- <div className="mt-6">
15
- <Link
16
- to="/"
17
- className="text-base font-medium text-primary hover:text-primary/80"
18
- >
19
- 홈으로 돌아가기<span aria-hidden="true"> &rarr;</span>
20
- </Link>
21
- </div>
22
- </div>
23
- </div>
24
- )
25
- }
@@ -1,126 +0,0 @@
1
- import { create } from 'zustand'
2
-
3
- interface Feature {
4
- id: string
5
- name: string
6
- description: string
7
- status: 'completed' | 'in_progress' | 'planned'
8
- type: string
9
- created_at: string
10
- completed_at?: string
11
- tags: string[]
12
- }
13
-
14
- interface TokenUsageData {
15
- total: number
16
- used: number
17
- remaining: number
18
- percentage: number
19
- history: Array<{
20
- date: string
21
- tokens: number
22
- action: string
23
- }>
24
- }
25
-
26
- interface ContextStatusData {
27
- compressionLevel: 'none' | 'balanced' | 'aggressive'
28
- cacheEnabled: boolean
29
- cacheSize: number
30
- maxCacheSize: number
31
- lastCompression: string
32
- savedTokens: number
33
- activePersona: string
34
- }
35
-
36
- interface AiwfStore {
37
- features: Feature[]
38
- tokenUsage: TokenUsageData
39
- contextStatus: ContextStatusData
40
- loadDashboardData: () => Promise<void>
41
- updateFeature: (featureId: string, updates: Partial<Feature>) => void
42
- addFeature: (feature: Feature) => void
43
- }
44
-
45
- export const useAiwfStore = create<AiwfStore>((set) => ({
46
- features: [],
47
- tokenUsage: {
48
- total: 100000,
49
- used: 45000,
50
- remaining: 55000,
51
- percentage: 45,
52
- history: []
53
- },
54
- contextStatus: {
55
- compressionLevel: 'balanced',
56
- cacheEnabled: true,
57
- cacheSize: 5242880, // 5MB
58
- maxCacheSize: 52428800, // 50MB
59
- lastCompression: new Date().toISOString(),
60
- savedTokens: 15000,
61
- activePersona: 'fullstack-developer'
62
- },
63
-
64
- loadDashboardData: async () => {
65
- try {
66
- // 실제 구현에서는 API를 호출하거나 로컬 파일을 읽습니다
67
- const mockFeatures: Feature[] = [
68
- {
69
- id: 'F001',
70
- name: '프로젝트 초기 설정',
71
- description: 'React + TypeScript + Vite 기반 웹 애플리케이션 초기 설정',
72
- type: 'setup',
73
- status: 'completed',
74
- created_at: new Date().toISOString(),
75
- completed_at: new Date().toISOString(),
76
- tags: ['초기설정', '인프라', '설정']
77
- }
78
- ]
79
-
80
- const mockHistory = [
81
- {
82
- date: new Date().toISOString(),
83
- tokens: 1500,
84
- action: '컴포넌트 생성'
85
- },
86
- {
87
- date: new Date(Date.now() - 3600000).toISOString(),
88
- tokens: 2300,
89
- action: 'API 통합'
90
- },
91
- {
92
- date: new Date(Date.now() - 7200000).toISOString(),
93
- tokens: 800,
94
- action: '코드 리뷰'
95
- }
96
- ]
97
-
98
- set({
99
- features: mockFeatures,
100
- tokenUsage: {
101
- total: 100000,
102
- used: 45000,
103
- remaining: 55000,
104
- percentage: 45,
105
- history: mockHistory
106
- }
107
- })
108
- } catch (error) {
109
- console.error('Failed to load AIWF dashboard data:', error)
110
- }
111
- },
112
-
113
- updateFeature: (featureId, updates) => {
114
- set((state) => ({
115
- features: state.features.map((feature) =>
116
- feature.id === featureId ? { ...feature, ...updates } : feature
117
- )
118
- }))
119
- },
120
-
121
- addFeature: (feature) => {
122
- set((state) => ({
123
- features: [...state.features, feature]
124
- }))
125
- }
126
- }))
@@ -1,9 +0,0 @@
1
- interface Window {
2
- aiwf: {
3
- trackPage: (path: string) => void
4
- trackEvent: (event: string, data?: any) => void
5
- getFeatures: () => Promise<any[]>
6
- getTokenUsage: () => Promise<any>
7
- getContextStatus: () => Promise<any>
8
- }
9
- }
@@ -1 +0,0 @@
1
- /// <reference types="vite/client" />
@@ -1,30 +0,0 @@
1
- /** @type {import('tailwindcss').Config} */
2
- export default {
3
- content: [
4
- "./index.html",
5
- "./src/**/*.{js,ts,jsx,tsx}",
6
- ],
7
- theme: {
8
- extend: {
9
- colors: {
10
- primary: {
11
- 50: '#eff6ff',
12
- 100: '#dbeafe',
13
- 200: '#bfdbfe',
14
- 300: '#93bbfd',
15
- 400: '#60a5fa',
16
- 500: '#3b82f6',
17
- 600: '#2563eb',
18
- 700: '#1d4ed8',
19
- 800: '#1e40af',
20
- 900: '#1e3a8a',
21
- 950: '#172554',
22
- }
23
- },
24
- fontFamily: {
25
- sans: ['Pretendard', 'Inter', 'system-ui', 'sans-serif'],
26
- }
27
- },
28
- },
29
- plugins: [],
30
- }
@@ -1,37 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2020",
4
- "useDefineForClassFields": true,
5
- "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
- "module": "ESNext",
7
- "skipLibCheck": true,
8
-
9
- /* Bundler mode */
10
- "moduleResolution": "bundler",
11
- "allowImportingTsExtensions": true,
12
- "resolveJsonModule": true,
13
- "isolatedModules": true,
14
- "noEmit": true,
15
- "jsx": "react-jsx",
16
-
17
- /* Linting */
18
- "strict": true,
19
- "noUnusedLocals": true,
20
- "noUnusedParameters": true,
21
- "noFallthroughCasesInSwitch": true,
22
-
23
- /* Path Aliases */
24
- "baseUrl": ".",
25
- "paths": {
26
- "@/*": ["src/*"],
27
- "@components/*": ["src/components/*"],
28
- "@pages/*": ["src/pages/*"],
29
- "@hooks/*": ["src/hooks/*"],
30
- "@utils/*": ["src/utils/*"],
31
- "@stores/*": ["src/stores/*"],
32
- "@types/*": ["src/types/*"]
33
- }
34
- },
35
- "include": ["src"],
36
- "references": [{ "path": "./tsconfig.node.json" }]
37
- }
@@ -1,10 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "composite": true,
4
- "skipLibCheck": true,
5
- "module": "ESNext",
6
- "moduleResolution": "bundler",
7
- "allowSyntheticDefaultImports": true
8
- },
9
- "include": ["vite.config.ts"]
10
- }
@@ -1,23 +0,0 @@
1
- import { defineConfig } from 'vite'
2
- import react from '@vitejs/plugin-react'
3
- import path from 'path'
4
-
5
- // https://vitejs.dev/config/
6
- export default defineConfig({
7
- plugins: [react()],
8
- resolve: {
9
- alias: {
10
- '@': path.resolve(__dirname, './src'),
11
- '@components': path.resolve(__dirname, './src/components'),
12
- '@pages': path.resolve(__dirname, './src/pages'),
13
- '@hooks': path.resolve(__dirname, './src/hooks'),
14
- '@utils': path.resolve(__dirname, './src/utils'),
15
- '@stores': path.resolve(__dirname, './src/stores'),
16
- '@types': path.resolve(__dirname, './src/types'),
17
- }
18
- },
19
- server: {
20
- port: 3000,
21
- host: true
22
- }
23
- })
@@ -1,223 +0,0 @@
1
- /**
2
- * 백그라운드 평가 모니터
3
- * 사용자 작업을 방해하지 않고 품질 모니터링
4
- */
5
-
6
- import { SimplifiedEvaluator } from './simplified-evaluator.js';
7
- import fs from 'fs/promises';
8
- import path from 'path';
9
-
10
- export class BackgroundMonitor {
11
- constructor() {
12
- this.evaluator = new SimplifiedEvaluator();
13
- this.recentEvaluations = [];
14
- this.maxHistorySize = 100;
15
- this.statsFile = null;
16
- this.initialized = false;
17
- }
18
-
19
- /**
20
- * 모니터 초기화
21
- */
22
- async initialize() {
23
- if (this.initialized) return;
24
-
25
- try {
26
- // 프로젝트 루트의 .aiwf 디렉토리 찾기
27
- const projectRoot = await this.findProjectRoot();
28
- if (projectRoot) {
29
- this.statsFile = path.join(projectRoot, '.aiwf', '.evaluation-stats.json');
30
- await this.loadStats();
31
- }
32
- this.initialized = true;
33
- } catch (error) {
34
- // 초기화 실패해도 기본 기능은 작동
35
- this.initialized = true;
36
- }
37
- }
38
-
39
- /**
40
- * 프로젝트 루트 찾기
41
- */
42
- async findProjectRoot() {
43
- let currentDir = process.cwd();
44
-
45
- while (currentDir !== path.dirname(currentDir)) {
46
- try {
47
- await fs.access(path.join(currentDir, '.aiwf'));
48
- return currentDir;
49
- } catch {
50
- currentDir = path.dirname(currentDir);
51
- }
52
- }
53
-
54
- return null;
55
- }
56
-
57
- /**
58
- * 통계 로드
59
- */
60
- async loadStats() {
61
- if (!this.statsFile) return;
62
-
63
- try {
64
- const data = await fs.readFile(this.statsFile, 'utf8');
65
- const stats = JSON.parse(data);
66
- this.recentEvaluations = stats.recentEvaluations || [];
67
- } catch {
68
- // 파일이 없으면 새로 시작
69
- this.recentEvaluations = [];
70
- }
71
- }
72
-
73
- /**
74
- * 통계 저장 (비동기, 에러 무시)
75
- */
76
- async saveStats() {
77
- if (!this.statsFile) return;
78
-
79
- try {
80
- const stats = {
81
- recentEvaluations: this.recentEvaluations.slice(-this.maxHistorySize),
82
- lastUpdated: new Date().toISOString()
83
- };
84
-
85
- await fs.writeFile(this.statsFile, JSON.stringify(stats, null, 2));
86
- } catch {
87
- // 저장 실패해도 무시
88
- }
89
- }
90
-
91
- /**
92
- * 백그라운드에서 응답 모니터링
93
- */
94
- async monitorResponse(response, persona, options = {}) {
95
- // 초기화 확인
96
- if (!this.initialized) {
97
- await this.initialize();
98
- }
99
-
100
- // 빠른 평가 수행
101
- const evaluation = this.evaluator.quickEvaluate(response, persona);
102
-
103
- // 기록 추가
104
- this.recentEvaluations.push({
105
- persona,
106
- score: evaluation.score,
107
- timestamp: new Date().toISOString(),
108
- responseLength: response.length
109
- });
110
-
111
- // 크기 제한
112
- if (this.recentEvaluations.length > this.maxHistorySize) {
113
- this.recentEvaluations = this.recentEvaluations.slice(-this.maxHistorySize);
114
- }
115
-
116
- // 비동기 저장 (차단하지 않음)
117
- this.saveStats().catch(() => {});
118
-
119
- // 피드백이 필요한 경우만 반환
120
- if (evaluation.needsFeedback && !options.silent) {
121
- return {
122
- feedback: evaluation.feedback,
123
- score: evaluation.score
124
- };
125
- }
126
-
127
- return null;
128
- }
129
-
130
- /**
131
- * 최근 통계 요약
132
- */
133
- getRecentStats(persona = null) {
134
- let evaluations = this.recentEvaluations;
135
-
136
- if (persona) {
137
- evaluations = evaluations.filter(e => e.persona === persona);
138
- }
139
-
140
- if (evaluations.length === 0) {
141
- return { message: '아직 평가 기록이 없습니다.' };
142
- }
143
-
144
- const scores = evaluations.map(e => e.score);
145
- const avgScore = scores.reduce((sum, s) => sum + s, 0) / scores.length;
146
-
147
- // 페르소나별 통계
148
- const personaStats = {};
149
- evaluations.forEach(e => {
150
- if (!personaStats[e.persona]) {
151
- personaStats[e.persona] = { count: 0, totalScore: 0 };
152
- }
153
- personaStats[e.persona].count++;
154
- personaStats[e.persona].totalScore += e.score;
155
- });
156
-
157
- Object.keys(personaStats).forEach(p => {
158
- const stats = personaStats[p];
159
- stats.avgScore = (stats.totalScore / stats.count).toFixed(2);
160
- delete stats.totalScore;
161
- });
162
-
163
- return {
164
- totalEvaluations: evaluations.length,
165
- averageScore: avgScore.toFixed(2),
166
- personaStats,
167
- trend: this.calculateTrend(scores)
168
- };
169
- }
170
-
171
- /**
172
- * 점수 추세 계산
173
- */
174
- calculateTrend(scores) {
175
- if (scores.length < 2) return 'stable';
176
-
177
- const recent = scores.slice(-10);
178
- const older = scores.slice(-20, -10);
179
-
180
- if (older.length === 0) return 'stable';
181
-
182
- const recentAvg = recent.reduce((sum, s) => sum + s, 0) / recent.length;
183
- const olderAvg = older.reduce((sum, s) => sum + s, 0) / older.length;
184
-
185
- if (recentAvg > olderAvg + 0.1) return 'improving';
186
- if (recentAvg < olderAvg - 0.1) return 'declining';
187
- return 'stable';
188
- }
189
-
190
- /**
191
- * 주간 요약 생성
192
- */
193
- getWeeklySummary() {
194
- const oneWeekAgo = new Date();
195
- oneWeekAgo.setDate(oneWeekAgo.getDate() - 7);
196
-
197
- const weeklyEvals = this.recentEvaluations.filter(e =>
198
- new Date(e.timestamp) > oneWeekAgo
199
- );
200
-
201
- if (weeklyEvals.length === 0) {
202
- return { message: '최근 일주일간 평가 기록이 없습니다.' };
203
- }
204
-
205
- const summary = this.getRecentStats();
206
- summary.period = 'weekly';
207
- summary.evaluationCount = weeklyEvals.length;
208
-
209
- return summary;
210
- }
211
- }
212
-
213
- // 싱글톤 인스턴스
214
- let monitorInstance = null;
215
-
216
- export function getBackgroundMonitor() {
217
- if (!monitorInstance) {
218
- monitorInstance = new BackgroundMonitor();
219
- }
220
- return monitorInstance;
221
- }
222
-
223
- export default BackgroundMonitor;