aiwf 0.3.6 → 0.3.8

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 (271) hide show
  1. package/.aiwf/00_PROJECT_MANIFEST.md +226 -2
  2. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/S03_M02_sprint_meta.md +112 -0
  3. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T01_S03_new_test_task.md +39 -0
  4. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T02_S03_first_task.md +39 -0
  5. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T03_S03_test_task.md +39 -0
  6. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T04_S03_task_with_special_characters.md +39 -0
  7. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T05_S03_test.md +39 -0
  8. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T06_S03_test_task.md +39 -0
  9. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T07_S03_next_task.md +39 -0
  10. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T08_S03_next_task.md +39 -0
  11. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T09_S03_new_test_task.md +39 -0
  12. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T100_S03_task_with_special_characters.md +39 -0
  13. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T101_S03_test.md +39 -0
  14. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T102_S03_test_task.md +39 -0
  15. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T103_S03_next_task.md +39 -0
  16. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T104_S03_next_task.md +39 -0
  17. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T105_S03_new_test_task.md +39 -0
  18. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T106_S03_first_task.md +39 -0
  19. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T107_S03_test_task.md +39 -0
  20. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T108_S03_task_with_special_characters.md +39 -0
  21. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T109_S03_test.md +39 -0
  22. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T10_S03_first_task.md +39 -0
  23. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T110_S03_test_task.md +39 -0
  24. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T111_S03_next_task.md +39 -0
  25. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T112_S03_next_task.md +39 -0
  26. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T11_S03_test_task.md +39 -0
  27. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T12_S03_task_with_special_characters.md +39 -0
  28. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T13_S03_test.md +39 -0
  29. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T14_S03_test_task.md +39 -0
  30. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T15_S03_next_task.md +39 -0
  31. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T16_S03_next_task.md +39 -0
  32. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T17_S03_new_test_task.md +39 -0
  33. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T18_S03_first_task.md +39 -0
  34. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T19_S03_test_task.md +39 -0
  35. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T20_S03_task_with_special_characters.md +39 -0
  36. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T21_S03_test.md +39 -0
  37. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T22_S03_test_task.md +39 -0
  38. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T23_S03_next_task.md +39 -0
  39. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T24_S03_next_task.md +39 -0
  40. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T25_S03_new_test_task.md +39 -0
  41. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T26_S03_first_task.md +39 -0
  42. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T27_S03_test_task.md +39 -0
  43. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T28_S03_task_with_special_characters.md +39 -0
  44. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T29_S03_test.md +39 -0
  45. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T30_S03_test_task.md +39 -0
  46. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T31_S03_next_task.md +39 -0
  47. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T32_S03_next_task.md +39 -0
  48. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T33_S03_new_test_task.md +39 -0
  49. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T34_S03_first_task.md +39 -0
  50. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T35_S03_test_task.md +39 -0
  51. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T36_S03_task_with_special_characters.md +39 -0
  52. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T37_S03_test.md +39 -0
  53. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T38_S03_test_task.md +39 -0
  54. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T39_S03_next_task.md +39 -0
  55. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T40_S03_next_task.md +39 -0
  56. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T41_S03_new_test_task.md +39 -0
  57. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T42_S03_first_task.md +39 -0
  58. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T43_S03_test_task.md +39 -0
  59. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T44_S03_task_with_special_characters.md +39 -0
  60. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T45_S03_test.md +39 -0
  61. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T46_S03_test_task.md +39 -0
  62. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T47_S03_next_task.md +39 -0
  63. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T48_S03_next_task.md +39 -0
  64. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T49_S03_new_test_task.md +39 -0
  65. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T50_S03_first_task.md +39 -0
  66. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T51_S03_test_task.md +39 -0
  67. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T52_S03_task_with_special_characters.md +39 -0
  68. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T53_S03_test.md +39 -0
  69. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T54_S03_test_task.md +39 -0
  70. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T55_S03_next_task.md +39 -0
  71. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T56_S03_next_task.md +39 -0
  72. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T57_S03_new_test_task.md +39 -0
  73. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T58_S03_first_task.md +39 -0
  74. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T59_S03_test_task.md +39 -0
  75. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T60_S03_task_with_special_characters.md +39 -0
  76. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T61_S03_test.md +39 -0
  77. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T62_S03_test_task.md +39 -0
  78. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T63_S03_next_task.md +39 -0
  79. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T64_S03_next_task.md +39 -0
  80. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T65_S03_new_test_task.md +39 -0
  81. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T66_S03_first_task.md +39 -0
  82. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T67_S03_test_task.md +39 -0
  83. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T68_S03_task_with_special_characters.md +39 -0
  84. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T69_S03_test.md +39 -0
  85. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T70_S03_test_task.md +39 -0
  86. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T71_S03_next_task.md +39 -0
  87. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T72_S03_next_task.md +39 -0
  88. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T73_S03_new_test_task.md +39 -0
  89. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T74_S03_first_task.md +39 -0
  90. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T75_S03_test_task.md +39 -0
  91. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T76_S03_task_with_special_characters.md +39 -0
  92. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T77_S03_test.md +39 -0
  93. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T78_S03_test_task.md +39 -0
  94. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T79_S03_next_task.md +39 -0
  95. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T80_S03_next_task.md +39 -0
  96. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T81_S03_new_test_task.md +39 -0
  97. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T82_S03_first_task.md +39 -0
  98. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T83_S03_test_task.md +39 -0
  99. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T84_S03_task_with_special_characters.md +39 -0
  100. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T85_S03_test.md +39 -0
  101. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T86_S03_test_task.md +39 -0
  102. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T87_S03_next_task.md +39 -0
  103. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T88_S03_next_task.md +39 -0
  104. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T89_S03_new_test_task.md +39 -0
  105. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T90_S03_first_task.md +39 -0
  106. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T91_S03_test_task.md +39 -0
  107. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T92_S03_task_with_special_characters.md +39 -0
  108. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T93_S03_test.md +39 -0
  109. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T94_S03_test_task.md +39 -0
  110. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T95_S03_next_task.md +39 -0
  111. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T96_S03_next_task.md +39 -0
  112. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T97_S03_new_test_task.md +39 -0
  113. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T98_S03_first_task.md +39 -0
  114. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T99_S03_test_task.md +39 -0
  115. package/.aiwf/test-results-s02.json +5 -5
  116. package/.claude/commands/aiwf/aiwf_compress_aggressive_persona.md +3 -15
  117. package/.claude/commands/aiwf/aiwf_compress_minimal_persona.md +2 -15
  118. package/.claude/commands/aiwf/aiwf_compress_stats.md +2 -51
  119. package/.claude/commands/aiwf/aiwf_compress_with_persona.md +5 -18
  120. package/.claude/commands/aiwf/aiwf_create_feature_ledger.md +1 -1
  121. package/.claude/commands/aiwf/aiwf_default_mode.md +1 -1
  122. package/.claude/commands/aiwf/aiwf_evaluate.md +3 -16
  123. package/.claude/commands/aiwf/aiwf_get_feature_details.md +1 -1
  124. package/.claude/commands/aiwf/aiwf_link_feature_to_milestone.md +1 -1
  125. package/.claude/commands/aiwf/aiwf_list_features.md +1 -1
  126. package/.claude/commands/aiwf/aiwf_switch_language.md +48 -120
  127. package/.claude/commands/aiwf/aiwf_update_feature_status.md +1 -1
  128. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_create_testcase.md +561 -0
  129. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_compress_aggressive_persona.md +2 -2
  130. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_compress_minimal_persona.md +2 -2
  131. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_compress_stats.md +10 -47
  132. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_compress_with_persona.md +2 -2
  133. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_create_feature_ledger.md +1 -1
  134. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_create_testcase.md +561 -0
  135. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_default_mode.md +1 -1
  136. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_evaluate.md +2 -2
  137. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_get_feature_details.md +1 -1
  138. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_link_feature_to_milestone.md +1 -1
  139. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_list_features.md +1 -1
  140. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_architect.md +1 -1
  141. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_backend.md +1 -1
  142. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_data_analyst.md +1 -1
  143. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_frontend.md +1 -1
  144. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_security.md +1 -1
  145. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_status.md +1 -1
  146. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_update_feature_status.md +1 -1
  147. package/package.json +1 -1
  148. package/src/cli/index.js +174 -0
  149. package/src/commands/compress.js +60 -0
  150. package/src/commands/create-project.js +23 -17
  151. package/src/commands/evaluate.js +459 -0
  152. package/src/commands/feature.js +365 -0
  153. package/src/commands/persona.js +37 -16
  154. package/src/commands/token.js +312 -0
  155. package/src/lib/file-downloader.js +189 -33
  156. package/src/lib/installer.js +38 -11
  157. package/src/lib/resource-loader.js +250 -0
  158. package/src/lib/resources/commands/ai-persona.js +602 -0
  159. package/src/lib/resources/commands/compress-context.js +389 -0
  160. package/src/lib/resources/commands/evaluate.js +246 -0
  161. package/src/lib/resources/commands/feature-ledger.js +565 -0
  162. package/src/lib/resources/commands/feature_commit_report.js +370 -0
  163. package/src/lib/resources/commands/persona-context-apply.js +562 -0
  164. package/src/lib/resources/commands/scan_git_history.js +234 -0
  165. package/src/lib/resources/commands/sync_feature_commits.js +154 -0
  166. package/src/lib/resources/commands/token-tracking.js +443 -0
  167. package/src/lib/resources/config/commit-patterns.js +103 -0
  168. package/src/lib/resources/config/language.json +6 -0
  169. package/src/lib/resources/personas/PERSONA_INDEX.md +57 -0
  170. package/src/lib/resources/personas/analyst.json +44 -0
  171. package/src/lib/resources/personas/architect/best_practices.md +136 -0
  172. package/src/lib/resources/personas/architect/knowledge_base.md +377 -0
  173. package/src/lib/resources/personas/architect.json +44 -0
  174. package/src/lib/resources/personas/backend/best_practices.md +766 -0
  175. package/src/lib/resources/personas/backend/knowledge_base.md +1070 -0
  176. package/src/lib/resources/personas/data_analyst/best_practices.md +594 -0
  177. package/src/lib/resources/personas/data_analyst/knowledge_base.md +1057 -0
  178. package/src/lib/resources/personas/developer.json +44 -0
  179. package/src/lib/resources/personas/developer.md +37 -0
  180. package/src/lib/resources/personas/evaluation_criteria.json +137 -0
  181. package/src/lib/resources/personas/frontend/best_practices.md +445 -0
  182. package/src/lib/resources/personas/frontend/knowledge_base.md +729 -0
  183. package/src/lib/resources/personas/persona-index.json +31 -0
  184. package/src/lib/resources/personas/reviewer.json +44 -0
  185. package/src/lib/resources/personas/security/best_practices.md +307 -0
  186. package/src/lib/resources/personas/security/knowledge_base.md +498 -0
  187. package/src/lib/resources/personas/tester.json +44 -0
  188. package/src/lib/resources/templates/README.md +78 -0
  189. package/src/lib/resources/templates/api-server/config.json +64 -0
  190. package/src/lib/resources/templates/api-server/template/.aiwf/config.json +56 -0
  191. package/src/lib/resources/templates/api-server/template/.aiwf/feature-ledger.json +42 -0
  192. package/src/lib/resources/templates/api-server/template/.aiwf/personas/backend-engineer.json +40 -0
  193. package/src/lib/resources/templates/api-server/template/.aiwf/scripts/cli.js +111 -0
  194. package/src/lib/resources/templates/api-server/template/.env.example +29 -0
  195. package/src/lib/resources/templates/api-server/template/.eslintrc.json +23 -0
  196. package/src/lib/resources/templates/api-server/template/README.md +171 -0
  197. package/src/lib/resources/templates/api-server/template/jest.config.js +26 -0
  198. package/src/lib/resources/templates/api-server/template/nodemon.json +9 -0
  199. package/src/lib/resources/templates/api-server/template/package.json +61 -0
  200. package/src/lib/resources/templates/api-server/template/src/app.ts +60 -0
  201. package/src/lib/resources/templates/api-server/template/src/config/swagger.ts +38 -0
  202. package/src/lib/resources/templates/api-server/template/src/controllers/aiwfController.ts +68 -0
  203. package/src/lib/resources/templates/api-server/template/src/controllers/authController.ts +128 -0
  204. package/src/lib/resources/templates/api-server/template/src/controllers/statusController.ts +28 -0
  205. package/src/lib/resources/templates/api-server/template/src/index.ts +28 -0
  206. package/src/lib/resources/templates/api-server/template/src/middleware/aiwfMiddleware.ts +50 -0
  207. package/src/lib/resources/templates/api-server/template/src/middleware/authMiddleware.ts +41 -0
  208. package/src/lib/resources/templates/api-server/template/src/middleware/errorHandler.ts +42 -0
  209. package/src/lib/resources/templates/api-server/template/src/middleware/notFoundHandler.ts +14 -0
  210. package/src/lib/resources/templates/api-server/template/src/middleware/requestLogger.ts +20 -0
  211. package/src/lib/resources/templates/api-server/template/src/routes/aiwf.ts +42 -0
  212. package/src/lib/resources/templates/api-server/template/src/routes/index.ts +13 -0
  213. package/src/lib/resources/templates/api-server/template/src/routes/v1/index.ts +67 -0
  214. package/src/lib/resources/templates/api-server/template/src/utils/logger.ts +37 -0
  215. package/src/lib/resources/templates/api-server/template/tests/app.test.ts +40 -0
  216. package/src/lib/resources/templates/api-server/template/tsconfig.json +43 -0
  217. package/src/lib/resources/templates/npm-library/config.json +61 -0
  218. package/src/lib/resources/templates/npm-library/template/LICENSE +21 -0
  219. package/src/lib/resources/templates/npm-library/template/README.md +201 -0
  220. package/src/lib/resources/templates/npm-library/template/package.json +78 -0
  221. package/src/lib/resources/templates/web-app/config.json +53 -0
  222. package/src/lib/resources/templates/web-app/template/.aiwf/config.json +54 -0
  223. package/src/lib/resources/templates/web-app/template/.aiwf/feature-ledger.json +37 -0
  224. package/src/lib/resources/templates/web-app/template/.aiwf/personas/fullstack-developer.json +40 -0
  225. package/src/lib/resources/templates/web-app/template/.aiwf/scripts/cli.js +110 -0
  226. package/src/lib/resources/templates/web-app/template/.eslintrc.cjs +20 -0
  227. package/src/lib/resources/templates/web-app/template/README.md +151 -0
  228. package/src/lib/resources/templates/web-app/template/index.html +14 -0
  229. package/src/lib/resources/templates/web-app/template/package.json +44 -0
  230. package/src/lib/resources/templates/web-app/template/postcss.config.js +6 -0
  231. package/src/lib/resources/templates/web-app/template/public/vite.svg +1 -0
  232. package/src/lib/resources/templates/web-app/template/src/App.tsx +21 -0
  233. package/src/lib/resources/templates/web-app/template/src/components/Layout.tsx +57 -0
  234. package/src/lib/resources/templates/web-app/template/src/components/aiwf/ContextStatus.tsx +107 -0
  235. package/src/lib/resources/templates/web-app/template/src/components/aiwf/FeatureLedger.tsx +93 -0
  236. package/src/lib/resources/templates/web-app/template/src/components/aiwf/TokenUsage.tsx +71 -0
  237. package/src/lib/resources/templates/web-app/template/src/index.css +60 -0
  238. package/src/lib/resources/templates/web-app/template/src/main.tsx +10 -0
  239. package/src/lib/resources/templates/web-app/template/src/pages/AiwfDashboard.tsx +60 -0
  240. package/src/lib/resources/templates/web-app/template/src/pages/HomePage.tsx +89 -0
  241. package/src/lib/resources/templates/web-app/template/src/pages/NotFound.tsx +25 -0
  242. package/src/lib/resources/templates/web-app/template/src/stores/aiwfStore.ts +126 -0
  243. package/src/lib/resources/templates/web-app/template/src/types/global.d.ts +9 -0
  244. package/src/lib/resources/templates/web-app/template/src/vite-env.d.ts +1 -0
  245. package/src/lib/resources/templates/web-app/template/tailwind.config.js +30 -0
  246. package/src/lib/resources/templates/web-app/template/tsconfig.json +37 -0
  247. package/src/lib/resources/templates/web-app/template/tsconfig.node.json +10 -0
  248. package/src/lib/resources/templates/web-app/template/vite.config.ts +23 -0
  249. package/src/lib/resources/utils/background-monitor.js +223 -0
  250. package/src/lib/resources/utils/compression-metrics.js +1031 -0
  251. package/src/lib/resources/utils/compression-strategies.js +557 -0
  252. package/src/lib/resources/utils/content-normalizer.js +455 -0
  253. package/src/lib/resources/utils/context-compressor.js +583 -0
  254. package/src/lib/resources/utils/context-rule-parser.js +180 -0
  255. package/src/lib/resources/utils/context-token-monitor.js +463 -0
  256. package/src/lib/resources/utils/context-update-manager.js +502 -0
  257. package/src/lib/resources/utils/feature-updater.js +271 -0
  258. package/src/lib/resources/utils/git-utils.js +220 -0
  259. package/src/lib/resources/utils/importance-classifier.js +645 -0
  260. package/src/lib/resources/utils/information-filter.js +710 -0
  261. package/src/lib/resources/utils/persona-aware-compressor.js +598 -0
  262. package/src/lib/resources/utils/prompt-injector.js +242 -0
  263. package/src/lib/resources/utils/simplified-evaluator.js +119 -0
  264. package/src/lib/resources/utils/text-summarizer.js +492 -0
  265. package/src/lib/resources/utils/token-counter.js +177 -0
  266. package/src/lib/resources/utils/token-monitor.js +484 -0
  267. package/src/lib/resources/utils/token-reporter.js +453 -0
  268. package/src/lib/resources/utils/token-storage.js +433 -0
  269. package/src/lib/resources/utils/token-tracker.js +283 -0
  270. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_switch_language.md +0 -160
  271. /package/claude-code/aiwf/ko/.claude/commands/aiwf/{aiwf_update_docs_kr.md → aiwf_update_docs.md} +0 -0
@@ -0,0 +1,60 @@
1
+ import { useState, useEffect } from 'react'
2
+ import { useAiwfStore } from '@/stores/aiwfStore'
3
+ import FeatureLedger from '@/components/aiwf/FeatureLedger'
4
+ import TokenUsage from '@/components/aiwf/TokenUsage'
5
+ import ContextStatus from '@/components/aiwf/ContextStatus'
6
+
7
+ export default function AiwfDashboard() {
8
+ const { features, tokenUsage, contextStatus, loadDashboardData } = useAiwfStore()
9
+ const [activeTab, setActiveTab] = useState('features')
10
+
11
+ useEffect(() => {
12
+ loadDashboardData()
13
+ }, [loadDashboardData])
14
+
15
+ const tabs = [
16
+ { id: 'features', name: 'Feature Ledger', icon: '📋' },
17
+ { id: 'tokens', name: '토큰 사용량', icon: '🪙' },
18
+ { id: 'context', name: 'Context 상태', icon: '📊' },
19
+ ]
20
+
21
+ return (
22
+ <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
23
+ <div className="mb-8">
24
+ <h2 className="text-2xl font-bold text-gray-900 dark:text-white">
25
+ AIWF 대시보드
26
+ </h2>
27
+ <p className="mt-1 text-sm text-gray-500 dark:text-gray-400">
28
+ 프로젝트의 AI 지원 개발 현황을 한눈에 확인하세요.
29
+ </p>
30
+ </div>
31
+
32
+ <div className="border-b border-gray-200 dark:border-gray-700">
33
+ <nav className="-mb-px flex space-x-8" aria-label="Tabs">
34
+ {tabs.map((tab) => (
35
+ <button
36
+ key={tab.id}
37
+ onClick={() => setActiveTab(tab.id)}
38
+ className={`
39
+ whitespace-nowrap py-2 px-1 border-b-2 font-medium text-sm
40
+ ${activeTab === tab.id
41
+ ? 'border-primary text-primary'
42
+ : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300'
43
+ }
44
+ `}
45
+ >
46
+ <span className="mr-2">{tab.icon}</span>
47
+ {tab.name}
48
+ </button>
49
+ ))}
50
+ </nav>
51
+ </div>
52
+
53
+ <div className="mt-8">
54
+ {activeTab === 'features' && <FeatureLedger features={features} />}
55
+ {activeTab === 'tokens' && <TokenUsage usage={tokenUsage} />}
56
+ {activeTab === 'context' && <ContextStatus status={contextStatus} />}
57
+ </div>
58
+ </div>
59
+ )
60
+ }
@@ -0,0 +1,89 @@
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
+ }
@@ -0,0 +1,25 @@
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
+ }
@@ -0,0 +1,126 @@
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
+ }))
@@ -0,0 +1,9 @@
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
+ }
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
@@ -0,0 +1,30 @@
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
+ }
@@ -0,0 +1,37 @@
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
+ }
@@ -0,0 +1,10 @@
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
+ }
@@ -0,0 +1,23 @@
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
+ })
@@ -0,0 +1,223 @@
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;