aiwf 0.3.1 → 0.3.3

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 (493) hide show
  1. package/.aiwf/00_PROJECT_MANIFEST.md +183 -0
  2. package/.aiwf/01_PROJECT_DOCS/ARCHITECTURE.md +121 -0
  3. package/.aiwf/01_PROJECT_DOCS/FEATURE_LEDGER_ADVANCED_USE_CASES.md +412 -0
  4. package/.aiwf/01_PROJECT_DOCS/FEATURE_LEDGER_API_REFERENCE.md +361 -0
  5. package/.aiwf/01_PROJECT_DOCS/FEATURE_LEDGER_COMMANDS_GUIDE.md +254 -0
  6. package/.aiwf/01_PROJECT_DOCS/FEATURE_LEDGER_FAQ.md +365 -0
  7. package/.aiwf/01_PROJECT_DOCS/FEATURE_LEDGER_SYSTEM_OVERVIEW.md +305 -0
  8. package/.aiwf/01_PROJECT_DOCS/FEATURE_LEDGER_USER_GUIDE.md +416 -0
  9. package/.aiwf/01_PROJECT_DOCS/FEATURE_LEDGER_/354/213/234/354/236/221_/352/260/200/354/235/264/353/223/234.md +247 -0
  10. package/.aiwf/02_REQUIREMENTS/CLAUDE.md +78 -0
  11. package/.aiwf/02_REQUIREMENTS/M02_Context_Engineering_Enhancement/M02_milestone_meta.md +34 -0
  12. package/.aiwf/02_REQUIREMENTS/M02_Context_Engineering_Enhancement/PRD_Context_Engineering_Enhancement.md +108 -0
  13. package/.aiwf/02_REQUIREMENTS/M02_Context_Engineering_Enhancement/SPECS_AI_Persona_System.md +299 -0
  14. package/.aiwf/02_REQUIREMENTS/M02_Context_Engineering_Enhancement/SPECS_Feature_Ledger_System.md +330 -0
  15. package/.aiwf/02_REQUIREMENTS/M02_Context_Engineering_Enhancement/SPECS_Token_Optimization.md +833 -0
  16. package/.aiwf/03_SPRINTS/CLAUDE.md +83 -0
  17. package/.aiwf/03_SPRINTS/S01_M02_context_foundation/S01_M02_sprint_meta.md +95 -0
  18. package/.aiwf/03_SPRINTS/S01_M02_context_foundation/TX01_S01_Feature_Ledger_/353/215/260/354/235/264/355/204/260_/352/265/254/354/241/260_/354/204/244/352/263/204.md +111 -0
  19. package/.aiwf/03_SPRINTS/S01_M02_context_foundation/TX02_S01_Feature_Ledger_CLI_/353/252/205/353/240/271/354/226/264_/352/260/234/353/260/234.md +115 -0
  20. package/.aiwf/03_SPRINTS/S01_M02_context_foundation/TX03_S01_Git_/354/227/260/353/217/231_Feature_/354/266/224/354/240/201.md +141 -0
  21. package/.aiwf/03_SPRINTS/S01_M02_context_foundation/TX04_S01_Feature_Ledger_/353/254/270/354/204/234/355/231/224.md +114 -0
  22. package/.aiwf/03_SPRINTS/S01_M02_context_foundation/TX05_S01_AI_/355/216/230/353/245/264/354/206/214/353/202/230_/353/215/260/354/235/264/355/204/260_/352/265/254/354/241/260_/354/204/244/352/263/204.md +123 -0
  23. package/.aiwf/03_SPRINTS/S01_M02_context_foundation/TX06_S01_/355/216/230/353/245/264/354/206/214/353/202/230_/352/264/200/353/246/254_/353/252/205/353/240/271/354/226/264_/352/265/254/355/230/204.md +114 -0
  24. package/.aiwf/03_SPRINTS/S01_M02_context_foundation/TX07_S01_Context_/354/225/225/354/266/225_/354/225/204/355/202/244/355/205/215/354/262/230_/354/204/244/352/263/204.md +114 -0
  25. package/.aiwf/03_SPRINTS/S01_M02_context_foundation/TX08_S01_/355/206/240/355/201/260_/354/266/224/354/240/201_/354/213/234/354/212/244/355/205/234_/355/224/204/353/241/234/355/206/240/355/203/200/354/236/205.md +112 -0
  26. package/.aiwf/03_SPRINTS/S01_M02_context_foundation/TX09_S01_/354/225/225/354/266/225_/354/225/214/352/263/240/353/246/254/354/246/230_/355/224/204/353/241/234/355/206/240/355/203/200/354/236/205.md +118 -0
  27. package/.aiwf/03_SPRINTS/S01_M02_context_foundation/TX10_S01_update_docs_/353/252/205/353/240/271/354/226/264_/353/263/265/352/265/254.md +118 -0
  28. package/.aiwf/03_SPRINTS/S01_M02_context_foundation/TX11_S01_/355/206/265/355/225/251_/355/205/214/354/212/244/355/212/270_Suite_/352/265/254/354/266/225.md +128 -0
  29. package/.aiwf/03_SPRINTS/S01_M02_context_foundation/TX12_S01_/354/204/261/353/212/245_/354/265/234/354/240/201/355/231/224_/353/260/217_/353/254/270/354/204/234/355/231/224.md +122 -0
  30. package/.aiwf/03_SPRINTS/S02_M02_ai_enhancement/S02_M02_sprint_meta.md +107 -0
  31. package/.aiwf/03_SPRINTS/S02_M02_ai_enhancement/TX01_S02_AI_/355/216/230/353/245/264/354/206/214/353/202/230_/353/252/205/353/240/271/354/226/264_/352/265/254/355/230/204.md +129 -0
  32. package/.aiwf/03_SPRINTS/S02_M02_ai_enhancement/TX02_S02_/355/216/230/353/245/264/354/206/214/353/202/230_/354/273/250/355/205/215/354/212/244/355/212/270_/354/240/201/354/232/251_/354/213/234/354/212/244/355/205/234.md +152 -0
  33. package/.aiwf/03_SPRINTS/S02_M02_ai_enhancement/TX03_S02_Context_/354/225/225/354/266/225_/354/225/214/352/263/240/353/246/254/354/246/230_/352/265/254/355/230/204.md +186 -0
  34. package/.aiwf/03_SPRINTS/S02_M02_ai_enhancement/TX05_S02_S02_/355/206/265/355/225/251_/355/205/214/354/212/244/355/212/270_/353/260/217_/353/254/270/354/204/234/355/231/224.md +192 -0
  35. package/.aiwf/03_SPRINTS/S02_M02_ai_enhancement/TX4_S02_Feature_Git_/354/227/260/353/217/231_/353/260/217_/354/236/220/353/217/231/355/231/224.md +162 -0
  36. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/S03_FINAL_SPRINT_SUMMARY.md +137 -0
  37. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/S03_M02_sprint_meta.md +106 -0
  38. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/TX14_S03_M02_/353/247/210/354/235/274/354/212/244/355/206/244_/354/265/234/354/242/205_/352/262/200/354/246/235_/353/260/217_/353/254/270/354/204/234/355/231/224.md +214 -0
  39. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/TX15_S03_/352/270/260/353/263/270_/355/224/204/353/241/234/354/240/235/355/212/270_/355/205/234/355/224/214/353/246/277_/352/260/234/353/260/234.md +177 -0
  40. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/TX16_S03_/354/230/244/355/224/204/353/235/274/354/235/270_/355/205/234/355/224/214/353/246/277_/354/272/220/354/213/234_/354/213/234/354/212/244/355/205/234.md +206 -0
  41. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/TX_T13_S03_AI_/353/217/204/352/265/254_/355/206/265/355/225/251_/355/205/234/355/224/214/353/246/277_/352/260/234/353/260/234.md +151 -0
  42. package/.aiwf/04_GENERAL_TASKS/CLAUDE.md +96 -0
  43. package/.aiwf/04_GENERAL_TASKS/TX001_complete_english_translation.md +127 -0
  44. package/.aiwf/05_DOCUMENTATION/performance-report.md +33 -0
  45. package/.aiwf/06_FEATURE_LEDGERS/FEATURE_GIT_INTEGRATION.md +314 -0
  46. package/.aiwf/06_FEATURE_LEDGERS/FEATURE_INTEGRATION_GUIDE.md +227 -0
  47. package/.aiwf/06_FEATURE_LEDGERS/FEATURE_LEDGER_INDEX.md +23 -0
  48. package/.aiwf/06_FEATURE_LEDGERS/FEATURE_SCHEMA.md +205 -0
  49. package/.aiwf/06_FEATURE_LEDGERS/FEATURE_STATE_DIAGRAM.md +190 -0
  50. package/.aiwf/06_FEATURE_LEDGERS/active/FL001_user_authentication_system.md +47 -0
  51. package/.aiwf/06_FEATURE_LEDGERS/active/FL002_user_authentication_system.md +47 -0
  52. package/.aiwf/07_AI_PERSONAS/PERSONA_INDEX.md +57 -0
  53. package/.aiwf/07_AI_PERSONAS/architect/best_practices.md +104 -0
  54. package/.aiwf/07_AI_PERSONAS/architect/context_rules.md +46 -0
  55. package/.aiwf/07_AI_PERSONAS/architect/knowledge_base.md +235 -0
  56. package/.aiwf/07_AI_PERSONAS/backend/best_practices.md +363 -0
  57. package/.aiwf/07_AI_PERSONAS/backend/context_rules.md +61 -0
  58. package/.aiwf/07_AI_PERSONAS/backend/knowledge_base.md +623 -0
  59. package/.aiwf/07_AI_PERSONAS/data_analyst/best_practices.md +32 -0
  60. package/.aiwf/07_AI_PERSONAS/data_analyst/context_rules.md +43 -0
  61. package/.aiwf/07_AI_PERSONAS/data_analyst/knowledge_base.md +36 -0
  62. package/.aiwf/07_AI_PERSONAS/frontend/best_practices.md +31 -0
  63. package/.aiwf/07_AI_PERSONAS/frontend/context_rules.md +43 -0
  64. package/.aiwf/07_AI_PERSONAS/frontend/knowledge_base.md +32 -0
  65. package/.aiwf/07_AI_PERSONAS/security/best_practices.md +63 -0
  66. package/.aiwf/07_AI_PERSONAS/security/context_rules.md +53 -0
  67. package/.aiwf/07_AI_PERSONAS/security/knowledge_base.md +93 -0
  68. package/.aiwf/10_PERSONAS/active.json +1 -0
  69. package/.aiwf/10_PERSONAS/developer.md +37 -0
  70. package/.aiwf/10_STATE_OF_PROJECT/2025-07-09-07-20-solid-progress.md +144 -0
  71. package/.aiwf/98_PROMPTS/SAAS_DEVELOPMENT_GUIDE.md +302 -0
  72. package/.aiwf/98_PROMPTS/github_integration.md +130 -0
  73. package/.aiwf/98_PROMPTS/useful-prompts.md +31 -0
  74. package/.aiwf/98_PROMPTS/vibe-front-prompts.md +89 -0
  75. package/.aiwf/99_TEMPLATES/adr_template.md +49 -0
  76. package/.aiwf/99_TEMPLATES/feature_template.md +263 -0
  77. package/.aiwf/99_TEMPLATES/milestone_meta_template.md +25 -0
  78. package/.aiwf/99_TEMPLATES/project_manifest_template.md +39 -0
  79. package/.aiwf/99_TEMPLATES/sprint_meta_template.md +23 -0
  80. package/.aiwf/99_TEMPLATES/task_template.md +36 -0
  81. package/.aiwf/CLAUDE.md +76 -0
  82. package/.aiwf/ai-tools/README.md +105 -0
  83. package/.aiwf/ai-tools/augment/README.md +371 -0
  84. package/.aiwf/ai-tools/augment/config.json +30 -0
  85. package/.aiwf/ai-tools/augment/template/.augment/aiwf-integration.md +387 -0
  86. package/.aiwf/ai-tools/augment/template/.augment/augment.yaml +347 -0
  87. package/.aiwf/ai-tools/augment/template/augment.config.json +64 -0
  88. package/.aiwf/ai-tools/claude-code/README.md +151 -0
  89. package/.aiwf/ai-tools/claude-code/config.json +28 -0
  90. package/.aiwf/ai-tools/claude-code/template/CLAUDE.md +91 -0
  91. package/.aiwf/ai-tools/cursor/README.md +314 -0
  92. package/.aiwf/ai-tools/cursor/config.json +29 -0
  93. package/.aiwf/ai-tools/cursor/template/.cursorrules +362 -0
  94. package/.aiwf/ai-tools/github-copilot/README.md +195 -0
  95. package/.aiwf/ai-tools/github-copilot/config.json +24 -0
  96. package/.aiwf/ai-tools/github-copilot/template/.github/copilot-instructions.md +202 -0
  97. package/.aiwf/ai-tools/windsurf/README.md +355 -0
  98. package/.aiwf/ai-tools/windsurf/config.json +29 -0
  99. package/.aiwf/ai-tools/windsurf/template/.windsurf/aiwf-rules.md +260 -0
  100. package/.aiwf/ai-tools/windsurf/template/.windsurf/windsurf.config.js +312 -0
  101. package/.aiwf/ai-tools/windsurf/template/windsurf.config.json +63 -0
  102. package/.aiwf/config/language.json +6 -0
  103. package/.aiwf/feature-ledger/FL-001-authentication.json +52 -0
  104. package/.aiwf/feature-ledger/feature-index.json +20 -0
  105. package/.aiwf/installed.flag +1 -0
  106. package/.aiwf/personas/analyst.json +44 -0
  107. package/.aiwf/personas/architect/best_practices.md +136 -0
  108. package/.aiwf/personas/architect/knowledge_base.md +377 -0
  109. package/.aiwf/personas/architect.json +44 -0
  110. package/.aiwf/personas/backend/best_practices.md +766 -0
  111. package/.aiwf/personas/backend/knowledge_base.md +1070 -0
  112. package/.aiwf/personas/data_analyst/best_practices.md +594 -0
  113. package/.aiwf/personas/data_analyst/knowledge_base.md +1057 -0
  114. package/.aiwf/personas/developer.json +44 -0
  115. package/.aiwf/personas/evaluation_criteria.json +137 -0
  116. package/.aiwf/personas/frontend/best_practices.md +445 -0
  117. package/.aiwf/personas/frontend/knowledge_base.md +729 -0
  118. package/.aiwf/personas/persona-index.json +31 -0
  119. package/.aiwf/personas/reviewer.json +44 -0
  120. package/.aiwf/personas/security/best_practices.md +307 -0
  121. package/.aiwf/personas/security/knowledge_base.md +498 -0
  122. package/.aiwf/personas/tester.json +44 -0
  123. package/.aiwf/scripts/cache-templates.js +209 -0
  124. package/.aiwf/scripts/create-offline.js +86 -0
  125. package/.aiwf/scripts/create-project.js +151 -0
  126. package/.aiwf/scripts/feature-progress-calculator.cjs +236 -0
  127. package/.aiwf/scripts/git-integration.cjs +391 -0
  128. package/.aiwf/scripts/install-git-hooks.cjs +226 -0
  129. package/.aiwf/scripts/test-commit-parsing.cjs +125 -0
  130. package/.aiwf/scripts/update-feature-status.cjs +198 -0
  131. package/.aiwf/templates/README.md +78 -0
  132. package/.aiwf/templates/api-server/config.json +64 -0
  133. package/.aiwf/templates/api-server/template/.aiwf/config.json +56 -0
  134. package/.aiwf/templates/api-server/template/.aiwf/feature-ledger.json +42 -0
  135. package/.aiwf/templates/api-server/template/.aiwf/personas/backend-engineer.json +40 -0
  136. package/.aiwf/templates/api-server/template/.aiwf/scripts/cli.js +111 -0
  137. package/.aiwf/templates/api-server/template/.env.example +29 -0
  138. package/.aiwf/templates/api-server/template/.eslintrc.json +23 -0
  139. package/.aiwf/templates/api-server/template/README.md +171 -0
  140. package/.aiwf/templates/api-server/template/jest.config.js +26 -0
  141. package/.aiwf/templates/api-server/template/nodemon.json +9 -0
  142. package/.aiwf/templates/api-server/template/package.json +61 -0
  143. package/.aiwf/templates/api-server/template/src/app.ts +60 -0
  144. package/.aiwf/templates/api-server/template/src/config/swagger.ts +38 -0
  145. package/.aiwf/templates/api-server/template/src/controllers/aiwfController.ts +68 -0
  146. package/.aiwf/templates/api-server/template/src/controllers/authController.ts +128 -0
  147. package/.aiwf/templates/api-server/template/src/controllers/statusController.ts +28 -0
  148. package/.aiwf/templates/api-server/template/src/index.ts +28 -0
  149. package/.aiwf/templates/api-server/template/src/middleware/aiwfMiddleware.ts +50 -0
  150. package/.aiwf/templates/api-server/template/src/middleware/authMiddleware.ts +41 -0
  151. package/.aiwf/templates/api-server/template/src/middleware/errorHandler.ts +42 -0
  152. package/.aiwf/templates/api-server/template/src/middleware/notFoundHandler.ts +14 -0
  153. package/.aiwf/templates/api-server/template/src/middleware/requestLogger.ts +20 -0
  154. package/.aiwf/templates/api-server/template/src/routes/aiwf.ts +42 -0
  155. package/.aiwf/templates/api-server/template/src/routes/index.ts +13 -0
  156. package/.aiwf/templates/api-server/template/src/routes/v1/index.ts +67 -0
  157. package/.aiwf/templates/api-server/template/src/utils/logger.ts +37 -0
  158. package/.aiwf/templates/api-server/template/tests/app.test.ts +40 -0
  159. package/.aiwf/templates/api-server/template/tsconfig.json +43 -0
  160. package/.aiwf/templates/npm-library/config.json +61 -0
  161. package/.aiwf/templates/npm-library/template/LICENSE +21 -0
  162. package/.aiwf/templates/npm-library/template/README.md +201 -0
  163. package/.aiwf/templates/npm-library/template/package.json +78 -0
  164. package/.aiwf/templates/web-app/config.json +53 -0
  165. package/.aiwf/templates/web-app/template/.aiwf/config.json +54 -0
  166. package/.aiwf/templates/web-app/template/.aiwf/feature-ledger.json +37 -0
  167. package/.aiwf/templates/web-app/template/.aiwf/personas/fullstack-developer.json +40 -0
  168. package/.aiwf/templates/web-app/template/.aiwf/scripts/cli.js +110 -0
  169. package/.aiwf/templates/web-app/template/.eslintrc.cjs +20 -0
  170. package/.aiwf/templates/web-app/template/README.md +151 -0
  171. package/.aiwf/templates/web-app/template/index.html +14 -0
  172. package/.aiwf/templates/web-app/template/package.json +44 -0
  173. package/.aiwf/templates/web-app/template/postcss.config.js +6 -0
  174. package/.aiwf/templates/web-app/template/public/vite.svg +1 -0
  175. package/.aiwf/templates/web-app/template/src/App.tsx +21 -0
  176. package/.aiwf/templates/web-app/template/src/components/Layout.tsx +57 -0
  177. package/.aiwf/templates/web-app/template/src/components/aiwf/ContextStatus.tsx +107 -0
  178. package/.aiwf/templates/web-app/template/src/components/aiwf/FeatureLedger.tsx +93 -0
  179. package/.aiwf/templates/web-app/template/src/components/aiwf/TokenUsage.tsx +71 -0
  180. package/.aiwf/templates/web-app/template/src/index.css +60 -0
  181. package/.aiwf/templates/web-app/template/src/main.tsx +10 -0
  182. package/.aiwf/templates/web-app/template/src/pages/AiwfDashboard.tsx +60 -0
  183. package/.aiwf/templates/web-app/template/src/pages/HomePage.tsx +89 -0
  184. package/.aiwf/templates/web-app/template/src/pages/NotFound.tsx +25 -0
  185. package/.aiwf/templates/web-app/template/src/stores/aiwfStore.ts +126 -0
  186. package/.aiwf/templates/web-app/template/src/types/global.d.ts +9 -0
  187. package/.aiwf/templates/web-app/template/src/vite-env.d.ts +1 -0
  188. package/.aiwf/templates/web-app/template/tailwind.config.js +30 -0
  189. package/.aiwf/templates/web-app/template/tsconfig.json +37 -0
  190. package/.aiwf/templates/web-app/template/tsconfig.node.json +10 -0
  191. package/.aiwf/templates/web-app/template/vite.config.ts +23 -0
  192. package/.aiwf/test-cache/86c7f9e80251abb8bedd58953ab0d1779e46b4f43ea33b63bffdb778106373b0.json +6 -0
  193. package/.aiwf/test-cache/9e252a90b80fce0585d7ed0646e7a9b4343e109f661f42a3ae678ba1ec5e22c7.json +7 -0
  194. package/.aiwf/test-results-s02.json +36 -0
  195. package/.aiwf/token-data/alerts.json +293 -0
  196. package/.aiwf/token-data/monitor-config.json +12 -0
  197. package/CHANGELOG.md +95 -11
  198. package/CHANGELOG_M02.md +52 -0
  199. package/CLAUDE.md +135 -0
  200. package/README.ko.md +5 -0
  201. package/README.md +6 -0
  202. package/RELEASE_NOTES_M02.md +177 -0
  203. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_create_feature_ledger.md +54 -0
  204. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_default_mode.md +66 -0
  205. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_get_feature_details.md +78 -0
  206. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_link_feature_to_milestone.md +57 -0
  207. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_list_features.md +54 -0
  208. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_persona_architect.md +60 -0
  209. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_persona_backend.md +60 -0
  210. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_persona_data_analyst.md +60 -0
  211. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_persona_frontend.md +60 -0
  212. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_persona_security.md +60 -0
  213. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_persona_status.md +72 -0
  214. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_update_feature_status.md +53 -0
  215. package/claude-code/aiwf/en/commands/ai-persona.js +667 -0
  216. package/claude-code/aiwf/en/commands/compress-context.js +355 -0
  217. package/claude-code/aiwf/en/commands/feature-ledger.js +565 -0
  218. package/claude-code/aiwf/en/commands/feature_commit_report.js +370 -0
  219. package/claude-code/aiwf/en/commands/scan_git_history.js +234 -0
  220. package/claude-code/aiwf/en/commands/sync_feature_commits.js +154 -0
  221. package/claude-code/aiwf/en/commands/token-tracking.js +443 -0
  222. package/claude-code/aiwf/en/config/commit-patterns.js +103 -0
  223. package/claude-code/aiwf/en/hooks/install-hooks.sh +100 -0
  224. package/claude-code/aiwf/en/hooks/post-commit +84 -0
  225. package/claude-code/aiwf/en/tests/compression-test-suite.js +1252 -0
  226. package/claude-code/aiwf/en/tests/test-git-integration.js +164 -0
  227. package/claude-code/aiwf/en/tests/token-tracking.test.js +537 -0
  228. package/claude-code/aiwf/en/utils/compression-metrics.js +1031 -0
  229. package/claude-code/aiwf/en/utils/compression-strategies.js +557 -0
  230. package/claude-code/aiwf/en/utils/content-normalizer.js +455 -0
  231. package/claude-code/aiwf/en/utils/context-compressor.js +583 -0
  232. package/claude-code/aiwf/en/utils/feature-updater.js +271 -0
  233. package/claude-code/aiwf/en/utils/git-utils.js +220 -0
  234. package/claude-code/aiwf/en/utils/importance-classifier.js +645 -0
  235. package/claude-code/aiwf/en/utils/information-filter.js +710 -0
  236. package/claude-code/aiwf/en/utils/text-summarizer.js +487 -0
  237. package/claude-code/aiwf/en/utils/token-counter.js +177 -0
  238. package/claude-code/aiwf/en/utils/token-monitor.js +484 -0
  239. package/claude-code/aiwf/en/utils/token-reporter.js +453 -0
  240. package/claude-code/aiwf/en/utils/token-storage.js +433 -0
  241. package/claude-code/aiwf/en/utils/token-tracker.js +283 -0
  242. package/claude-code/aiwf/ko/.aiwf/06_FEATURE_LEDGERS/FEATURE_ID_GENERATOR.md +138 -0
  243. package/claude-code/aiwf/ko/.aiwf/06_FEATURE_LEDGERS/FEATURE_INDEX.md +186 -0
  244. package/claude-code/aiwf/ko/.aiwf/06_FEATURE_LEDGERS/FEATURE_METADATA.md +240 -0
  245. package/claude-code/aiwf/ko/.aiwf/06_FEATURE_LEDGERS/FEATURE_WORKFLOW.md +183 -0
  246. package/claude-code/aiwf/ko/.aiwf/06_FEATURE_LEDGERS/README.md +94 -0
  247. package/claude-code/aiwf/ko/.aiwf/06_FEATURE_LEDGERS/active/FL001_/354/202/254/354/232/251/354/236/220_/354/235/270/354/246/235_/354/213/234/354/212/244/355/205/234.md +154 -0
  248. package/claude-code/aiwf/ko/.aiwf/06_FEATURE_LEDGERS/active/FL002_ai_/355/216/230/353/245/264/354/206/214/353/202/230_/354/213/234/354/212/244/355/205/234.md +272 -0
  249. package/claude-code/aiwf/ko/.aiwf/06_FEATURE_LEDGERS/completed/FL003_/353/213/244/352/265/255/354/226/264_/353/252/205/353/240/271/354/226/264_/355/221/234/354/244/200/355/231/224.md +266 -0
  250. package/claude-code/aiwf/ko/.aiwf/06_FEATURE_LEDGERS/schemas/feature_schema.json +122 -0
  251. package/claude-code/aiwf/ko/.aiwf/06_FEATURE_LEDGERS/schemas/feature_validator.cjs +406 -0
  252. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_compress_aggressive_persona.md +53 -0
  253. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_compress_context.md +116 -0
  254. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_compress_minimal_persona.md +48 -0
  255. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_compress_stats.md +79 -0
  256. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_compress_with_persona.md +51 -0
  257. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_create_feature_ledger.md +54 -0
  258. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_default_mode.md +44 -0
  259. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_evaluate.md +92 -0
  260. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_get_feature_details.md +78 -0
  261. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_link_feature_to_milestone.md +57 -0
  262. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_list_features.md +54 -0
  263. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_architect.md +48 -0
  264. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_backend.md +37 -0
  265. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_data_analyst.md +37 -0
  266. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_frontend.md +37 -0
  267. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_security.md +48 -0
  268. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_status.md +50 -0
  269. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_update_docs_kr.md +25 -0
  270. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_update_feature_status.md +53 -0
  271. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_yolo.md +2 -2
  272. package/claude-code/aiwf/ko/CLAUDE.md +76 -0
  273. package/claude-code/aiwf/ko/ai-tools/README.md +105 -0
  274. package/claude-code/aiwf/ko/ai-tools/augment/README.md +371 -0
  275. package/claude-code/aiwf/ko/ai-tools/augment/config.json +30 -0
  276. package/claude-code/aiwf/ko/ai-tools/augment/template/.augment/aiwf-integration.md +387 -0
  277. package/claude-code/aiwf/ko/ai-tools/augment/template/.augment/augment.yaml +347 -0
  278. package/claude-code/aiwf/ko/ai-tools/augment/template/augment.config.json +64 -0
  279. package/claude-code/aiwf/ko/ai-tools/claude-code/README.md +151 -0
  280. package/claude-code/aiwf/ko/ai-tools/claude-code/config.json +28 -0
  281. package/claude-code/aiwf/ko/ai-tools/claude-code/template/CLAUDE.md +91 -0
  282. package/claude-code/aiwf/ko/ai-tools/cursor/README.md +314 -0
  283. package/claude-code/aiwf/ko/ai-tools/cursor/config.json +29 -0
  284. package/claude-code/aiwf/ko/ai-tools/cursor/template/.cursorrules +362 -0
  285. package/claude-code/aiwf/ko/ai-tools/github-copilot/README.md +195 -0
  286. package/claude-code/aiwf/ko/ai-tools/github-copilot/config.json +24 -0
  287. package/claude-code/aiwf/ko/ai-tools/github-copilot/template/.github/copilot-instructions.md +202 -0
  288. package/claude-code/aiwf/ko/ai-tools/windsurf/README.md +355 -0
  289. package/claude-code/aiwf/ko/ai-tools/windsurf/config.json +29 -0
  290. package/claude-code/aiwf/ko/ai-tools/windsurf/template/.windsurf/aiwf-rules.md +260 -0
  291. package/claude-code/aiwf/ko/ai-tools/windsurf/template/.windsurf/windsurf.config.js +312 -0
  292. package/claude-code/aiwf/ko/ai-tools/windsurf/template/windsurf.config.json +63 -0
  293. package/claude-code/aiwf/ko/commands/ai-persona.js +602 -0
  294. package/claude-code/aiwf/ko/commands/compress-context.js +389 -0
  295. package/claude-code/aiwf/ko/commands/evaluate.js +246 -0
  296. package/claude-code/aiwf/ko/commands/feature-ledger.js +565 -0
  297. package/claude-code/aiwf/ko/commands/feature_commit_report.js +370 -0
  298. package/claude-code/aiwf/ko/commands/persona-context-apply.js +562 -0
  299. package/claude-code/aiwf/ko/commands/scan_git_history.js +234 -0
  300. package/claude-code/aiwf/ko/commands/sync_feature_commits.js +154 -0
  301. package/claude-code/aiwf/ko/commands/token-tracking.js +443 -0
  302. package/claude-code/aiwf/ko/config/commit-patterns.js +103 -0
  303. package/claude-code/aiwf/ko/config/language.json +6 -0
  304. package/claude-code/aiwf/ko/feature-ledger/FL-001-authentication.json +52 -0
  305. package/claude-code/aiwf/ko/feature-ledger/feature-index.json +20 -0
  306. package/claude-code/aiwf/ko/hooks/install-hooks.sh +100 -0
  307. package/claude-code/aiwf/ko/hooks/post-commit +84 -0
  308. package/claude-code/aiwf/ko/personas/PERSONA_INDEX.md +57 -0
  309. package/claude-code/aiwf/ko/personas/analyst.json +44 -0
  310. package/claude-code/aiwf/ko/personas/architect/best_practices.md +136 -0
  311. package/claude-code/aiwf/ko/personas/architect/knowledge_base.md +377 -0
  312. package/claude-code/aiwf/ko/personas/architect.json +44 -0
  313. package/claude-code/aiwf/ko/personas/backend/best_practices.md +766 -0
  314. package/claude-code/aiwf/ko/personas/backend/knowledge_base.md +1070 -0
  315. package/claude-code/aiwf/ko/personas/data_analyst/best_practices.md +594 -0
  316. package/claude-code/aiwf/ko/personas/data_analyst/knowledge_base.md +1057 -0
  317. package/claude-code/aiwf/ko/personas/developer.json +44 -0
  318. package/claude-code/aiwf/ko/personas/developer.md +37 -0
  319. package/claude-code/aiwf/ko/personas/evaluation_criteria.json +137 -0
  320. package/claude-code/aiwf/ko/personas/frontend/best_practices.md +445 -0
  321. package/claude-code/aiwf/ko/personas/frontend/knowledge_base.md +729 -0
  322. package/claude-code/aiwf/ko/personas/persona-index.json +31 -0
  323. package/claude-code/aiwf/ko/personas/reviewer.json +44 -0
  324. package/claude-code/aiwf/ko/personas/security/best_practices.md +307 -0
  325. package/claude-code/aiwf/ko/personas/security/knowledge_base.md +498 -0
  326. package/claude-code/aiwf/ko/personas/tester.json +44 -0
  327. package/claude-code/aiwf/ko/scripts/cache-templates.js +209 -0
  328. package/claude-code/aiwf/ko/scripts/create-offline.js +86 -0
  329. package/claude-code/aiwf/ko/scripts/create-project.js +151 -0
  330. package/claude-code/aiwf/ko/scripts/feature-progress-calculator.cjs +236 -0
  331. package/claude-code/aiwf/ko/scripts/git-integration.cjs +391 -0
  332. package/claude-code/aiwf/ko/scripts/install-git-hooks.cjs +226 -0
  333. package/claude-code/aiwf/ko/scripts/test-commit-parsing.cjs +125 -0
  334. package/claude-code/aiwf/ko/scripts/update-feature-status.cjs +198 -0
  335. package/claude-code/aiwf/ko/templates/README.md +78 -0
  336. package/claude-code/aiwf/ko/templates/api-server/config.json +64 -0
  337. package/claude-code/aiwf/ko/templates/api-server/template/.aiwf/config.json +56 -0
  338. package/claude-code/aiwf/ko/templates/api-server/template/.aiwf/feature-ledger.json +42 -0
  339. package/claude-code/aiwf/ko/templates/api-server/template/.aiwf/personas/backend-engineer.json +40 -0
  340. package/claude-code/aiwf/ko/templates/api-server/template/.aiwf/scripts/cli.js +111 -0
  341. package/claude-code/aiwf/ko/templates/api-server/template/.env.example +29 -0
  342. package/claude-code/aiwf/ko/templates/api-server/template/.eslintrc.json +23 -0
  343. package/claude-code/aiwf/ko/templates/api-server/template/README.md +171 -0
  344. package/claude-code/aiwf/ko/templates/api-server/template/jest.config.js +26 -0
  345. package/claude-code/aiwf/ko/templates/api-server/template/nodemon.json +9 -0
  346. package/claude-code/aiwf/ko/templates/api-server/template/package.json +61 -0
  347. package/claude-code/aiwf/ko/templates/api-server/template/src/app.ts +60 -0
  348. package/claude-code/aiwf/ko/templates/api-server/template/src/config/swagger.ts +38 -0
  349. package/claude-code/aiwf/ko/templates/api-server/template/src/controllers/aiwfController.ts +68 -0
  350. package/claude-code/aiwf/ko/templates/api-server/template/src/controllers/authController.ts +128 -0
  351. package/claude-code/aiwf/ko/templates/api-server/template/src/controllers/statusController.ts +28 -0
  352. package/claude-code/aiwf/ko/templates/api-server/template/src/index.ts +28 -0
  353. package/claude-code/aiwf/ko/templates/api-server/template/src/middleware/aiwfMiddleware.ts +50 -0
  354. package/claude-code/aiwf/ko/templates/api-server/template/src/middleware/authMiddleware.ts +41 -0
  355. package/claude-code/aiwf/ko/templates/api-server/template/src/middleware/errorHandler.ts +42 -0
  356. package/claude-code/aiwf/ko/templates/api-server/template/src/middleware/notFoundHandler.ts +14 -0
  357. package/claude-code/aiwf/ko/templates/api-server/template/src/middleware/requestLogger.ts +20 -0
  358. package/claude-code/aiwf/ko/templates/api-server/template/src/routes/aiwf.ts +42 -0
  359. package/claude-code/aiwf/ko/templates/api-server/template/src/routes/index.ts +13 -0
  360. package/claude-code/aiwf/ko/templates/api-server/template/src/routes/v1/index.ts +67 -0
  361. package/claude-code/aiwf/ko/templates/api-server/template/src/utils/logger.ts +37 -0
  362. package/claude-code/aiwf/ko/templates/api-server/template/tests/app.test.ts +40 -0
  363. package/claude-code/aiwf/ko/templates/api-server/template/tsconfig.json +43 -0
  364. package/claude-code/aiwf/ko/templates/npm-library/config.json +61 -0
  365. package/claude-code/aiwf/ko/templates/npm-library/template/LICENSE +21 -0
  366. package/claude-code/aiwf/ko/templates/npm-library/template/README.md +201 -0
  367. package/claude-code/aiwf/ko/templates/npm-library/template/package.json +78 -0
  368. package/claude-code/aiwf/ko/templates/web-app/config.json +53 -0
  369. package/claude-code/aiwf/ko/templates/web-app/template/.aiwf/config.json +54 -0
  370. package/claude-code/aiwf/ko/templates/web-app/template/.aiwf/feature-ledger.json +37 -0
  371. package/claude-code/aiwf/ko/templates/web-app/template/.aiwf/personas/fullstack-developer.json +40 -0
  372. package/claude-code/aiwf/ko/templates/web-app/template/.aiwf/scripts/cli.js +110 -0
  373. package/claude-code/aiwf/ko/templates/web-app/template/.eslintrc.cjs +20 -0
  374. package/claude-code/aiwf/ko/templates/web-app/template/README.md +151 -0
  375. package/claude-code/aiwf/ko/templates/web-app/template/index.html +14 -0
  376. package/claude-code/aiwf/ko/templates/web-app/template/package-lock.json +10022 -0
  377. package/claude-code/aiwf/ko/templates/web-app/template/package.json +44 -0
  378. package/claude-code/aiwf/ko/templates/web-app/template/postcss.config.js +6 -0
  379. package/claude-code/aiwf/ko/templates/web-app/template/public/vite.svg +1 -0
  380. package/claude-code/aiwf/ko/templates/web-app/template/src/App.tsx +21 -0
  381. package/claude-code/aiwf/ko/templates/web-app/template/src/components/Layout.tsx +57 -0
  382. package/claude-code/aiwf/ko/templates/web-app/template/src/components/aiwf/ContextStatus.tsx +107 -0
  383. package/claude-code/aiwf/ko/templates/web-app/template/src/components/aiwf/FeatureLedger.tsx +93 -0
  384. package/claude-code/aiwf/ko/templates/web-app/template/src/components/aiwf/TokenUsage.tsx +71 -0
  385. package/claude-code/aiwf/ko/templates/web-app/template/src/index.css +60 -0
  386. package/claude-code/aiwf/ko/templates/web-app/template/src/main.tsx +10 -0
  387. package/claude-code/aiwf/ko/templates/web-app/template/src/pages/AiwfDashboard.tsx +60 -0
  388. package/claude-code/aiwf/ko/templates/web-app/template/src/pages/HomePage.tsx +89 -0
  389. package/claude-code/aiwf/ko/templates/web-app/template/src/pages/NotFound.tsx +25 -0
  390. package/claude-code/aiwf/ko/templates/web-app/template/src/stores/aiwfStore.ts +126 -0
  391. package/claude-code/aiwf/ko/templates/web-app/template/src/types/global.d.ts +9 -0
  392. package/claude-code/aiwf/ko/templates/web-app/template/src/vite-env.d.ts +1 -0
  393. package/claude-code/aiwf/ko/templates/web-app/template/tailwind.config.js +30 -0
  394. package/claude-code/aiwf/ko/templates/web-app/template/tsconfig.json +37 -0
  395. package/claude-code/aiwf/ko/templates/web-app/template/tsconfig.node.json +10 -0
  396. package/claude-code/aiwf/ko/templates/web-app/template/vite.config.ts +23 -0
  397. package/claude-code/aiwf/ko/tests/compression-test-suite.js +1252 -0
  398. package/claude-code/aiwf/ko/tests/test-git-integration.js +164 -0
  399. package/claude-code/aiwf/ko/tests/token-tracking.test.js +537 -0
  400. package/claude-code/aiwf/ko/token-data/alerts.json +293 -0
  401. package/claude-code/aiwf/ko/token-data/monitor-config.json +12 -0
  402. package/claude-code/aiwf/ko/utils/background-monitor.js +223 -0
  403. package/claude-code/aiwf/ko/utils/compression-metrics.js +1031 -0
  404. package/claude-code/aiwf/ko/utils/compression-strategies.js +557 -0
  405. package/claude-code/aiwf/ko/utils/content-normalizer.js +455 -0
  406. package/claude-code/aiwf/ko/utils/context-compressor.js +583 -0
  407. package/claude-code/aiwf/ko/utils/context-rule-parser.js +180 -0
  408. package/claude-code/aiwf/ko/utils/context-token-monitor.js +463 -0
  409. package/claude-code/aiwf/ko/utils/context-update-manager.js +502 -0
  410. package/claude-code/aiwf/ko/utils/feature-updater.js +271 -0
  411. package/claude-code/aiwf/ko/utils/git-utils.js +220 -0
  412. package/claude-code/aiwf/ko/utils/importance-classifier.js +645 -0
  413. package/claude-code/aiwf/ko/utils/information-filter.js +710 -0
  414. package/claude-code/aiwf/ko/utils/persona-aware-compressor.js +598 -0
  415. package/claude-code/aiwf/ko/utils/prompt-injector.js +242 -0
  416. package/claude-code/aiwf/ko/utils/simplified-evaluator.js +119 -0
  417. package/claude-code/aiwf/ko/utils/text-summarizer.js +492 -0
  418. package/claude-code/aiwf/ko/utils/token-counter.js +177 -0
  419. package/claude-code/aiwf/ko/utils/token-monitor.js +484 -0
  420. package/claude-code/aiwf/ko/utils/token-reporter.js +453 -0
  421. package/claude-code/aiwf/ko/utils/token-storage.js +433 -0
  422. package/claude-code/aiwf/ko/utils/token-tracker.js +283 -0
  423. package/docs/AI_PERSONA_SYSTEM_DESIGN.md +516 -0
  424. package/docs/API_DOCUMENTATION.md +932 -0
  425. package/docs/API_REFERENCE.md +979 -0
  426. package/docs/COMMANDS_GUIDE.ko.md +8 -2
  427. package/docs/COMMANDS_GUIDE.md +196 -2
  428. package/docs/CONTRIBUTING.ko.md +408 -0
  429. package/docs/CONTRIBUTING.md +205 -203
  430. package/docs/EXAMPLES.md +691 -0
  431. package/docs/GETTING_STARTED.md +480 -0
  432. package/docs/PERFORMANCE_ARCHITECTURE.md +494 -0
  433. package/docs/PERFORMANCE_GUIDELINES.md +553 -0
  434. package/docs/TROUBLESHOOTING.md +721 -0
  435. package/docs/git-feature-integration-guide.md +253 -0
  436. package/docs/guides/ai-personas-guide-ko.md +239 -0
  437. package/docs/guides/ai-personas-guide.md +239 -0
  438. package/docs/guides/context-compression-guide-ko.md +313 -0
  439. package/docs/guides/context-compression-guide.md +313 -0
  440. package/docs/guides/feature-git-integration-guide-ko.md +481 -0
  441. package/docs/guides/feature-git-integration-guide.md +481 -0
  442. package/docs/lightweight-evaluation.md +198 -0
  443. package/docs/m02-dod-checklist.md +125 -0
  444. package/docs/m02-gap-analysis.md +214 -0
  445. package/docs/m02-milestone-completion-report.md +186 -0
  446. package/docs/m02-milestone-executive-summary.md +68 -0
  447. package/docs/offline-template-cache.md +323 -0
  448. package/docs/performance-benchmark-report.md +159 -0
  449. package/docs/persona-aware-compression.md +168 -0
  450. package/docs/reports/S02-sprint-report.md +190 -0
  451. package/docs/usability-test-report.md +170 -0
  452. package/index.js +116 -4
  453. package/jest.config.js +20 -1
  454. package/language-utils.js +1 -1
  455. package/lib/ai-persona-manager.js +711 -0
  456. package/lib/cache-cli.js +459 -0
  457. package/lib/cache-integration.js +401 -0
  458. package/lib/cache-system.js +332 -0
  459. package/lib/context-engine.js +568 -0
  460. package/lib/file-batch-processor.js +401 -0
  461. package/lib/memory-profiler.js +471 -0
  462. package/lib/metrics-collector.js +885 -0
  463. package/lib/offline-detector.js +386 -0
  464. package/lib/performance-benchmark.js +621 -0
  465. package/lib/task-analyzer.js +599 -0
  466. package/lib/template-cache-system.js +559 -0
  467. package/lib/template-downloader.js +467 -0
  468. package/lib/template-manager.js +310 -0
  469. package/lib/template-version-manager.js +491 -0
  470. package/lib/token-optimizer.js +517 -0
  471. package/package.json +6 -3
  472. package/scripts/run-integration-tests.js +317 -0
  473. package/src/commands/ai-tool.js +383 -0
  474. package/test-token-system.js +88 -0
  475. package/tests/application.test.js +260 -0
  476. package/tests/basic.test.js +1 -1
  477. package/tests/integration/ai-persona-system.test.js +396 -0
  478. package/tests/integration/ai-persona.test.js +390 -0
  479. package/tests/integration/command-integration.test.js +600 -0
  480. package/tests/integration/context-compression.test.js +361 -0
  481. package/tests/integration/feature-ledger.test.js +226 -0
  482. package/tests/integration/git-integration.test.js +307 -0
  483. package/tests/integration/m02-milestone.test.js +420 -0
  484. package/tests/integration/persona-context-application.test.js +508 -0
  485. package/tests/integration/setup.js +174 -0
  486. package/tests/integration/test-persona-aware-compression.js +93 -0
  487. package/tests/language-utils.test.js +25 -9
  488. package/tests/s02-integration.test.js +422 -0
  489. package/tests/unit/ai-persona-manager.test.js +514 -0
  490. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_language_manager.md +0 -287
  491. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_language_status.md +0 -246
  492. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_language_manager.md +0 -287
  493. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_language_status.md +0 -246
@@ -0,0 +1,1031 @@
1
+ import { TokenCounter } from './token-counter.js';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+
5
+ /**
6
+ * 압축률 측정 및 성능 분석 도구
7
+ */
8
+ export class CompressionMetrics {
9
+ constructor() {
10
+ this.tokenCounter = new TokenCounter();
11
+ this.measurements = new Map();
12
+ this.benchmarks = new Map();
13
+ this.initializeMetrics();
14
+ }
15
+
16
+ /**
17
+ * 메트릭 시스템을 초기화합니다
18
+ */
19
+ initializeMetrics() {
20
+ // 메트릭 타입 정의
21
+ this.metricTypes = {
22
+ compression: {
23
+ name: 'Compression Metrics',
24
+ description: '압축률 관련 메트릭',
25
+ measurements: [
26
+ 'compression_ratio',
27
+ 'token_reduction',
28
+ 'size_reduction',
29
+ 'information_preservation'
30
+ ]
31
+ },
32
+ performance: {
33
+ name: 'Performance Metrics',
34
+ description: '성능 관련 메트릭',
35
+ measurements: [
36
+ 'compression_time',
37
+ 'decompression_time',
38
+ 'memory_usage',
39
+ 'throughput'
40
+ ]
41
+ },
42
+ quality: {
43
+ name: 'Quality Metrics',
44
+ description: '품질 관련 메트릭',
45
+ measurements: [
46
+ 'readability_score',
47
+ 'structure_preservation',
48
+ 'semantic_similarity',
49
+ 'information_loss'
50
+ ]
51
+ },
52
+ efficiency: {
53
+ name: 'Efficiency Metrics',
54
+ description: '효율성 관련 메트릭',
55
+ measurements: [
56
+ 'tokens_per_second',
57
+ 'compression_efficiency',
58
+ 'resource_utilization',
59
+ 'cost_effectiveness'
60
+ ]
61
+ }
62
+ };
63
+
64
+ // 벤치마크 기준점
65
+ this.benchmarkThresholds = {
66
+ compression_ratio: {
67
+ excellent: 70,
68
+ good: 50,
69
+ acceptable: 30,
70
+ poor: 10
71
+ },
72
+ compression_time: {
73
+ excellent: 1000, // 1초
74
+ good: 3000, // 3초
75
+ acceptable: 5000, // 5초
76
+ poor: 10000 // 10초
77
+ },
78
+ information_preservation: {
79
+ excellent: 90,
80
+ good: 80,
81
+ acceptable: 70,
82
+ poor: 50
83
+ },
84
+ readability_score: {
85
+ excellent: 90,
86
+ good: 80,
87
+ acceptable: 70,
88
+ poor: 50
89
+ }
90
+ };
91
+
92
+ // 측정 히스토리
93
+ this.measurementHistory = [];
94
+ }
95
+
96
+ /**
97
+ * 압축 결과를 측정합니다
98
+ * @param {string} original - 원본 콘텐츠
99
+ * @param {string} compressed - 압축된 콘텐츠
100
+ * @param {Object} metadata - 압축 메타데이터
101
+ * @returns {Object} 측정 결과
102
+ */
103
+ measureCompression(original, compressed, metadata = {}) {
104
+ const measurementId = this.generateMeasurementId();
105
+ const timestamp = Date.now();
106
+
107
+ const measurement = {
108
+ id: measurementId,
109
+ timestamp,
110
+ originalContent: original,
111
+ compressedContent: compressed,
112
+ metadata,
113
+ metrics: {},
114
+ analysis: {},
115
+ benchmark: {}
116
+ };
117
+
118
+ // 1. 압축 메트릭 계산
119
+ measurement.metrics.compression = this.calculateCompressionMetrics(original, compressed);
120
+
121
+ // 2. 성능 메트릭 계산
122
+ measurement.metrics.performance = this.calculatePerformanceMetrics(metadata);
123
+
124
+ // 3. 품질 메트릭 계산
125
+ measurement.metrics.quality = this.calculateQualityMetrics(original, compressed, metadata);
126
+
127
+ // 4. 효율성 메트릭 계산
128
+ measurement.metrics.efficiency = this.calculateEfficiencyMetrics(original, compressed, metadata);
129
+
130
+ // 5. 벤치마크 분석
131
+ measurement.benchmark = this.analyzeBenchmark(measurement.metrics);
132
+
133
+ // 6. 종합 분석
134
+ measurement.analysis = this.generateAnalysis(measurement.metrics, measurement.benchmark);
135
+
136
+ // 측정 결과 저장
137
+ this.measurements.set(measurementId, measurement);
138
+ this.measurementHistory.push(measurement);
139
+
140
+ return measurement;
141
+ }
142
+
143
+ /**
144
+ * 압축 메트릭을 계산합니다
145
+ * @param {string} original - 원본 콘텐츠
146
+ * @param {string} compressed - 압축된 콘텐츠
147
+ * @returns {Object} 압축 메트릭
148
+ */
149
+ calculateCompressionMetrics(original, compressed) {
150
+ const originalTokens = this.tokenCounter.countTokens(original);
151
+ const compressedTokens = this.tokenCounter.countTokens(compressed);
152
+ const originalSize = Buffer.byteLength(original, 'utf8');
153
+ const compressedSize = Buffer.byteLength(compressed, 'utf8');
154
+
155
+ const tokenReduction = originalTokens - compressedTokens;
156
+ const sizeReduction = originalSize - compressedSize;
157
+ const compressionRatio = originalTokens > 0 ? (tokenReduction / originalTokens) * 100 : 0;
158
+ const sizeCompressionRatio = originalSize > 0 ? (sizeReduction / originalSize) * 100 : 0;
159
+
160
+ // 정보 보존률 계산
161
+ const informationPreservation = this.calculateInformationPreservation(original, compressed);
162
+
163
+ return {
164
+ original_tokens: originalTokens,
165
+ compressed_tokens: compressedTokens,
166
+ token_reduction: tokenReduction,
167
+ token_reduction_percentage: compressionRatio,
168
+ original_size: originalSize,
169
+ compressed_size: compressedSize,
170
+ size_reduction: sizeReduction,
171
+ size_reduction_percentage: sizeCompressionRatio,
172
+ information_preservation: informationPreservation,
173
+ compression_efficiency: this.calculateCompressionEfficiency(compressionRatio, informationPreservation)
174
+ };
175
+ }
176
+
177
+ /**
178
+ * 성능 메트릭을 계산합니다
179
+ * @param {Object} metadata - 메타데이터
180
+ * @returns {Object} 성능 메트릭
181
+ */
182
+ calculatePerformanceMetrics(metadata) {
183
+ const performance = {
184
+ compression_time: metadata.processingTime || 0,
185
+ decompression_time: metadata.decompressionTime || 0,
186
+ memory_usage: metadata.memoryUsage || 0,
187
+ throughput: 0,
188
+ tokens_per_second: 0
189
+ };
190
+
191
+ // 처리량 계산
192
+ if (performance.compression_time > 0 && metadata.originalTokens) {
193
+ performance.tokens_per_second = (metadata.originalTokens / performance.compression_time) * 1000;
194
+ performance.throughput = (metadata.originalTokens / performance.compression_time) * 1000;
195
+ }
196
+
197
+ // 메모리 효율성 계산
198
+ if (performance.memory_usage > 0 && metadata.originalTokens) {
199
+ performance.memory_efficiency = metadata.originalTokens / performance.memory_usage;
200
+ }
201
+
202
+ // 파이프라인 성능 분석
203
+ if (metadata.pipelineStages) {
204
+ performance.pipeline_analysis = this.analyzePipelinePerformance(metadata.pipelineStages);
205
+ }
206
+
207
+ return performance;
208
+ }
209
+
210
+ /**
211
+ * 품질 메트릭을 계산합니다
212
+ * @param {string} original - 원본 콘텐츠
213
+ * @param {string} compressed - 압축된 콘텐츠
214
+ * @param {Object} metadata - 메타데이터
215
+ * @returns {Object} 품질 메트릭
216
+ */
217
+ calculateQualityMetrics(original, compressed, metadata) {
218
+ const quality = {
219
+ readability_score: this.calculateReadabilityScore(compressed),
220
+ structure_preservation: this.calculateStructurePreservation(original, compressed),
221
+ semantic_similarity: this.calculateSemanticSimilarity(original, compressed),
222
+ information_loss: this.calculateInformationLoss(original, compressed),
223
+ coherence_score: this.calculateCoherenceScore(compressed),
224
+ completeness_score: this.calculateCompletenessScore(original, compressed)
225
+ };
226
+
227
+ // 전체 품질 점수 계산
228
+ quality.overall_quality = this.calculateOverallQuality(quality);
229
+
230
+ return quality;
231
+ }
232
+
233
+ /**
234
+ * 효율성 메트릭을 계산합니다
235
+ * @param {string} original - 원본 콘텐츠
236
+ * @param {string} compressed - 압축된 콘텐츠
237
+ * @param {Object} metadata - 메타데이터
238
+ * @returns {Object} 효율성 메트릭
239
+ */
240
+ calculateEfficiencyMetrics(original, compressed, metadata) {
241
+ const originalTokens = this.tokenCounter.countTokens(original);
242
+ const compressedTokens = this.tokenCounter.countTokens(compressed);
243
+ const processingTime = metadata.processingTime || 1;
244
+
245
+ const efficiency = {
246
+ compression_efficiency: this.calculateCompressionEfficiency(
247
+ ((originalTokens - compressedTokens) / originalTokens) * 100,
248
+ this.calculateInformationPreservation(original, compressed)
249
+ ),
250
+ resource_utilization: this.calculateResourceUtilization(metadata),
251
+ cost_effectiveness: this.calculateCostEffectiveness(originalTokens, compressedTokens, processingTime),
252
+ energy_efficiency: this.calculateEnergyEfficiency(originalTokens, processingTime)
253
+ };
254
+
255
+ return efficiency;
256
+ }
257
+
258
+ /**
259
+ * 정보 보존률을 계산합니다
260
+ * @param {string} original - 원본 콘텐츠
261
+ * @param {string} compressed - 압축된 콘텐츠
262
+ * @returns {number} 정보 보존률 (0-100)
263
+ */
264
+ calculateInformationPreservation(original, compressed) {
265
+ // 키워드 보존률 계산
266
+ const originalKeywords = this.extractKeywords(original);
267
+ const compressedKeywords = this.extractKeywords(compressed);
268
+
269
+ const preservedKeywords = originalKeywords.filter(keyword =>
270
+ compressedKeywords.includes(keyword)
271
+ );
272
+
273
+ const keywordPreservation = originalKeywords.length > 0
274
+ ? (preservedKeywords.length / originalKeywords.length) * 100
275
+ : 100;
276
+
277
+ // 구조 보존률 계산
278
+ const structurePreservation = this.calculateStructurePreservation(original, compressed);
279
+
280
+ // 의미 보존률 계산
281
+ const semanticPreservation = this.calculateSemanticSimilarity(original, compressed);
282
+
283
+ // 가중 평균 계산
284
+ return (keywordPreservation * 0.4 + structurePreservation * 0.3 + semanticPreservation * 0.3);
285
+ }
286
+
287
+ /**
288
+ * 키워드를 추출합니다
289
+ * @param {string} text - 텍스트
290
+ * @returns {Array<string>} 키워드 배열
291
+ */
292
+ extractKeywords(text) {
293
+ const keywords = [];
294
+ const words = text.toLowerCase().split(/\s+/);
295
+
296
+ // 중요한 키워드 패턴
297
+ const keywordPatterns = [
298
+ /\b(goal|objective|task|requirement|critical|important|key|main|primary|essential)\b/g,
299
+ /\b(목표|목적|태스크|요구사항|중요|핵심|주요|필수|기본|우선)\b/g
300
+ ];
301
+
302
+ for (const pattern of keywordPatterns) {
303
+ const matches = text.match(pattern);
304
+ if (matches) {
305
+ keywords.push(...matches);
306
+ }
307
+ }
308
+
309
+ // 고유 키워드만 반환
310
+ return [...new Set(keywords)];
311
+ }
312
+
313
+ /**
314
+ * 구조 보존률을 계산합니다
315
+ * @param {string} original - 원본 콘텐츠
316
+ * @param {string} compressed - 압축된 콘텐츠
317
+ * @returns {number} 구조 보존률 (0-100)
318
+ */
319
+ calculateStructurePreservation(original, compressed) {
320
+ const originalHeaders = (original.match(/^#{1,6}\s+.+$/gm) || []).length;
321
+ const compressedHeaders = (compressed.match(/^#{1,6}\s+.+$/gm) || []).length;
322
+
323
+ const originalLists = (original.match(/^\s*[-*+]\s+/gm) || []).length;
324
+ const compressedLists = (compressed.match(/^\s*[-*+]\s+/gm) || []).length;
325
+
326
+ const originalCodeBlocks = (original.match(/```[\s\S]*?```/g) || []).length;
327
+ const compressedCodeBlocks = (compressed.match(/```[\s\S]*?```/g) || []).length;
328
+
329
+ const headerPreservation = originalHeaders > 0 ? (compressedHeaders / originalHeaders) * 100 : 100;
330
+ const listPreservation = originalLists > 0 ? (compressedLists / originalLists) * 100 : 100;
331
+ const codePreservation = originalCodeBlocks > 0 ? (compressedCodeBlocks / originalCodeBlocks) * 100 : 100;
332
+
333
+ return (headerPreservation + listPreservation + codePreservation) / 3;
334
+ }
335
+
336
+ /**
337
+ * 의미 유사도를 계산합니다
338
+ * @param {string} original - 원본 콘텐츠
339
+ * @param {string} compressed - 압축된 콘텐츠
340
+ * @returns {number} 의미 유사도 (0-100)
341
+ */
342
+ calculateSemanticSimilarity(original, compressed) {
343
+ // 단순한 어휘 기반 유사도 계산
344
+ const originalWords = new Set(original.toLowerCase().split(/\s+/));
345
+ const compressedWords = new Set(compressed.toLowerCase().split(/\s+/));
346
+
347
+ const intersection = new Set([...originalWords].filter(word => compressedWords.has(word)));
348
+ const union = new Set([...originalWords, ...compressedWords]);
349
+
350
+ return union.size > 0 ? (intersection.size / union.size) * 100 : 0;
351
+ }
352
+
353
+ /**
354
+ * 정보 손실률을 계산합니다
355
+ * @param {string} original - 원본 콘텐츠
356
+ * @param {string} compressed - 압축된 콘텐츠
357
+ * @returns {number} 정보 손실률 (0-100)
358
+ */
359
+ calculateInformationLoss(original, compressed) {
360
+ const preservation = this.calculateInformationPreservation(original, compressed);
361
+ return 100 - preservation;
362
+ }
363
+
364
+ /**
365
+ * 가독성 점수를 계산합니다
366
+ * @param {string} text - 텍스트
367
+ * @returns {number} 가독성 점수 (0-100)
368
+ */
369
+ calculateReadabilityScore(text) {
370
+ const sentences = text.split(/[.!?]+/).filter(s => s.trim().length > 0);
371
+ const words = text.split(/\s+/).filter(w => w.trim().length > 0);
372
+
373
+ if (sentences.length === 0 || words.length === 0) return 0;
374
+
375
+ const avgWordsPerSentence = words.length / sentences.length;
376
+ const avgCharsPerWord = words.reduce((sum, word) => sum + word.length, 0) / words.length;
377
+
378
+ // 단순한 가독성 점수 계산
379
+ let score = 100;
380
+
381
+ // 문장 길이 페널티
382
+ if (avgWordsPerSentence > 20) score -= 20;
383
+ else if (avgWordsPerSentence > 15) score -= 10;
384
+
385
+ // 단어 길이 페널티
386
+ if (avgCharsPerWord > 7) score -= 20;
387
+ else if (avgCharsPerWord > 5) score -= 10;
388
+
389
+ return Math.max(0, Math.min(100, score));
390
+ }
391
+
392
+ /**
393
+ * 일관성 점수를 계산합니다
394
+ * @param {string} text - 텍스트
395
+ * @returns {number} 일관성 점수 (0-100)
396
+ */
397
+ calculateCoherenceScore(text) {
398
+ // 단순한 일관성 점수 계산
399
+ const lines = text.split('\n');
400
+ let coherenceScore = 100;
401
+
402
+ // 빈 줄 패턴 확인
403
+ const emptyLinePattern = /^\s*$/;
404
+ const consecutiveEmptyLines = lines.reduce((count, line, index) => {
405
+ if (emptyLinePattern.test(line) && index > 0 && emptyLinePattern.test(lines[index - 1])) {
406
+ return count + 1;
407
+ }
408
+ return count;
409
+ }, 0);
410
+
411
+ coherenceScore -= consecutiveEmptyLines * 2;
412
+
413
+ // 헤더 계층 구조 확인
414
+ const headers = lines.filter(line => line.match(/^#{1,6}\s+/));
415
+ const headerLevels = headers.map(header => header.match(/^(#{1,6})/)[1].length);
416
+
417
+ let previousLevel = 0;
418
+ for (const level of headerLevels) {
419
+ if (level - previousLevel > 1) {
420
+ coherenceScore -= 5; // 헤더 레벨 건너뛰기 페널티
421
+ }
422
+ previousLevel = level;
423
+ }
424
+
425
+ return Math.max(0, Math.min(100, coherenceScore));
426
+ }
427
+
428
+ /**
429
+ * 완성도 점수를 계산합니다
430
+ * @param {string} original - 원본 콘텐츠
431
+ * @param {string} compressed - 압축된 콘텐츠
432
+ * @returns {number} 완성도 점수 (0-100)
433
+ */
434
+ calculateCompletenessScore(original, compressed) {
435
+ // 중요한 섹션이 유지되었는지 확인
436
+ const importantSections = [
437
+ 'goal', 'objective', 'requirement', 'task', 'subtask', 'acceptance criteria',
438
+ '목표', '목적', '요구사항', '태스크', '하위', '승인 기준'
439
+ ];
440
+
441
+ let foundSections = 0;
442
+ const lowerCompressed = compressed.toLowerCase();
443
+
444
+ for (const section of importantSections) {
445
+ if (lowerCompressed.includes(section.toLowerCase())) {
446
+ foundSections++;
447
+ }
448
+ }
449
+
450
+ const completenessRatio = foundSections / importantSections.length;
451
+ return completenessRatio * 100;
452
+ }
453
+
454
+ /**
455
+ * 압축 효율성을 계산합니다
456
+ * @param {number} compressionRatio - 압축률
457
+ * @param {number} informationPreservation - 정보 보존률
458
+ * @returns {number} 압축 효율성 (0-100)
459
+ */
460
+ calculateCompressionEfficiency(compressionRatio, informationPreservation) {
461
+ // 압축률과 정보 보존률의 균형을 고려한 효율성 계산
462
+ const alpha = 0.6; // 압축률 가중치
463
+ const beta = 0.4; // 정보 보존률 가중치
464
+
465
+ return (alpha * compressionRatio) + (beta * informationPreservation);
466
+ }
467
+
468
+ /**
469
+ * 자원 사용률을 계산합니다
470
+ * @param {Object} metadata - 메타데이터
471
+ * @returns {number} 자원 사용률 (0-100)
472
+ */
473
+ calculateResourceUtilization(metadata) {
474
+ // 메모리 사용량, 처리 시간 등을 고려한 자원 사용률
475
+ const memoryScore = metadata.memoryUsage ? Math.min(100, 100 - (metadata.memoryUsage / 1024 / 1024)) : 100;
476
+ const timeScore = metadata.processingTime ? Math.min(100, 100 - (metadata.processingTime / 1000)) : 100;
477
+
478
+ return (memoryScore + timeScore) / 2;
479
+ }
480
+
481
+ /**
482
+ * 비용 효율성을 계산합니다
483
+ * @param {number} originalTokens - 원본 토큰 수
484
+ * @param {number} compressedTokens - 압축된 토큰 수
485
+ * @param {number} processingTime - 처리 시간
486
+ * @returns {number} 비용 효율성 (0-100)
487
+ */
488
+ calculateCostEffectiveness(originalTokens, compressedTokens, processingTime) {
489
+ const tokenSaved = originalTokens - compressedTokens;
490
+ const processingTimeInSeconds = processingTime / 1000;
491
+
492
+ if (processingTimeInSeconds === 0) return 0;
493
+
494
+ // 초당 절약된 토큰 수
495
+ const tokensPerSecond = tokenSaved / processingTimeInSeconds;
496
+
497
+ // 정규화된 비용 효율성 (최대 100)
498
+ return Math.min(100, tokensPerSecond);
499
+ }
500
+
501
+ /**
502
+ * 에너지 효율성을 계산합니다
503
+ * @param {number} originalTokens - 원본 토큰 수
504
+ * @param {number} processingTime - 처리 시간
505
+ * @returns {number} 에너지 효율성 (0-100)
506
+ */
507
+ calculateEnergyEfficiency(originalTokens, processingTime) {
508
+ const processingTimeInSeconds = processingTime / 1000;
509
+
510
+ if (processingTimeInSeconds === 0) return 0;
511
+
512
+ // 초당 처리된 토큰 수
513
+ const tokensPerSecond = originalTokens / processingTimeInSeconds;
514
+
515
+ // 정규화된 에너지 효율성 (최대 100)
516
+ return Math.min(100, tokensPerSecond / 10);
517
+ }
518
+
519
+ /**
520
+ * 전체 품질 점수를 계산합니다
521
+ * @param {Object} quality - 품질 메트릭
522
+ * @returns {number} 전체 품질 점수 (0-100)
523
+ */
524
+ calculateOverallQuality(quality) {
525
+ const weights = {
526
+ readability_score: 0.2,
527
+ structure_preservation: 0.25,
528
+ semantic_similarity: 0.25,
529
+ coherence_score: 0.15,
530
+ completeness_score: 0.15
531
+ };
532
+
533
+ let totalScore = 0;
534
+ let totalWeight = 0;
535
+
536
+ for (const [metric, weight] of Object.entries(weights)) {
537
+ if (quality[metric] !== undefined) {
538
+ totalScore += quality[metric] * weight;
539
+ totalWeight += weight;
540
+ }
541
+ }
542
+
543
+ return totalWeight > 0 ? totalScore / totalWeight : 0;
544
+ }
545
+
546
+ /**
547
+ * 파이프라인 성능을 분석합니다
548
+ * @param {Array<Object>} stages - 파이프라인 스테이지
549
+ * @returns {Object} 파이프라인 성능 분석
550
+ */
551
+ analyzePipelinePerformance(stages) {
552
+ const analysis = {
553
+ total_stages: stages.length,
554
+ total_duration: stages.reduce((sum, stage) => sum + stage.duration, 0),
555
+ average_duration: 0,
556
+ slowest_stage: null,
557
+ fastest_stage: null,
558
+ stage_breakdown: []
559
+ };
560
+
561
+ if (stages.length > 0) {
562
+ analysis.average_duration = analysis.total_duration / stages.length;
563
+
564
+ // 가장 느린/빠른 스테이지 찾기
565
+ let slowest = stages[0];
566
+ let fastest = stages[0];
567
+
568
+ for (const stage of stages) {
569
+ if (stage.duration > slowest.duration) slowest = stage;
570
+ if (stage.duration < fastest.duration) fastest = stage;
571
+ }
572
+
573
+ analysis.slowest_stage = { name: slowest.name, duration: slowest.duration };
574
+ analysis.fastest_stage = { name: fastest.name, duration: fastest.duration };
575
+
576
+ // 스테이지별 세부 분석
577
+ analysis.stage_breakdown = stages.map(stage => ({
578
+ name: stage.name,
579
+ duration: stage.duration,
580
+ percentage: (stage.duration / analysis.total_duration) * 100,
581
+ success: stage.success
582
+ }));
583
+ }
584
+
585
+ return analysis;
586
+ }
587
+
588
+ /**
589
+ * 벤치마크 분석을 수행합니다
590
+ * @param {Object} metrics - 메트릭 데이터
591
+ * @returns {Object} 벤치마크 분석
592
+ */
593
+ analyzeBenchmark(metrics) {
594
+ const benchmark = {
595
+ overall_grade: 'C',
596
+ overall_score: 0,
597
+ category_grades: {},
598
+ recommendations: []
599
+ };
600
+
601
+ let totalScore = 0;
602
+ let categoryCount = 0;
603
+
604
+ // 각 카테고리별 벤치마크 분석
605
+ for (const [category, categoryMetrics] of Object.entries(metrics)) {
606
+ const categoryGrade = this.gradeCategoryMetrics(categoryMetrics);
607
+ benchmark.category_grades[category] = categoryGrade;
608
+ totalScore += categoryGrade.score;
609
+ categoryCount++;
610
+ }
611
+
612
+ // 전체 점수 계산
613
+ benchmark.overall_score = categoryCount > 0 ? totalScore / categoryCount : 0;
614
+ benchmark.overall_grade = this.scoreToGrade(benchmark.overall_score);
615
+
616
+ // 권장사항 생성
617
+ benchmark.recommendations = this.generateRecommendations(metrics, benchmark);
618
+
619
+ return benchmark;
620
+ }
621
+
622
+ /**
623
+ * 카테고리 메트릭을 평가합니다
624
+ * @param {Object} categoryMetrics - 카테고리 메트릭
625
+ * @returns {Object} 카테고리 평가
626
+ */
627
+ gradeCategoryMetrics(categoryMetrics) {
628
+ const grade = {
629
+ score: 0,
630
+ grade: 'F',
631
+ details: {}
632
+ };
633
+
634
+ let totalScore = 0;
635
+ let metricCount = 0;
636
+
637
+ for (const [metric, value] of Object.entries(categoryMetrics)) {
638
+ if (typeof value === 'number' && this.benchmarkThresholds[metric]) {
639
+ const metricGrade = this.gradeMetric(metric, value);
640
+ grade.details[metric] = metricGrade;
641
+ totalScore += metricGrade.score;
642
+ metricCount++;
643
+ }
644
+ }
645
+
646
+ if (metricCount > 0) {
647
+ grade.score = totalScore / metricCount;
648
+ grade.grade = this.scoreToGrade(grade.score);
649
+ }
650
+
651
+ return grade;
652
+ }
653
+
654
+ /**
655
+ * 개별 메트릭을 평가합니다
656
+ * @param {string} metric - 메트릭 이름
657
+ * @param {number} value - 메트릭 값
658
+ * @returns {Object} 메트릭 평가
659
+ */
660
+ gradeMetric(metric, value) {
661
+ const thresholds = this.benchmarkThresholds[metric];
662
+ if (!thresholds) return { score: 50, grade: 'C' };
663
+
664
+ let score = 0;
665
+
666
+ if (value >= thresholds.excellent) {
667
+ score = 90;
668
+ } else if (value >= thresholds.good) {
669
+ score = 80;
670
+ } else if (value >= thresholds.acceptable) {
671
+ score = 70;
672
+ } else if (value >= thresholds.poor) {
673
+ score = 60;
674
+ } else {
675
+ score = 40;
676
+ }
677
+
678
+ return {
679
+ score,
680
+ grade: this.scoreToGrade(score),
681
+ value,
682
+ threshold: thresholds
683
+ };
684
+ }
685
+
686
+ /**
687
+ * 점수를 등급으로 변환합니다
688
+ * @param {number} score - 점수 (0-100)
689
+ * @returns {string} 등급 (A-F)
690
+ */
691
+ scoreToGrade(score) {
692
+ if (score >= 90) return 'A';
693
+ if (score >= 80) return 'B';
694
+ if (score >= 70) return 'C';
695
+ if (score >= 60) return 'D';
696
+ return 'F';
697
+ }
698
+
699
+ /**
700
+ * 분석 결과를 생성합니다
701
+ * @param {Object} metrics - 메트릭 데이터
702
+ * @param {Object} benchmark - 벤치마크 분석
703
+ * @returns {Object} 분석 결과
704
+ */
705
+ generateAnalysis(metrics, benchmark) {
706
+ return {
707
+ summary: this.generateSummary(metrics),
708
+ strengths: this.identifyStrengths(metrics, benchmark),
709
+ weaknesses: this.identifyWeaknesses(metrics, benchmark),
710
+ recommendations: this.generateRecommendations(metrics, benchmark),
711
+ trend_analysis: this.analyzeTrends(),
712
+ comparative_analysis: this.generateComparativeAnalysis(metrics)
713
+ };
714
+ }
715
+
716
+ /**
717
+ * 요약을 생성합니다
718
+ * @param {Object} metrics - 메트릭 데이터
719
+ * @returns {string} 요약
720
+ */
721
+ generateSummary(metrics) {
722
+ const compressionRatio = metrics.compression?.token_reduction_percentage || 0;
723
+ const informationPreservation = metrics.compression?.information_preservation || 0;
724
+ const processingTime = metrics.performance?.compression_time || 0;
725
+
726
+ return `압축률 ${compressionRatio.toFixed(1)}%로 ${informationPreservation.toFixed(1)}%의 정보를 보존하며 ${processingTime}ms 내에 처리되었습니다.`;
727
+ }
728
+
729
+ /**
730
+ * 강점을 식별합니다
731
+ * @param {Object} metrics - 메트릭 데이터
732
+ * @param {Object} benchmark - 벤치마크 분석
733
+ * @returns {Array<string>} 강점 목록
734
+ */
735
+ identifyStrengths(metrics, benchmark) {
736
+ const strengths = [];
737
+
738
+ for (const [category, grade] of Object.entries(benchmark.category_grades)) {
739
+ if (grade.score >= 80) {
740
+ strengths.push(`${category} 카테고리에서 우수한 성능을 보였습니다 (${grade.grade}등급)`);
741
+ }
742
+ }
743
+
744
+ return strengths;
745
+ }
746
+
747
+ /**
748
+ * 약점을 식별합니다
749
+ * @param {Object} metrics - 메트릭 데이터
750
+ * @param {Object} benchmark - 벤치마크 분석
751
+ * @returns {Array<string>} 약점 목록
752
+ */
753
+ identifyWeaknesses(metrics, benchmark) {
754
+ const weaknesses = [];
755
+
756
+ for (const [category, grade] of Object.entries(benchmark.category_grades)) {
757
+ if (grade.score < 60) {
758
+ weaknesses.push(`${category} 카테고리에서 개선이 필요합니다 (${grade.grade}등급)`);
759
+ }
760
+ }
761
+
762
+ return weaknesses;
763
+ }
764
+
765
+ /**
766
+ * 권장사항을 생성합니다
767
+ * @param {Object} metrics - 메트릭 데이터
768
+ * @param {Object} benchmark - 벤치마크 분석
769
+ * @returns {Array<string>} 권장사항 목록
770
+ */
771
+ generateRecommendations(metrics, benchmark) {
772
+ const recommendations = [];
773
+
774
+ // 압축률 기반 권장사항
775
+ const compressionRatio = metrics.compression?.token_reduction_percentage || 0;
776
+ if (compressionRatio < 30) {
777
+ recommendations.push('압축률을 높이기 위해 더 적극적인 압축 전략을 고려하세요.');
778
+ } else if (compressionRatio > 80) {
779
+ recommendations.push('압축률이 너무 높습니다. 정보 손실을 방지하기 위해 덜 적극적인 압축을 고려하세요.');
780
+ }
781
+
782
+ // 성능 기반 권장사항
783
+ const processingTime = metrics.performance?.compression_time || 0;
784
+ if (processingTime > 5000) {
785
+ recommendations.push('처리 시간이 오래 걸립니다. 성능 최적화를 고려하세요.');
786
+ }
787
+
788
+ // 품질 기반 권장사항
789
+ const informationPreservation = metrics.compression?.information_preservation || 0;
790
+ if (informationPreservation < 70) {
791
+ recommendations.push('정보 보존률이 낮습니다. 중요한 정보를 더 잘 보존하는 방법을 고려하세요.');
792
+ }
793
+
794
+ return recommendations;
795
+ }
796
+
797
+ /**
798
+ * 트렌드를 분석합니다
799
+ * @returns {Object} 트렌드 분석
800
+ */
801
+ analyzeTrends() {
802
+ if (this.measurementHistory.length < 2) {
803
+ return { message: '트렌드 분석을 위한 충분한 데이터가 없습니다.' };
804
+ }
805
+
806
+ const recent = this.measurementHistory.slice(-5);
807
+ const trends = {};
808
+
809
+ // 압축률 트렌드
810
+ const compressionRatios = recent.map(m => m.metrics.compression?.token_reduction_percentage || 0);
811
+ trends.compression_ratio = this.calculateTrend(compressionRatios);
812
+
813
+ // 처리 시간 트렌드
814
+ const processingTimes = recent.map(m => m.metrics.performance?.compression_time || 0);
815
+ trends.processing_time = this.calculateTrend(processingTimes);
816
+
817
+ // 품질 트렌드
818
+ const qualityScores = recent.map(m => m.metrics.quality?.overall_quality || 0);
819
+ trends.quality = this.calculateTrend(qualityScores);
820
+
821
+ return trends;
822
+ }
823
+
824
+ /**
825
+ * 트렌드를 계산합니다
826
+ * @param {Array<number>} values - 값 배열
827
+ * @returns {Object} 트렌드 정보
828
+ */
829
+ calculateTrend(values) {
830
+ if (values.length < 2) return { trend: 'stable', change: 0 };
831
+
832
+ const first = values[0];
833
+ const last = values[values.length - 1];
834
+ const change = ((last - first) / first) * 100;
835
+
836
+ let trend = 'stable';
837
+ if (change > 5) trend = 'increasing';
838
+ else if (change < -5) trend = 'decreasing';
839
+
840
+ return { trend, change: change.toFixed(1) };
841
+ }
842
+
843
+ /**
844
+ * 비교 분석을 생성합니다
845
+ * @param {Object} metrics - 메트릭 데이터
846
+ * @returns {Object} 비교 분석
847
+ */
848
+ generateComparativeAnalysis(metrics) {
849
+ const analysis = {
850
+ vs_previous: null,
851
+ vs_average: null,
852
+ vs_best: null
853
+ };
854
+
855
+ if (this.measurementHistory.length > 1) {
856
+ const current = metrics;
857
+ const previous = this.measurementHistory[this.measurementHistory.length - 2].metrics;
858
+
859
+ analysis.vs_previous = {
860
+ compression_ratio_change: this.calculateChange(
861
+ previous.compression?.token_reduction_percentage || 0,
862
+ current.compression?.token_reduction_percentage || 0
863
+ ),
864
+ quality_change: this.calculateChange(
865
+ previous.quality?.overall_quality || 0,
866
+ current.quality?.overall_quality || 0
867
+ ),
868
+ performance_change: this.calculateChange(
869
+ previous.performance?.compression_time || 0,
870
+ current.performance?.compression_time || 0
871
+ )
872
+ };
873
+ }
874
+
875
+ return analysis;
876
+ }
877
+
878
+ /**
879
+ * 변화량을 계산합니다
880
+ * @param {number} previous - 이전 값
881
+ * @param {number} current - 현재 값
882
+ * @returns {Object} 변화량 정보
883
+ */
884
+ calculateChange(previous, current) {
885
+ const change = current - previous;
886
+ const changePercentage = previous > 0 ? (change / previous) * 100 : 0;
887
+
888
+ return {
889
+ absolute: change,
890
+ percentage: changePercentage.toFixed(1),
891
+ direction: change > 0 ? 'increase' : change < 0 ? 'decrease' : 'stable'
892
+ };
893
+ }
894
+
895
+ /**
896
+ * 측정 ID를 생성합니다
897
+ * @returns {string} 측정 ID
898
+ */
899
+ generateMeasurementId() {
900
+ const timestamp = Date.now();
901
+ const random = Math.random().toString(36).substr(2, 9);
902
+ return `metric_${timestamp}_${random}`;
903
+ }
904
+
905
+ /**
906
+ * 측정 결과를 내보냅니다
907
+ * @param {string} measurementId - 측정 ID
908
+ * @param {string} format - 내보내기 형식 ('json', 'csv', 'report')
909
+ * @returns {string} 내보내기 결과
910
+ */
911
+ exportMeasurement(measurementId, format = 'json') {
912
+ const measurement = this.measurements.get(measurementId);
913
+ if (!measurement) {
914
+ throw new Error(`측정 결과를 찾을 수 없습니다: ${measurementId}`);
915
+ }
916
+
917
+ switch (format) {
918
+ case 'json':
919
+ return JSON.stringify(measurement, null, 2);
920
+ case 'csv':
921
+ return this.convertToCSV(measurement);
922
+ case 'report':
923
+ return this.generateReport(measurement);
924
+ default:
925
+ throw new Error(`지원되지 않는 형식: ${format}`);
926
+ }
927
+ }
928
+
929
+ /**
930
+ * CSV 형식으로 변환합니다
931
+ * @param {Object} measurement - 측정 결과
932
+ * @returns {string} CSV 문자열
933
+ */
934
+ convertToCSV(measurement) {
935
+ // 플랫한 구조로 변환
936
+ const flatData = this.flattenObject(measurement.metrics);
937
+
938
+ const headers = Object.keys(flatData);
939
+ const values = Object.values(flatData);
940
+
941
+ return [headers.join(','), values.join(',')].join('\n');
942
+ }
943
+
944
+ /**
945
+ * 객체를 평면화합니다
946
+ * @param {Object} obj - 객체
947
+ * @param {string} prefix - 접두사
948
+ * @returns {Object} 평면화된 객체
949
+ */
950
+ flattenObject(obj, prefix = '') {
951
+ const flattened = {};
952
+
953
+ for (const [key, value] of Object.entries(obj)) {
954
+ const newKey = prefix ? `${prefix}.${key}` : key;
955
+
956
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
957
+ Object.assign(flattened, this.flattenObject(value, newKey));
958
+ } else {
959
+ flattened[newKey] = value;
960
+ }
961
+ }
962
+
963
+ return flattened;
964
+ }
965
+
966
+ /**
967
+ * 보고서를 생성합니다
968
+ * @param {Object} measurement - 측정 결과
969
+ * @returns {string} 보고서
970
+ */
971
+ generateReport(measurement) {
972
+ const report = [];
973
+
974
+ report.push('# 압축 성능 보고서');
975
+ report.push(`측정 ID: ${measurement.id}`);
976
+ report.push(`측정 시간: ${new Date(measurement.timestamp).toLocaleString()}`);
977
+ report.push('');
978
+
979
+ // 요약
980
+ report.push('## 요약');
981
+ report.push(measurement.analysis.summary);
982
+ report.push('');
983
+
984
+ // 벤치마크 결과
985
+ report.push('## 벤치마크 결과');
986
+ report.push(`전체 등급: ${measurement.benchmark.overall_grade} (${measurement.benchmark.overall_score.toFixed(1)}점)`);
987
+ report.push('');
988
+
989
+ // 강점과 약점
990
+ if (measurement.analysis.strengths.length > 0) {
991
+ report.push('## 강점');
992
+ measurement.analysis.strengths.forEach(strength => {
993
+ report.push(`- ${strength}`);
994
+ });
995
+ report.push('');
996
+ }
997
+
998
+ if (measurement.analysis.weaknesses.length > 0) {
999
+ report.push('## 약점');
1000
+ measurement.analysis.weaknesses.forEach(weakness => {
1001
+ report.push(`- ${weakness}`);
1002
+ });
1003
+ report.push('');
1004
+ }
1005
+
1006
+ // 권장사항
1007
+ if (measurement.analysis.recommendations.length > 0) {
1008
+ report.push('## 권장사항');
1009
+ measurement.analysis.recommendations.forEach(rec => {
1010
+ report.push(`- ${rec}`);
1011
+ });
1012
+ report.push('');
1013
+ }
1014
+
1015
+ return report.join('\n');
1016
+ }
1017
+
1018
+ /**
1019
+ * 리소스를 정리합니다
1020
+ */
1021
+ cleanup() {
1022
+ if (this.tokenCounter) {
1023
+ this.tokenCounter.cleanup();
1024
+ }
1025
+ this.measurements.clear();
1026
+ this.benchmarks.clear();
1027
+ this.measurementHistory.length = 0;
1028
+ }
1029
+ }
1030
+
1031
+ export default CompressionMetrics;