aiwf 0.3.7 → 0.3.12

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 (605) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/README.ko.md +114 -28
  3. package/README.md +152 -40
  4. package/docs/AI-WORKFLOW.md +121 -19
  5. package/docs/API_DOCUMENTATION.md +1 -1
  6. package/docs/API_REFERENCE.md +1 -1
  7. package/docs/CLI_USAGE_GUIDE.ko.md +634 -0
  8. package/docs/CLI_USAGE_GUIDE.md +339 -178
  9. package/docs/COMMANDS_GUIDE.ko.md +308 -4
  10. package/docs/COMMANDS_GUIDE.md +117 -0
  11. package/docs/CONTRIBUTING.ko.md +6 -6
  12. package/docs/CONTRIBUTING.md +6 -6
  13. package/docs/DEVELOPMENT_GUIDE.ko.md +440 -0
  14. package/docs/DEVELOPMENT_GUIDE.md +1 -1
  15. package/docs/EXAMPLES.md +8 -6
  16. package/docs/GETTING_STARTED.md +6 -3
  17. package/docs/STATE_MANAGEMENT_GUIDE.ko.md +278 -0
  18. package/docs/STATE_MANAGEMENT_GUIDE.md +278 -0
  19. package/docs/TROUBLESHOOTING.md +14 -13
  20. package/docs/guides/checkpoint-system-guide-ko.md +356 -0
  21. package/docs/guides/checkpoint-system-guide.md +356 -0
  22. package/docs/guides/independent-sprint-guide-ko.md +321 -0
  23. package/docs/guides/independent-sprint-guide.md +321 -0
  24. package/package.json +30 -3
  25. package/scripts/update-file-lists.js +267 -0
  26. package/src/cli/checkpoint-cli.js +417 -0
  27. package/src/cli/index.js +461 -0
  28. package/src/cli/sprint-cli.js +287 -0
  29. package/src/commands/compress.js +60 -0
  30. package/src/commands/create-project.js +23 -17
  31. package/src/commands/evaluate.js +459 -0
  32. package/src/commands/persona.js +37 -16
  33. package/src/commands/sprint-independent.js +393 -0
  34. package/src/commands/state-refactored.js +419 -0
  35. package/src/commands/state.js +1164 -0
  36. package/src/commands/token.js +312 -0
  37. package/src/commands/yolo-config.js +502 -0
  38. package/src/config/file-lists.js +147 -0
  39. package/src/config/yolo-config-template.yaml +168 -0
  40. package/src/lib/file-downloader.js +7 -72
  41. package/src/lib/github-integration.js +402 -0
  42. package/src/lib/resource-loader-enhanced.js +399 -0
  43. package/src/lib/resource-loader.js +250 -0
  44. package/{claude-code/aiwf/ko → src/lib/resources}/commands/ai-persona.js +1 -1
  45. package/src/lib/state/priority-calculator.js +217 -0
  46. package/src/lib/state/state-index.js +155 -0
  47. package/src/lib/state/task-scanner.js +328 -0
  48. package/src/utils/checkpoint-manager.js +425 -0
  49. package/src/utils/engineering-guard.js +389 -0
  50. package/.aiwf/00_PROJECT_MANIFEST.md +0 -196
  51. package/.aiwf/01_PROJECT_DOCS/ARCHITECTURE.md +0 -121
  52. package/.aiwf/01_PROJECT_DOCS/FEATURE_LEDGER_ADVANCED_USE_CASES.md +0 -412
  53. package/.aiwf/01_PROJECT_DOCS/FEATURE_LEDGER_API_REFERENCE.md +0 -361
  54. package/.aiwf/01_PROJECT_DOCS/FEATURE_LEDGER_COMMANDS_GUIDE.md +0 -254
  55. package/.aiwf/01_PROJECT_DOCS/FEATURE_LEDGER_FAQ.md +0 -365
  56. package/.aiwf/01_PROJECT_DOCS/FEATURE_LEDGER_SYSTEM_OVERVIEW.md +0 -305
  57. package/.aiwf/01_PROJECT_DOCS/FEATURE_LEDGER_USER_GUIDE.md +0 -416
  58. package/.aiwf/01_PROJECT_DOCS/FEATURE_LEDGER_/354/213/234/354/236/221_/352/260/200/354/235/264/353/223/234.md +0 -247
  59. package/.aiwf/02_REQUIREMENTS/CLAUDE.md +0 -78
  60. package/.aiwf/02_REQUIREMENTS/M02_Context_Engineering_Enhancement/M02_milestone_meta.md +0 -34
  61. package/.aiwf/02_REQUIREMENTS/M02_Context_Engineering_Enhancement/PRD_Context_Engineering_Enhancement.md +0 -108
  62. package/.aiwf/02_REQUIREMENTS/M02_Context_Engineering_Enhancement/SPECS_AI_Persona_System.md +0 -299
  63. package/.aiwf/02_REQUIREMENTS/M02_Context_Engineering_Enhancement/SPECS_Feature_Ledger_System.md +0 -330
  64. package/.aiwf/02_REQUIREMENTS/M02_Context_Engineering_Enhancement/SPECS_Token_Optimization.md +0 -833
  65. package/.aiwf/02_REQUIREMENTS/M03_Simone_Integration_Enhancement/M03_milestone_meta.md +0 -55
  66. package/.aiwf/02_REQUIREMENTS/M03_Simone_Integration_Enhancement/SPECS_AIWF_Simplified_Plan.md +0 -221
  67. package/.aiwf/03_SPRINTS/CLAUDE.md +0 -83
  68. package/.aiwf/03_SPRINTS/S01_M02_context_foundation/S01_M02_sprint_meta.md +0 -95
  69. 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 +0 -111
  70. 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 +0 -115
  71. 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 +0 -141
  72. package/.aiwf/03_SPRINTS/S01_M02_context_foundation/TX04_S01_Feature_Ledger_/353/254/270/354/204/234/355/231/224.md +0 -114
  73. 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 +0 -123
  74. 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 +0 -114
  75. 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 +0 -114
  76. 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 +0 -112
  77. 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 +0 -118
  78. 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 +0 -118
  79. 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 +0 -128
  80. 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 +0 -122
  81. package/.aiwf/03_SPRINTS/S02_M02_ai_enhancement/S02_M02_sprint_meta.md +0 -107
  82. 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 +0 -129
  83. 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 +0 -152
  84. 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 +0 -186
  85. 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 +0 -192
  86. 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 +0 -162
  87. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/S03_FINAL_SPRINT_SUMMARY.md +0 -137
  88. package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/S03_M02_sprint_meta.md +0 -105
  89. 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 +0 -214
  90. 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 +0 -177
  91. 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 +0 -206
  92. 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 +0 -151
  93. package/.aiwf/04_GENERAL_TASKS/CLAUDE.md +0 -96
  94. package/.aiwf/04_GENERAL_TASKS/TX001_complete_english_translation.md +0 -127
  95. package/.aiwf/06_FEATURE_LEDGERS/FEATURE_GIT_INTEGRATION.md +0 -314
  96. package/.aiwf/06_FEATURE_LEDGERS/FEATURE_INTEGRATION_GUIDE.md +0 -227
  97. package/.aiwf/06_FEATURE_LEDGERS/FEATURE_LEDGER_INDEX.md +0 -23
  98. package/.aiwf/06_FEATURE_LEDGERS/FEATURE_SCHEMA.md +0 -205
  99. package/.aiwf/06_FEATURE_LEDGERS/FEATURE_STATE_DIAGRAM.md +0 -190
  100. package/.aiwf/06_FEATURE_LEDGERS/active/FL001_user_authentication_system.md +0 -47
  101. package/.aiwf/06_FEATURE_LEDGERS/active/FL002_user_authentication_system.md +0 -47
  102. package/.aiwf/07_AI_PERSONAS/architect/best_practices.md +0 -104
  103. package/.aiwf/07_AI_PERSONAS/architect/context_rules.md +0 -46
  104. package/.aiwf/07_AI_PERSONAS/architect/knowledge_base.md +0 -235
  105. package/.aiwf/07_AI_PERSONAS/backend/best_practices.md +0 -363
  106. package/.aiwf/07_AI_PERSONAS/backend/context_rules.md +0 -61
  107. package/.aiwf/07_AI_PERSONAS/backend/knowledge_base.md +0 -623
  108. package/.aiwf/07_AI_PERSONAS/data_analyst/best_practices.md +0 -32
  109. package/.aiwf/07_AI_PERSONAS/data_analyst/context_rules.md +0 -43
  110. package/.aiwf/07_AI_PERSONAS/data_analyst/knowledge_base.md +0 -36
  111. package/.aiwf/07_AI_PERSONAS/frontend/best_practices.md +0 -31
  112. package/.aiwf/07_AI_PERSONAS/frontend/context_rules.md +0 -43
  113. package/.aiwf/07_AI_PERSONAS/frontend/knowledge_base.md +0 -32
  114. package/.aiwf/07_AI_PERSONAS/security/best_practices.md +0 -63
  115. package/.aiwf/07_AI_PERSONAS/security/context_rules.md +0 -53
  116. package/.aiwf/07_AI_PERSONAS/security/knowledge_base.md +0 -93
  117. package/.aiwf/10_PERSONAS/active.json +0 -1
  118. package/.aiwf/10_STATE_OF_PROJECT/2025-07-09-07-20-solid-progress.md +0 -144
  119. package/.aiwf/98_PROMPTS/SAAS_DEVELOPMENT_GUIDE.md +0 -302
  120. package/.aiwf/98_PROMPTS/github_integration.md +0 -130
  121. package/.aiwf/98_PROMPTS/useful-prompts.md +0 -31
  122. package/.aiwf/98_PROMPTS/vibe-front-prompts.md +0 -89
  123. package/.aiwf/99_TEMPLATES/adr_template.md +0 -49
  124. package/.aiwf/99_TEMPLATES/feature_template.md +0 -263
  125. package/.aiwf/99_TEMPLATES/milestone_meta_template.md +0 -25
  126. package/.aiwf/99_TEMPLATES/project_manifest_template.md +0 -39
  127. package/.aiwf/99_TEMPLATES/sprint_meta_template.md +0 -23
  128. package/.aiwf/99_TEMPLATES/task_template.md +0 -36
  129. package/.aiwf/CLAUDE.md +0 -76
  130. package/.aiwf/ai-tools/README.md +0 -105
  131. package/.aiwf/ai-tools/augment/README.md +0 -371
  132. package/.aiwf/ai-tools/augment/config.json +0 -30
  133. package/.aiwf/ai-tools/augment/template/.augment/aiwf-integration.md +0 -387
  134. package/.aiwf/ai-tools/augment/template/.augment/augment.yaml +0 -347
  135. package/.aiwf/ai-tools/augment/template/augment.config.json +0 -64
  136. package/.aiwf/ai-tools/claude-code/README.md +0 -151
  137. package/.aiwf/ai-tools/claude-code/config.json +0 -28
  138. package/.aiwf/ai-tools/claude-code/template/CLAUDE.md +0 -91
  139. package/.aiwf/ai-tools/cursor/README.md +0 -314
  140. package/.aiwf/ai-tools/cursor/config.json +0 -29
  141. package/.aiwf/ai-tools/cursor/template/.cursorrules +0 -362
  142. package/.aiwf/ai-tools/github-copilot/README.md +0 -195
  143. package/.aiwf/ai-tools/github-copilot/config.json +0 -24
  144. package/.aiwf/ai-tools/github-copilot/template/.github/copilot-instructions.md +0 -202
  145. package/.aiwf/ai-tools/windsurf/README.md +0 -355
  146. package/.aiwf/ai-tools/windsurf/config.json +0 -29
  147. package/.aiwf/ai-tools/windsurf/template/.windsurf/aiwf-rules.md +0 -260
  148. package/.aiwf/ai-tools/windsurf/template/.windsurf/windsurf.config.js +0 -312
  149. package/.aiwf/ai-tools/windsurf/template/windsurf.config.json +0 -63
  150. package/.aiwf/config/language.json +0 -6
  151. package/.aiwf/feature-ledger/FL-001-authentication.json +0 -52
  152. package/.aiwf/feature-ledger/feature-index.json +0 -20
  153. package/.aiwf/installed.flag +0 -1
  154. package/.aiwf/metrics/metrics.json +0 -18
  155. package/.aiwf/personas/current.json +0 -5
  156. package/.aiwf/scripts/cache-templates.js +0 -209
  157. package/.aiwf/scripts/create-offline.js +0 -86
  158. package/.aiwf/scripts/create-project.js +0 -151
  159. package/.aiwf/scripts/feature-progress-calculator.cjs +0 -236
  160. package/.aiwf/scripts/git-integration.cjs +0 -391
  161. package/.aiwf/scripts/install-git-hooks.cjs +0 -226
  162. package/.aiwf/scripts/test-commit-parsing.cjs +0 -125
  163. package/.aiwf/scripts/update-feature-status.cjs +0 -198
  164. package/.aiwf/test-results-s02.json +0 -36
  165. package/.claude/commands/aiwf/aiwf_add_task_to_sprint.md +0 -283
  166. package/.claude/commands/aiwf/aiwf_changelog.md +0 -82
  167. package/.claude/commands/aiwf/aiwf_code_review.md +0 -88
  168. package/.claude/commands/aiwf/aiwf_commit.md +0 -160
  169. package/.claude/commands/aiwf/aiwf_compress_aggressive_persona.md +0 -53
  170. package/.claude/commands/aiwf/aiwf_compress_context.md +0 -116
  171. package/.claude/commands/aiwf/aiwf_compress_minimal_persona.md +0 -48
  172. package/.claude/commands/aiwf/aiwf_compress_stats.md +0 -79
  173. package/.claude/commands/aiwf/aiwf_compress_with_persona.md +0 -51
  174. package/.claude/commands/aiwf/aiwf_create_feature_ledger.md +0 -54
  175. package/.claude/commands/aiwf/aiwf_create_general_task.md +0 -147
  176. package/.claude/commands/aiwf/aiwf_create_milestone_plan.md +0 -194
  177. package/.claude/commands/aiwf/aiwf_create_prd.md +0 -280
  178. package/.claude/commands/aiwf/aiwf_create_sprint_tasks.md +0 -189
  179. package/.claude/commands/aiwf/aiwf_create_sprints_from_milestone.md +0 -121
  180. package/.claude/commands/aiwf/aiwf_default_mode.md +0 -44
  181. package/.claude/commands/aiwf/aiwf_discuss_review.md +0 -29
  182. package/.claude/commands/aiwf/aiwf_do_task.md +0 -109
  183. package/.claude/commands/aiwf/aiwf_docs.md +0 -225
  184. package/.claude/commands/aiwf/aiwf_evaluate.md +0 -92
  185. package/.claude/commands/aiwf/aiwf_get_feature_details.md +0 -78
  186. package/.claude/commands/aiwf/aiwf_infinite.md +0 -202
  187. package/.claude/commands/aiwf/aiwf_initialize.md +0 -134
  188. package/.claude/commands/aiwf/aiwf_install_git_hooks.md +0 -63
  189. package/.claude/commands/aiwf/aiwf_issue_create.md +0 -65
  190. package/.claude/commands/aiwf/aiwf_link_feature_branch.md +0 -43
  191. package/.claude/commands/aiwf/aiwf_link_feature_commit.md +0 -46
  192. package/.claude/commands/aiwf/aiwf_link_feature_to_milestone.md +0 -57
  193. package/.claude/commands/aiwf/aiwf_list_features.md +0 -54
  194. package/.claude/commands/aiwf/aiwf_mermaid.md +0 -272
  195. package/.claude/commands/aiwf/aiwf_persona_architect.md +0 -48
  196. package/.claude/commands/aiwf/aiwf_persona_backend.md +0 -37
  197. package/.claude/commands/aiwf/aiwf_persona_data_analyst.md +0 -37
  198. package/.claude/commands/aiwf/aiwf_persona_frontend.md +0 -37
  199. package/.claude/commands/aiwf/aiwf_persona_security.md +0 -48
  200. package/.claude/commands/aiwf/aiwf_persona_status.md +0 -50
  201. package/.claude/commands/aiwf/aiwf_pr_create.md +0 -76
  202. package/.claude/commands/aiwf/aiwf_prime.md +0 -9
  203. package/.claude/commands/aiwf/aiwf_project_review.md +0 -261
  204. package/.claude/commands/aiwf/aiwf_switch_language.md +0 -160
  205. package/.claude/commands/aiwf/aiwf_test.md +0 -124
  206. package/.claude/commands/aiwf/aiwf_testing_review.md +0 -198
  207. package/.claude/commands/aiwf/aiwf_tm-run-all-subtask.md +0 -210
  208. package/.claude/commands/aiwf/aiwf_ultrathink_code_advanced.md +0 -460
  209. package/.claude/commands/aiwf/aiwf_ultrathink_code_basic.md +0 -165
  210. package/.claude/commands/aiwf/aiwf_ultrathink_general.md +0 -305
  211. package/.claude/commands/aiwf/aiwf_update_docs_kr.md +0 -25
  212. package/.claude/commands/aiwf/aiwf_update_feature_status.md +0 -53
  213. package/.claude/commands/aiwf/aiwf_yolo.md +0 -300
  214. package/.eslintrc.json +0 -26
  215. package/.prettierrc +0 -10
  216. package/CLAUDE.md +0 -254
  217. package/RELEASE_NOTES_M02.md +0 -177
  218. package/TEST_RECOVERY_PLAN.md +0 -68
  219. package/claude-code/aiwf/en/.aiwf/00_PROJECT_MANIFEST.md +0 -49
  220. package/claude-code/aiwf/en/.aiwf/01_PROJECT_DOCS/ARCHITECTURE.md +0 -55
  221. package/claude-code/aiwf/en/.aiwf/02_REQUIREMENTS/CLAUDE.md +0 -78
  222. package/claude-code/aiwf/en/.aiwf/02_REQUIREMENTS/M01_Backend_Setup/M01_milestone_meta.md +0 -42
  223. package/claude-code/aiwf/en/.aiwf/02_REQUIREMENTS/M01_Backend_Setup/PRD_AMEND_01_Auth_Flow_Update.md +0 -73
  224. package/claude-code/aiwf/en/.aiwf/02_REQUIREMENTS/M01_Backend_Setup/PRD_Backend_Setup.md +0 -98
  225. package/claude-code/aiwf/en/.aiwf/02_REQUIREMENTS/M01_Backend_Setup/SPECS_API_V1.md +0 -232
  226. package/claude-code/aiwf/en/.aiwf/03_SPRINTS/CLAUDE.md +0 -83
  227. package/claude-code/aiwf/en/.aiwf/03_SPRINTS/S01_M01_Initial_API/S01_sprint_meta.md +0 -49
  228. package/claude-code/aiwf/en/.aiwf/03_SPRINTS/S01_M01_Initial_API/T01_S01_Setup_Project_Structure.md +0 -60
  229. package/claude-code/aiwf/en/.aiwf/04_GENERAL_TASKS/CLAUDE.md +0 -96
  230. package/claude-code/aiwf/en/.aiwf/04_GENERAL_TASKS/T002_API_Rate_Limiting.md +0 -54
  231. package/claude-code/aiwf/en/.aiwf/04_GENERAL_TASKS/TX001_Refactor_Logging_Module.md +0 -58
  232. package/claude-code/aiwf/en/.aiwf/05_ARCHITECTURAL_DECISIONS/ADR001_Chosen_Database_System.md +0 -119
  233. package/claude-code/aiwf/en/.aiwf/05_ARCHITECTURAL_DECISIONS/ADR002_API_Authentication_Method.md +0 -124
  234. package/claude-code/aiwf/en/.aiwf/10_STATE_OF_PROJECT/2025-06-12-12-00-needs-focus.md +0 -139
  235. package/claude-code/aiwf/en/.aiwf/10_STATE_OF_PROJECT/2025-06-12-12-00-test-alignment.md +0 -155
  236. package/claude-code/aiwf/en/.aiwf/10_STATE_OF_PROJECT/2025-06-13-00-50-solid-progress.md +0 -122
  237. package/claude-code/aiwf/en/.aiwf/10_STATE_OF_PROJECT/2025-06-14-08-30-infrastructure-challenges.md +0 -141
  238. package/claude-code/aiwf/en/.aiwf/10_STATE_OF_PROJECT/2025-06-16-21-48-critical-foundation-issues.md +0 -177
  239. package/claude-code/aiwf/en/.aiwf/10_STATE_OF_PROJECT/2025-06-17-15-08-solid-progress.md +0 -149
  240. package/claude-code/aiwf/en/.aiwf/10_STATE_OF_PROJECT/index.json +0 -5
  241. package/claude-code/aiwf/en/.aiwf/10_STATE_OF_PROJECT/sync-index.js +0 -78
  242. package/claude-code/aiwf/en/.aiwf/98_PROMPTS/github_integration.md +0 -130
  243. package/claude-code/aiwf/en/.aiwf/98_PROMPTS/useful-prompts.md +0 -31
  244. package/claude-code/aiwf/en/.aiwf/98_PROMPTS/vibe-front-prompts.md +0 -89
  245. package/claude-code/aiwf/en/.aiwf/99_TEMPLATES/adr_template.md +0 -49
  246. package/claude-code/aiwf/en/.aiwf/99_TEMPLATES/milestone_meta_template.md +0 -25
  247. package/claude-code/aiwf/en/.aiwf/99_TEMPLATES/project_manifest_template.md +0 -39
  248. package/claude-code/aiwf/en/.aiwf/99_TEMPLATES/sprint_meta_template.md +0 -23
  249. package/claude-code/aiwf/en/.aiwf/99_TEMPLATES/task_template.md +0 -36
  250. package/claude-code/aiwf/en/.aiwf/CLAUDE.md +0 -74
  251. package/claude-code/aiwf/en/.aiwf/README.md +0 -97
  252. package/claude-code/aiwf/en/.claude/CLAUDE_BE.md +0 -276
  253. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_changelog.md +0 -82
  254. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_code_review.md +0 -88
  255. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_commit.md +0 -160
  256. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_create_feature_ledger.md +0 -54
  257. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_create_general_task.md +0 -147
  258. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_create_milestone_plan.md +0 -194
  259. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_create_prd.md +0 -272
  260. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_create_sprint_tasks.md +0 -189
  261. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_create_sprints_from_milestone.md +0 -121
  262. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_create_testcase.md +0 -561
  263. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_default_mode.md +0 -66
  264. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_discuss_review.md +0 -29
  265. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_do_task.md +0 -109
  266. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_docs.md +0 -225
  267. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_get_feature_details.md +0 -78
  268. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_infinite.md +0 -202
  269. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_initialize.md +0 -134
  270. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_issue_create.md +0 -65
  271. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_link_feature_to_milestone.md +0 -57
  272. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_list_features.md +0 -54
  273. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_mermaid.md +0 -272
  274. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_persona_architect.md +0 -60
  275. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_persona_backend.md +0 -60
  276. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_persona_data_analyst.md +0 -60
  277. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_persona_frontend.md +0 -60
  278. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_persona_security.md +0 -60
  279. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_persona_status.md +0 -72
  280. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_pr_create.md +0 -76
  281. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_prime.md +0 -9
  282. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_project_review.md +0 -261
  283. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_switch_language.md +0 -160
  284. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_test.md +0 -125
  285. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_testing_review.md +0 -198
  286. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_tm-run-all-subtask.md +0 -206
  287. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_ultrathink_code_advanced.md +0 -460
  288. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_ultrathink_code_basic.md +0 -165
  289. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_ultrathink_general.md +0 -362
  290. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_update_feature_status.md +0 -53
  291. package/claude-code/aiwf/en/.claude/commands/aiwf/aiwf_yolo.md +0 -300
  292. package/claude-code/aiwf/en/.claude/mcp.json +0 -31
  293. package/claude-code/aiwf/en/.claude/settings.json +0 -102
  294. package/claude-code/aiwf/en/commands/ai-persona.js +0 -667
  295. package/claude-code/aiwf/en/commands/compress-context.js +0 -355
  296. package/claude-code/aiwf/en/commands/feature-ledger.js +0 -565
  297. package/claude-code/aiwf/en/config/commit-patterns.js +0 -103
  298. package/claude-code/aiwf/en/hooks/install-hooks.sh +0 -100
  299. package/claude-code/aiwf/en/hooks/post-commit +0 -84
  300. package/claude-code/aiwf/en/tests/compression-test-suite.js +0 -1252
  301. package/claude-code/aiwf/en/tests/test-git-integration.js +0 -164
  302. package/claude-code/aiwf/en/tests/token-tracking.test.js +0 -537
  303. package/claude-code/aiwf/en/utils/context-compressor.js +0 -583
  304. package/claude-code/aiwf/en/utils/git-utils.js +0 -220
  305. package/claude-code/aiwf/en/utils/text-summarizer.js +0 -487
  306. package/claude-code/aiwf/ko/.aiwf/00_PROJECT_MANIFEST.md +0 -49
  307. package/claude-code/aiwf/ko/.aiwf/01_PROJECT_DOCS/ARCHITECTURE.md +0 -55
  308. package/claude-code/aiwf/ko/.aiwf/02_REQUIREMENTS/CLAUDE.md +0 -78
  309. package/claude-code/aiwf/ko/.aiwf/02_REQUIREMENTS/M01_Backend_Setup/M01_milestone_meta.md +0 -42
  310. package/claude-code/aiwf/ko/.aiwf/02_REQUIREMENTS/M01_Backend_Setup/PRD_AMEND_01_Auth_Flow_Update.md +0 -73
  311. package/claude-code/aiwf/ko/.aiwf/02_REQUIREMENTS/M01_Backend_Setup/PRD_Backend_Setup.md +0 -98
  312. package/claude-code/aiwf/ko/.aiwf/02_REQUIREMENTS/M01_Backend_Setup/SPECS_API_V1.md +0 -232
  313. package/claude-code/aiwf/ko/.aiwf/03_SPRINTS/CLAUDE.md +0 -83
  314. package/claude-code/aiwf/ko/.aiwf/03_SPRINTS/S01_M01_Initial_API/S01_sprint_meta.md +0 -49
  315. package/claude-code/aiwf/ko/.aiwf/03_SPRINTS/S01_M01_Initial_API/T01_S01_Setup_Project_Structure.md +0 -60
  316. package/claude-code/aiwf/ko/.aiwf/04_GENERAL_TASKS/CLAUDE.md +0 -96
  317. package/claude-code/aiwf/ko/.aiwf/04_GENERAL_TASKS/T002_API_Rate_Limiting.md +0 -54
  318. package/claude-code/aiwf/ko/.aiwf/04_GENERAL_TASKS/TX001_Refactor_Logging_Module.md +0 -58
  319. package/claude-code/aiwf/ko/.aiwf/05_ARCHITECTURAL_DECISIONS/ADR001_Chosen_Database_System.md +0 -119
  320. package/claude-code/aiwf/ko/.aiwf/05_ARCHITECTURAL_DECISIONS/ADR002_API_Authentication_Method.md +0 -124
  321. package/claude-code/aiwf/ko/.aiwf/06_FEATURE_LEDGERS/FEATURE_ID_GENERATOR.md +0 -138
  322. package/claude-code/aiwf/ko/.aiwf/06_FEATURE_LEDGERS/FEATURE_INDEX.md +0 -186
  323. package/claude-code/aiwf/ko/.aiwf/06_FEATURE_LEDGERS/FEATURE_METADATA.md +0 -240
  324. package/claude-code/aiwf/ko/.aiwf/06_FEATURE_LEDGERS/FEATURE_WORKFLOW.md +0 -183
  325. package/claude-code/aiwf/ko/.aiwf/06_FEATURE_LEDGERS/README.md +0 -94
  326. 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 +0 -154
  327. 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 +0 -272
  328. 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 +0 -266
  329. package/claude-code/aiwf/ko/.aiwf/06_FEATURE_LEDGERS/schemas/feature_schema.json +0 -122
  330. package/claude-code/aiwf/ko/.aiwf/06_FEATURE_LEDGERS/schemas/feature_validator.cjs +0 -406
  331. package/claude-code/aiwf/ko/.aiwf/10_STATE_OF_PROJECT/2025-06-12-12-00-needs-focus.md +0 -139
  332. package/claude-code/aiwf/ko/.aiwf/10_STATE_OF_PROJECT/2025-06-12-12-00-test-alignment.md +0 -155
  333. package/claude-code/aiwf/ko/.aiwf/10_STATE_OF_PROJECT/2025-06-13-00-50-solid-progress.md +0 -122
  334. package/claude-code/aiwf/ko/.aiwf/10_STATE_OF_PROJECT/2025-06-14-08-30-infrastructure-challenges.md +0 -141
  335. package/claude-code/aiwf/ko/.aiwf/10_STATE_OF_PROJECT/2025-06-16-21-48-critical-foundation-issues.md +0 -177
  336. package/claude-code/aiwf/ko/.aiwf/10_STATE_OF_PROJECT/2025-06-17-15-08-solid-progress.md +0 -149
  337. package/claude-code/aiwf/ko/.aiwf/10_STATE_OF_PROJECT/index.json +0 -5
  338. package/claude-code/aiwf/ko/.aiwf/10_STATE_OF_PROJECT/sync-index.js +0 -78
  339. package/claude-code/aiwf/ko/.aiwf/98_PROMPTS/github_integration.md +0 -130
  340. package/claude-code/aiwf/ko/.aiwf/98_PROMPTS/useful-prompts.md +0 -31
  341. package/claude-code/aiwf/ko/.aiwf/98_PROMPTS/vibe-front-prompts.md +0 -89
  342. package/claude-code/aiwf/ko/.aiwf/99_TEMPLATES/adr_template.md +0 -49
  343. package/claude-code/aiwf/ko/.aiwf/99_TEMPLATES/milestone_meta_template.md +0 -25
  344. package/claude-code/aiwf/ko/.aiwf/99_TEMPLATES/project_manifest_template.md +0 -39
  345. package/claude-code/aiwf/ko/.aiwf/99_TEMPLATES/sprint_meta_template.md +0 -23
  346. package/claude-code/aiwf/ko/.aiwf/99_TEMPLATES/task_template.md +0 -36
  347. package/claude-code/aiwf/ko/.aiwf/CLAUDE.md +0 -76
  348. package/claude-code/aiwf/ko/.aiwf/README.md +0 -97
  349. package/claude-code/aiwf/ko/.claude/CLAUDE_BE.md +0 -276
  350. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_changelog.md +0 -82
  351. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_code_review.md +0 -88
  352. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_commit.md +0 -160
  353. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_compress_aggressive_persona.md +0 -53
  354. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_compress_context.md +0 -116
  355. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_compress_minimal_persona.md +0 -48
  356. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_compress_stats.md +0 -79
  357. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_compress_with_persona.md +0 -51
  358. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_create_feature_ledger.md +0 -54
  359. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_create_general_task.md +0 -147
  360. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_create_milestone_plan.md +0 -194
  361. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_create_prd.md +0 -280
  362. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_create_sprint_tasks.md +0 -189
  363. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_create_sprints_from_milestone.md +0 -121
  364. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_create_testcase.md +0 -561
  365. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_default_mode.md +0 -44
  366. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_discuss_review.md +0 -29
  367. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_do_task.md +0 -109
  368. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_docs.md +0 -225
  369. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_evaluate.md +0 -92
  370. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_get_feature_details.md +0 -78
  371. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_infinite.md +0 -202
  372. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_initialize.md +0 -134
  373. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_issue_create.md +0 -65
  374. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_link_feature_to_milestone.md +0 -57
  375. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_list_features.md +0 -54
  376. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_mermaid.md +0 -272
  377. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_architect.md +0 -48
  378. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_backend.md +0 -37
  379. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_data_analyst.md +0 -37
  380. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_frontend.md +0 -37
  381. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_security.md +0 -48
  382. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_status.md +0 -50
  383. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_pr_create.md +0 -76
  384. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_prime.md +0 -9
  385. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_project_review.md +0 -261
  386. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_switch_language.md +0 -160
  387. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_test.md +0 -124
  388. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_testing_review.md +0 -198
  389. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_tm-run-all-subtask.md +0 -210
  390. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_ultrathink_code_advanced.md +0 -460
  391. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_ultrathink_code_basic.md +0 -165
  392. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_ultrathink_general.md +0 -305
  393. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_update_docs_kr.md +0 -25
  394. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_update_feature_status.md +0 -53
  395. package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_yolo.md +0 -300
  396. package/claude-code/aiwf/ko/.claude/mcp.json +0 -31
  397. package/claude-code/aiwf/ko/.claude/settings.json +0 -102
  398. package/claude-code/aiwf/ko/CLAUDE.md +0 -76
  399. package/claude-code/aiwf/ko/ai-tools/README.md +0 -105
  400. package/claude-code/aiwf/ko/ai-tools/augment/README.md +0 -371
  401. package/claude-code/aiwf/ko/ai-tools/augment/config.json +0 -30
  402. package/claude-code/aiwf/ko/ai-tools/augment/template/.augment/aiwf-integration.md +0 -387
  403. package/claude-code/aiwf/ko/ai-tools/augment/template/.augment/augment.yaml +0 -347
  404. package/claude-code/aiwf/ko/ai-tools/augment/template/augment.config.json +0 -64
  405. package/claude-code/aiwf/ko/ai-tools/claude-code/README.md +0 -151
  406. package/claude-code/aiwf/ko/ai-tools/claude-code/config.json +0 -28
  407. package/claude-code/aiwf/ko/ai-tools/claude-code/template/CLAUDE.md +0 -91
  408. package/claude-code/aiwf/ko/ai-tools/cursor/README.md +0 -314
  409. package/claude-code/aiwf/ko/ai-tools/cursor/config.json +0 -29
  410. package/claude-code/aiwf/ko/ai-tools/cursor/template/.cursorrules +0 -362
  411. package/claude-code/aiwf/ko/ai-tools/github-copilot/README.md +0 -195
  412. package/claude-code/aiwf/ko/ai-tools/github-copilot/config.json +0 -24
  413. package/claude-code/aiwf/ko/ai-tools/github-copilot/template/.github/copilot-instructions.md +0 -202
  414. package/claude-code/aiwf/ko/ai-tools/windsurf/README.md +0 -355
  415. package/claude-code/aiwf/ko/ai-tools/windsurf/config.json +0 -29
  416. package/claude-code/aiwf/ko/ai-tools/windsurf/template/.windsurf/aiwf-rules.md +0 -260
  417. package/claude-code/aiwf/ko/ai-tools/windsurf/template/.windsurf/windsurf.config.js +0 -312
  418. package/claude-code/aiwf/ko/ai-tools/windsurf/template/windsurf.config.json +0 -63
  419. package/claude-code/aiwf/ko/commands/feature_commit_report.js +0 -370
  420. package/claude-code/aiwf/ko/commands/scan_git_history.js +0 -234
  421. package/claude-code/aiwf/ko/commands/sync_feature_commits.js +0 -154
  422. package/claude-code/aiwf/ko/commands/token-tracking.js +0 -443
  423. package/claude-code/aiwf/ko/feature-ledger/FL-001-authentication.json +0 -52
  424. package/claude-code/aiwf/ko/feature-ledger/feature-index.json +0 -20
  425. package/claude-code/aiwf/ko/hooks/install-hooks.sh +0 -100
  426. package/claude-code/aiwf/ko/hooks/post-commit +0 -84
  427. package/claude-code/aiwf/ko/personas/PERSONA_INDEX.md +0 -57
  428. package/claude-code/aiwf/ko/personas/analyst.json +0 -44
  429. package/claude-code/aiwf/ko/personas/architect/best_practices.md +0 -136
  430. package/claude-code/aiwf/ko/personas/architect/knowledge_base.md +0 -377
  431. package/claude-code/aiwf/ko/personas/architect.json +0 -44
  432. package/claude-code/aiwf/ko/personas/backend/best_practices.md +0 -766
  433. package/claude-code/aiwf/ko/personas/backend/knowledge_base.md +0 -1070
  434. package/claude-code/aiwf/ko/personas/data_analyst/best_practices.md +0 -594
  435. package/claude-code/aiwf/ko/personas/data_analyst/knowledge_base.md +0 -1057
  436. package/claude-code/aiwf/ko/personas/developer.json +0 -44
  437. package/claude-code/aiwf/ko/personas/developer.md +0 -37
  438. package/claude-code/aiwf/ko/personas/evaluation_criteria.json +0 -137
  439. package/claude-code/aiwf/ko/personas/frontend/best_practices.md +0 -445
  440. package/claude-code/aiwf/ko/personas/frontend/knowledge_base.md +0 -729
  441. package/claude-code/aiwf/ko/personas/persona-index.json +0 -31
  442. package/claude-code/aiwf/ko/personas/reviewer.json +0 -44
  443. package/claude-code/aiwf/ko/personas/security/best_practices.md +0 -307
  444. package/claude-code/aiwf/ko/personas/security/knowledge_base.md +0 -498
  445. package/claude-code/aiwf/ko/personas/tester.json +0 -44
  446. package/claude-code/aiwf/ko/scripts/cache-templates.js +0 -209
  447. package/claude-code/aiwf/ko/scripts/create-offline.js +0 -86
  448. package/claude-code/aiwf/ko/scripts/create-project.js +0 -151
  449. package/claude-code/aiwf/ko/scripts/feature-progress-calculator.cjs +0 -236
  450. package/claude-code/aiwf/ko/scripts/git-integration.cjs +0 -391
  451. package/claude-code/aiwf/ko/scripts/install-git-hooks.cjs +0 -226
  452. package/claude-code/aiwf/ko/scripts/test-commit-parsing.cjs +0 -125
  453. package/claude-code/aiwf/ko/scripts/update-feature-status.cjs +0 -198
  454. package/claude-code/aiwf/ko/tests/compression-test-suite.js +0 -1252
  455. package/claude-code/aiwf/ko/tests/test-git-integration.js +0 -164
  456. package/claude-code/aiwf/ko/tests/token-tracking.test.js +0 -537
  457. package/claude-code/aiwf/ko/utils/compression-metrics.js +0 -1031
  458. package/claude-code/aiwf/ko/utils/compression-strategies.js +0 -557
  459. package/claude-code/aiwf/ko/utils/content-normalizer.js +0 -455
  460. package/claude-code/aiwf/ko/utils/feature-updater.js +0 -271
  461. package/claude-code/aiwf/ko/utils/importance-classifier.js +0 -645
  462. package/claude-code/aiwf/ko/utils/information-filter.js +0 -710
  463. package/claude-code/aiwf/ko/utils/token-counter.js +0 -177
  464. package/claude-code/aiwf/ko/utils/token-monitor.js +0 -484
  465. package/claude-code/aiwf/ko/utils/token-reporter.js +0 -453
  466. package/claude-code/aiwf/ko/utils/token-storage.js +0 -433
  467. package/claude-code/aiwf/ko/utils/token-tracker.js +0 -283
  468. package/claude-code/docker/Dockerfile +0 -117
  469. package/jest.config.js +0 -23
  470. package/scripts/update-feature-status.js +0 -70
  471. package/tests/application.test.js +0 -260
  472. package/tests/basic.test.js +0 -62
  473. package/tests/commands.test.js +0 -127
  474. package/tests/installer.test.js +0 -129
  475. package/tests/integration/ai-persona-system.test.js +0 -396
  476. package/tests/integration/ai-persona.test.js +0 -390
  477. package/tests/integration/command-integration.test.js +0 -600
  478. package/tests/integration/context-compression.test.js +0 -361
  479. package/tests/integration/feature-ledger.test.js +0 -226
  480. package/tests/integration/git-integration.test.js +0 -307
  481. package/tests/integration/m02-milestone.test.js +0 -420
  482. package/tests/integration/persona-context-application.test.js +0 -508
  483. package/tests/integration/setup.js +0 -174
  484. package/tests/integration/test-persona-aware-compression.js +0 -93
  485. package/tests/integration/test-persona-system/.aiwf/metrics/metrics.json +0 -833
  486. package/tests/integration/test-persona-system/docs/README.md +0 -1
  487. package/tests/integration/test-persona-system/package.json +0 -1
  488. package/tests/integration/test-persona-system/src/auth.js +0 -1
  489. package/tests/integration/test-persona-system/src/index.js +0 -1
  490. package/tests/integration/test-persona-system/test/test.js +0 -1
  491. package/tests/language-utils.test.js +0 -287
  492. package/tests/s02-integration.test.js +0 -422
  493. package/tests/unit/ai-persona-manager.test.js +0 -514
  494. package/tests/unit/sprint-task.test.js +0 -172
  495. /package/{claude-code/aiwf/ko → src/lib/resources}/commands/compress-context.js +0 -0
  496. /package/{claude-code/aiwf/ko → src/lib/resources}/commands/evaluate.js +0 -0
  497. /package/{claude-code/aiwf/ko → src/lib/resources}/commands/feature-ledger.js +0 -0
  498. /package/{claude-code/aiwf/en → src/lib/resources}/commands/feature_commit_report.js +0 -0
  499. /package/{claude-code/aiwf/ko → src/lib/resources}/commands/persona-context-apply.js +0 -0
  500. /package/{claude-code/aiwf/en → src/lib/resources}/commands/scan_git_history.js +0 -0
  501. /package/{claude-code/aiwf/en → src/lib/resources}/commands/sync_feature_commits.js +0 -0
  502. /package/{claude-code/aiwf/en → src/lib/resources}/commands/token-tracking.js +0 -0
  503. /package/{claude-code/aiwf/ko → src/lib/resources}/config/commit-patterns.js +0 -0
  504. /package/{claude-code/aiwf/ko → src/lib/resources}/config/language.json +0 -0
  505. /package/{.aiwf/07_AI_PERSONAS → src/lib/resources/personas}/PERSONA_INDEX.md +0 -0
  506. /package/{.aiwf → src/lib/resources}/personas/analyst.json +0 -0
  507. /package/{.aiwf → src/lib/resources}/personas/architect/best_practices.md +0 -0
  508. /package/{.aiwf → src/lib/resources}/personas/architect/knowledge_base.md +0 -0
  509. /package/{.aiwf → src/lib/resources}/personas/architect.json +0 -0
  510. /package/{.aiwf → src/lib/resources}/personas/backend/best_practices.md +0 -0
  511. /package/{.aiwf → src/lib/resources}/personas/backend/knowledge_base.md +0 -0
  512. /package/{.aiwf → src/lib/resources}/personas/data_analyst/best_practices.md +0 -0
  513. /package/{.aiwf → src/lib/resources}/personas/data_analyst/knowledge_base.md +0 -0
  514. /package/{.aiwf → src/lib/resources}/personas/developer.json +0 -0
  515. /package/{.aiwf/10_PERSONAS → src/lib/resources/personas}/developer.md +0 -0
  516. /package/{.aiwf → src/lib/resources}/personas/evaluation_criteria.json +0 -0
  517. /package/{.aiwf → src/lib/resources}/personas/frontend/best_practices.md +0 -0
  518. /package/{.aiwf → src/lib/resources}/personas/frontend/knowledge_base.md +0 -0
  519. /package/{.aiwf → src/lib/resources}/personas/persona-index.json +0 -0
  520. /package/{.aiwf → src/lib/resources}/personas/reviewer.json +0 -0
  521. /package/{.aiwf → src/lib/resources}/personas/security/best_practices.md +0 -0
  522. /package/{.aiwf → src/lib/resources}/personas/security/knowledge_base.md +0 -0
  523. /package/{.aiwf → src/lib/resources}/personas/tester.json +0 -0
  524. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/README.md +0 -0
  525. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/config.json +0 -0
  526. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/.aiwf/config.json +0 -0
  527. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/.aiwf/feature-ledger.json +0 -0
  528. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/.aiwf/personas/backend-engineer.json +0 -0
  529. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/.aiwf/scripts/cli.js +0 -0
  530. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/.env.example +0 -0
  531. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/.eslintrc.json +0 -0
  532. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/README.md +0 -0
  533. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/jest.config.js +0 -0
  534. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/nodemon.json +0 -0
  535. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/package.json +0 -0
  536. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/src/app.ts +0 -0
  537. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/src/config/swagger.ts +0 -0
  538. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/src/controllers/aiwfController.ts +0 -0
  539. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/src/controllers/authController.ts +0 -0
  540. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/src/controllers/statusController.ts +0 -0
  541. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/src/index.ts +0 -0
  542. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/src/middleware/aiwfMiddleware.ts +0 -0
  543. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/src/middleware/authMiddleware.ts +0 -0
  544. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/src/middleware/errorHandler.ts +0 -0
  545. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/src/middleware/notFoundHandler.ts +0 -0
  546. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/src/middleware/requestLogger.ts +0 -0
  547. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/src/routes/aiwf.ts +0 -0
  548. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/src/routes/index.ts +0 -0
  549. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/src/routes/v1/index.ts +0 -0
  550. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/src/utils/logger.ts +0 -0
  551. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/tests/app.test.ts +0 -0
  552. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/api-server/template/tsconfig.json +0 -0
  553. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/npm-library/config.json +0 -0
  554. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/npm-library/template/LICENSE +0 -0
  555. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/npm-library/template/README.md +0 -0
  556. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/npm-library/template/package.json +0 -0
  557. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/config.json +0 -0
  558. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/.aiwf/config.json +0 -0
  559. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/.aiwf/feature-ledger.json +0 -0
  560. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/.aiwf/personas/fullstack-developer.json +0 -0
  561. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/.aiwf/scripts/cli.js +0 -0
  562. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/.eslintrc.cjs +0 -0
  563. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/README.md +0 -0
  564. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/index.html +0 -0
  565. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/package.json +0 -0
  566. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/postcss.config.js +0 -0
  567. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/public/vite.svg +0 -0
  568. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/src/App.tsx +0 -0
  569. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/src/components/Layout.tsx +0 -0
  570. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/src/components/aiwf/ContextStatus.tsx +0 -0
  571. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/src/components/aiwf/FeatureLedger.tsx +0 -0
  572. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/src/components/aiwf/TokenUsage.tsx +0 -0
  573. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/src/index.css +0 -0
  574. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/src/main.tsx +0 -0
  575. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/src/pages/AiwfDashboard.tsx +0 -0
  576. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/src/pages/HomePage.tsx +0 -0
  577. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/src/pages/NotFound.tsx +0 -0
  578. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/src/stores/aiwfStore.ts +0 -0
  579. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/src/types/global.d.ts +0 -0
  580. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/src/vite-env.d.ts +0 -0
  581. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/tailwind.config.js +0 -0
  582. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/tsconfig.json +0 -0
  583. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/tsconfig.node.json +0 -0
  584. /package/{claude-code/aiwf/ko → src/lib/resources}/templates/web-app/template/vite.config.ts +0 -0
  585. /package/{claude-code/aiwf/ko → src/lib/resources}/utils/background-monitor.js +0 -0
  586. /package/{claude-code/aiwf/en → src/lib/resources}/utils/compression-metrics.js +0 -0
  587. /package/{claude-code/aiwf/en → src/lib/resources}/utils/compression-strategies.js +0 -0
  588. /package/{claude-code/aiwf/en → src/lib/resources}/utils/content-normalizer.js +0 -0
  589. /package/{claude-code/aiwf/ko → src/lib/resources}/utils/context-compressor.js +0 -0
  590. /package/{claude-code/aiwf/ko → src/lib/resources}/utils/context-rule-parser.js +0 -0
  591. /package/{claude-code/aiwf/ko → src/lib/resources}/utils/context-token-monitor.js +0 -0
  592. /package/{claude-code/aiwf/ko → src/lib/resources}/utils/context-update-manager.js +0 -0
  593. /package/{claude-code/aiwf/en → src/lib/resources}/utils/feature-updater.js +0 -0
  594. /package/{claude-code/aiwf/ko → src/lib/resources}/utils/git-utils.js +0 -0
  595. /package/{claude-code/aiwf/en → src/lib/resources}/utils/importance-classifier.js +0 -0
  596. /package/{claude-code/aiwf/en → src/lib/resources}/utils/information-filter.js +0 -0
  597. /package/{claude-code/aiwf/ko → src/lib/resources}/utils/persona-aware-compressor.js +0 -0
  598. /package/{claude-code/aiwf/ko → src/lib/resources}/utils/prompt-injector.js +0 -0
  599. /package/{claude-code/aiwf/ko → src/lib/resources}/utils/simplified-evaluator.js +0 -0
  600. /package/{claude-code/aiwf/ko → src/lib/resources}/utils/text-summarizer.js +0 -0
  601. /package/{claude-code/aiwf/en → src/lib/resources}/utils/token-counter.js +0 -0
  602. /package/{claude-code/aiwf/en → src/lib/resources}/utils/token-monitor.js +0 -0
  603. /package/{claude-code/aiwf/en → src/lib/resources}/utils/token-reporter.js +0 -0
  604. /package/{claude-code/aiwf/en → src/lib/resources}/utils/token-storage.js +0 -0
  605. /package/{claude-code/aiwf/en → src/lib/resources}/utils/token-tracker.js +0 -0
@@ -0,0 +1,1164 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * AIWF State Management Command
5
+ * 중앙 상태 인덱스를 통한 프로젝트 상태 관리
6
+ */
7
+
8
+ import fs from 'fs/promises';
9
+ import path from 'path';
10
+ import chalk from 'chalk';
11
+ import ora from 'ora';
12
+ import { glob } from 'glob';
13
+
14
+ export default class StateCommand {
15
+ constructor() {
16
+ this.stateFile = 'task-state-index.json';
17
+ this.workflowRulesFile = 'workflow-rules.json';
18
+ this.projectRoot = null;
19
+ this.aiwfPath = null;
20
+ this.workflowRules = null;
21
+ }
22
+
23
+ async execute(args) {
24
+ const subcommand = args[0] || 'show';
25
+
26
+ try {
27
+ // 프로젝트 루트 찾기
28
+ this.projectRoot = await this.findProjectRoot();
29
+ this.aiwfPath = path.join(this.projectRoot, '.aiwf');
30
+
31
+ switch (subcommand) {
32
+ case 'update':
33
+ await this.updateStateIndex();
34
+ break;
35
+ case 'show':
36
+ await this.showState();
37
+ break;
38
+ case 'focus':
39
+ await this.focusTask(args[1]);
40
+ break;
41
+ case 'complete':
42
+ await this.completeTask(args[1]);
43
+ break;
44
+ case 'next':
45
+ await this.suggestNext();
46
+ break;
47
+ case 'init':
48
+ await this.initStateIndex();
49
+ break;
50
+ case 'validate':
51
+ await this.validateCommand();
52
+ break;
53
+ default:
54
+ console.error(chalk.red(`Unknown subcommand: ${subcommand}`));
55
+ this.showHelp();
56
+ }
57
+ } catch (error) {
58
+ console.error(chalk.red(`Error: ${error.message}`));
59
+ process.exit(1);
60
+ }
61
+ }
62
+
63
+ async findProjectRoot(startDir = process.cwd()) {
64
+ let currentDir = startDir;
65
+
66
+ while (currentDir !== path.parse(currentDir).root) {
67
+ try {
68
+ const aiwfPath = path.join(currentDir, '.aiwf');
69
+ await fs.access(aiwfPath);
70
+ return currentDir;
71
+ } catch {
72
+ currentDir = path.dirname(currentDir);
73
+ }
74
+ }
75
+
76
+ throw new Error('.aiwf directory not found. Are you in an AIWF project?');
77
+ }
78
+
79
+ async initStateIndex() {
80
+ const spinner = ora('Initializing state index...').start();
81
+
82
+ try {
83
+ const indexPath = path.join(this.aiwfPath, this.stateFile);
84
+ const exists = await this.fileExists(indexPath);
85
+
86
+ if (exists) {
87
+ spinner.warn('State index already exists');
88
+ return;
89
+ }
90
+
91
+ const initialState = {
92
+ version: '1.0.0',
93
+ last_updated: new Date().toISOString(),
94
+ last_updated_by: 'aiwf-state-init',
95
+ project_info: {
96
+ name: path.basename(this.projectRoot),
97
+ current_milestone: null,
98
+ current_sprint: null,
99
+ phase: 'planning'
100
+ },
101
+ current_focus: {
102
+ primary_task: null,
103
+ secondary_tasks: [],
104
+ blocked_tasks: [],
105
+ last_worked_on: null,
106
+ session_notes: ''
107
+ },
108
+ tasks: {},
109
+ sprint_summary: {},
110
+ next_actions: [],
111
+ ai_context: {
112
+ last_session: new Date().toISOString(),
113
+ session_count: 0,
114
+ learned_patterns: {},
115
+ working_hours: {}
116
+ },
117
+ metrics: {
118
+ total_tasks: 0,
119
+ completed_tasks: 0,
120
+ in_progress_tasks: 0,
121
+ pending_tasks: 0,
122
+ blocked_tasks: 0,
123
+ overall_progress: 0
124
+ }
125
+ };
126
+
127
+ await fs.writeFile(indexPath, JSON.stringify(initialState, null, 2));
128
+ spinner.succeed('State index initialized successfully');
129
+ } catch (error) {
130
+ spinner.fail(`Failed to initialize state index: ${error.message}`);
131
+ throw error;
132
+ }
133
+ }
134
+
135
+ async updateStateIndex() {
136
+ const spinner = ora('Updating state index...').start();
137
+
138
+ try {
139
+ const indexPath = path.join(this.aiwfPath, this.stateFile);
140
+ let stateIndex = await this.loadStateIndex();
141
+
142
+ if (!stateIndex) {
143
+ spinner.info('State index not found. Creating new one...');
144
+ await this.initStateIndex();
145
+ stateIndex = await this.loadStateIndex();
146
+ }
147
+
148
+ // 스프린트 폴더들 스캔
149
+ const sprintDirs = await glob('03_SPRINTS/S*/', { cwd: this.aiwfPath });
150
+ let totalTasks = 0;
151
+ let completedTasks = 0;
152
+ let inProgressTasks = 0;
153
+ let pendingTasks = 0;
154
+ let blockedTasks = 0;
155
+
156
+ // 각 스프린트 폴더에서 태스크 파일들 스캔
157
+ for (const sprintDir of sprintDirs) {
158
+ const sprintPath = path.join(this.aiwfPath, sprintDir);
159
+ const sprintId = path.basename(sprintDir).split('_')[0];
160
+
161
+ // 스프린트 메타 파일 읽기
162
+ const metaFiles = await glob('*_sprint_meta.md', { cwd: sprintPath });
163
+ let sprintName = sprintDir;
164
+ let sprintStatus = 'active';
165
+
166
+ if (metaFiles.length > 0) {
167
+ const metaContent = await fs.readFile(path.join(sprintPath, metaFiles[0]), 'utf-8');
168
+ const nameMatch = metaContent.match(/^#\s+(.+)$/m);
169
+ if (nameMatch) sprintName = nameMatch[1];
170
+
171
+ // 스프린트 상태 확인
172
+ if (metaContent.includes('상태: 완료') || metaContent.includes('Status: Completed')) {
173
+ sprintStatus = 'completed';
174
+ } else if (metaContent.includes('상태: 계획') || metaContent.includes('Status: Planning')) {
175
+ sprintStatus = 'planning';
176
+ }
177
+ }
178
+
179
+ // 태스크 파일들 스캔
180
+ const taskFiles = await glob('T*.md', { cwd: sprintPath });
181
+ const sprintTasks = taskFiles.filter(f => !f.includes('_template'));
182
+
183
+ let sprintCompleted = 0;
184
+ let sprintInProgress = 0;
185
+ let sprintPending = 0;
186
+
187
+ for (const taskFile of sprintTasks) {
188
+ totalTasks++;
189
+ const taskPath = path.join(sprintPath, taskFile);
190
+ const taskContent = await fs.readFile(taskPath, 'utf-8');
191
+
192
+ // 태스크 ID 추출
193
+ const taskId = taskFile.replace('.md', '').split('_').slice(0, 3).join('_');
194
+
195
+ // 태스크 정보 파싱
196
+ const titleMatch = taskContent.match(/^#\s+T\d+:\s+(.+)$/m);
197
+ const statusMatch = taskContent.match(/\*\*상태\*\*:\s*(\w+)|\*\*Status\*\*:\s*(\w+)/i);
198
+ const milestoneMatch = taskContent.match(/\*\*마일스톤\*\*:\s*(M\d+)|\*\*Milestone\*\*:\s*(M\d+)/i);
199
+
200
+ const title = titleMatch ? titleMatch[1] : taskFile;
201
+ const status = statusMatch ? (statusMatch[1] || statusMatch[2]).toLowerCase() : 'pending';
202
+ const milestone = milestoneMatch ? (milestoneMatch[1] || milestoneMatch[2]) : 'M01';
203
+
204
+ // 태스크 상태 카운트
205
+ switch (status) {
206
+ case 'completed':
207
+ case 'done':
208
+ completedTasks++;
209
+ sprintCompleted++;
210
+ break;
211
+ case 'in_progress':
212
+ case 'in-progress':
213
+ case 'active':
214
+ inProgressTasks++;
215
+ sprintInProgress++;
216
+ if (!stateIndex.current_focus.primary_task) {
217
+ stateIndex.current_focus.primary_task = taskId;
218
+ }
219
+ break;
220
+ case 'blocked':
221
+ blockedTasks++;
222
+ break;
223
+ default:
224
+ pendingTasks++;
225
+ sprintPending++;
226
+ }
227
+
228
+ // 태스크 정보 업데이트
229
+ stateIndex.tasks[taskId] = {
230
+ id: taskId,
231
+ title: title,
232
+ status: status,
233
+ sprint: sprintId,
234
+ milestone: milestone,
235
+ location: path.relative(this.projectRoot, taskPath),
236
+ last_updated: new Date().toISOString()
237
+ };
238
+
239
+ // OUTPUT LOG 확인
240
+ if (taskContent.includes('## OUTPUT LOG')) {
241
+ const outputSection = taskContent.split('## OUTPUT LOG')[1];
242
+ if (outputSection.includes('✅') || outputSection.includes('완료')) {
243
+ stateIndex.tasks[taskId].status = 'completed';
244
+ }
245
+ }
246
+ }
247
+
248
+ // 스프린트 요약 업데이트
249
+ stateIndex.sprint_summary[sprintId] = {
250
+ name: sprintName,
251
+ status: sprintStatus,
252
+ total_tasks: sprintTasks.length,
253
+ completed_tasks: sprintCompleted,
254
+ in_progress_tasks: sprintInProgress,
255
+ pending_tasks: sprintPending,
256
+ completion_rate: sprintTasks.length > 0 ? Math.round((sprintCompleted / sprintTasks.length) * 100) : 0
257
+ };
258
+ }
259
+
260
+ // 현재 마일스톤/스프린트 찾기
261
+ const manifestPath = path.join(this.aiwfPath, '00_PROJECT_MANIFEST.md');
262
+ if (await this.fileExists(manifestPath)) {
263
+ const manifestContent = await fs.readFile(manifestPath, 'utf-8');
264
+ const currentMilestoneMatch = manifestContent.match(/\*\*현재 마일스톤\*\*:\s*(M\d+)|\*\*Current Milestone\*\*:\s*(M\d+)/);
265
+ const currentSprintMatch = manifestContent.match(/\*\*활성 스프린트\*\*:\s*(S\d+)|\*\*Active Sprint\*\*:\s*(S\d+)/);
266
+
267
+ if (currentMilestoneMatch) {
268
+ stateIndex.project_info.current_milestone = currentMilestoneMatch[1] || currentMilestoneMatch[2];
269
+ }
270
+ if (currentSprintMatch) {
271
+ stateIndex.project_info.current_sprint = currentSprintMatch[1] || currentSprintMatch[2];
272
+ }
273
+ }
274
+
275
+ // 메트릭스 업데이트
276
+ stateIndex.metrics = {
277
+ total_tasks: totalTasks,
278
+ completed_tasks: completedTasks,
279
+ in_progress_tasks: inProgressTasks,
280
+ pending_tasks: pendingTasks,
281
+ blocked_tasks: blockedTasks,
282
+ overall_progress: totalTasks > 0 ? Math.round((completedTasks / totalTasks) * 100) : 0
283
+ };
284
+
285
+ // 워크플로우 규칙 로드
286
+ if (!this.workflowRules) {
287
+ this.workflowRules = await this.loadWorkflowRules();
288
+ }
289
+
290
+ // 의존성 분석
291
+ const dependencies = await this.analyzeDependencies(stateIndex);
292
+
293
+ // 다음 액션 제안을 우선순위 기반으로 생성
294
+ stateIndex.next_actions = [];
295
+ const taskPriorities = [];
296
+
297
+ // 모든 태스크의 우선순위 계산
298
+ Object.values(stateIndex.tasks).forEach(task => {
299
+ // 의존성 정보 추가
300
+ task.dependencies = dependencies[task.id]?.dependsOn || [];
301
+ task.blockedBy = dependencies[task.id]?.blockedBy || [];
302
+ task.blocks = dependencies[task.id]?.blocks || [];
303
+
304
+ // 우선순위 계산
305
+ const priority = this.calculateTaskPriority(task, stateIndex);
306
+ taskPriorities.push({ task, priority, dependencies: dependencies[task.id] });
307
+ });
308
+
309
+ // 우선순위로 정렬
310
+ taskPriorities.sort((a, b) => b.priority - a.priority);
311
+
312
+ // 진행 중인 태스크 우선
313
+ taskPriorities.forEach(({ task, priority }) => {
314
+ if (task.status === 'in_progress') {
315
+ stateIndex.next_actions.push({
316
+ priority: 'high',
317
+ score: priority,
318
+ action: `Continue working on ${task.title}`,
319
+ task_id: task.id,
320
+ reason: 'Already in progress',
321
+ estimated_time: '2-4 hours',
322
+ blockedBy: task.blockedBy
323
+ });
324
+ }
325
+ });
326
+
327
+ // 차단되지 않은 대기 중인 태스크 추가
328
+ taskPriorities.forEach(({ task, priority }) => {
329
+ if (task.status === 'pending' &&
330
+ task.sprint === stateIndex.project_info.current_sprint &&
331
+ task.blockedBy.length === 0) {
332
+ stateIndex.next_actions.push({
333
+ priority: priority >= 70 ? 'high' : priority >= 40 ? 'medium' : 'low',
334
+ score: priority,
335
+ action: `Start ${task.title}`,
336
+ task_id: task.id,
337
+ reason: task.blocks.length > 0 ? `Blocks ${task.blocks.length} other tasks` : 'Ready to start',
338
+ estimated_time: '4-8 hours',
339
+ dependencies: task.dependencies
340
+ });
341
+ }
342
+ });
343
+
344
+ // 차단된 태스크 정보
345
+ taskPriorities.forEach(({ task, priority }) => {
346
+ if (task.status === 'pending' && task.blockedBy.length > 0) {
347
+ stateIndex.next_actions.push({
348
+ priority: 'blocked',
349
+ score: priority,
350
+ action: `Blocked: ${task.title}`,
351
+ task_id: task.id,
352
+ reason: `Waiting for: ${task.blockedBy.join(', ')}`,
353
+ blockedBy: task.blockedBy
354
+ });
355
+ }
356
+ });
357
+
358
+ // 워크플로우 검증
359
+ const validation = await this.validateWorkflow(stateIndex);
360
+ stateIndex.workflow_validation = validation;
361
+
362
+ // 타임스탬프 업데이트
363
+ stateIndex.last_updated = new Date().toISOString();
364
+ stateIndex.last_updated_by = 'aiwf-state-update';
365
+
366
+ // 저장
367
+ await fs.writeFile(indexPath, JSON.stringify(stateIndex, null, 2));
368
+
369
+ spinner.succeed(`State index updated: ${totalTasks} tasks tracked`);
370
+ console.log(chalk.green(` ✅ Completed: ${completedTasks}`));
371
+ console.log(chalk.yellow(` 🔄 In Progress: ${inProgressTasks}`));
372
+ console.log(chalk.blue(` ⏳ Pending: ${pendingTasks}`));
373
+ console.log(chalk.red(` ❌ Blocked: ${blockedTasks}`));
374
+ console.log(chalk.cyan(` 📊 Overall Progress: ${stateIndex.metrics.overall_progress}%`));
375
+
376
+ } catch (error) {
377
+ spinner.fail(`Failed to update state index: ${error.message}`);
378
+ throw error;
379
+ }
380
+ }
381
+
382
+ async showState() {
383
+ try {
384
+ const stateIndex = await this.loadStateIndex();
385
+ if (!stateIndex) {
386
+ console.log(chalk.yellow('No state index found. Run "aiwf state init" or "aiwf state update" first.'));
387
+ return;
388
+ }
389
+
390
+ console.log(chalk.bold('\n🏗️ AIWF Project State\n'));
391
+
392
+ // 프로젝트 정보
393
+ console.log(chalk.cyan('📋 Project Information:'));
394
+ console.log(` Name: ${stateIndex.project_info.name}`);
395
+ console.log(` Current Milestone: ${stateIndex.project_info.current_milestone || 'None'}`);
396
+ console.log(` Active Sprint: ${stateIndex.project_info.current_sprint || 'None'}`);
397
+ console.log(` Phase: ${stateIndex.project_info.phase}`);
398
+ console.log(` Last Updated: ${new Date(stateIndex.last_updated).toLocaleString()}`);
399
+
400
+ // 현재 포커스
401
+ console.log(chalk.yellow('\n🎯 Current Focus:'));
402
+ if (stateIndex.current_focus.primary_task) {
403
+ const task = stateIndex.tasks[stateIndex.current_focus.primary_task];
404
+ if (task) {
405
+ console.log(` Primary Task: ${task.id} - ${task.title}`);
406
+ console.log(` Status: ${task.status}`);
407
+ }
408
+ } else {
409
+ console.log(' No task currently in focus');
410
+ }
411
+
412
+ // 메트릭스
413
+ console.log(chalk.green('\n📊 Metrics:'));
414
+ const m = stateIndex.metrics;
415
+ console.log(` Total Tasks: ${m.total_tasks}`);
416
+ console.log(` Completed: ${m.completed_tasks} (${Math.round((m.completed_tasks/m.total_tasks)*100) || 0}%)`);
417
+ console.log(` In Progress: ${m.in_progress_tasks}`);
418
+ console.log(` Pending: ${m.pending_tasks}`);
419
+ console.log(` Blocked: ${m.blocked_tasks}`);
420
+
421
+ // 진행률 바
422
+ const progressBar = this.createProgressBar(m.overall_progress);
423
+ console.log(`\n Overall Progress: ${progressBar} ${m.overall_progress}%`);
424
+
425
+ // 다음 액션
426
+ if (stateIndex.next_actions.length > 0) {
427
+ console.log(chalk.magenta('\n🚀 Next Actions:'));
428
+ stateIndex.next_actions.slice(0, 3).forEach((action, i) => {
429
+ const priority = action.priority === 'high' ? '🔴' : action.priority === 'medium' ? '🟡' : '🟢';
430
+ console.log(` ${i + 1}. ${priority} ${action.action} (${action.estimated_time})`);
431
+ });
432
+ }
433
+
434
+ // 스프린트 요약
435
+ const activeSprints = Object.entries(stateIndex.sprint_summary)
436
+ .filter(([_, sprint]) => sprint.status === 'active');
437
+
438
+ if (activeSprints.length > 0) {
439
+ console.log(chalk.blue('\n📅 Active Sprints:'));
440
+ activeSprints.forEach(([id, sprint]) => {
441
+ const sprintProgress = this.createProgressBar(sprint.completion_rate);
442
+ console.log(` ${id}: ${sprint.name}`);
443
+ console.log(` Progress: ${sprintProgress} ${sprint.completion_rate}%`);
444
+ console.log(` Tasks: ${sprint.completed_tasks}/${sprint.total_tasks} completed`);
445
+ });
446
+ }
447
+
448
+ console.log('');
449
+ } catch (error) {
450
+ console.error(chalk.red(`Failed to show state: ${error.message}`));
451
+ throw error;
452
+ }
453
+ }
454
+
455
+ async focusTask(taskId) {
456
+ if (!taskId) {
457
+ console.error(chalk.red('Please provide a task ID'));
458
+ return;
459
+ }
460
+
461
+ const spinner = ora(`Setting focus to ${taskId}...`).start();
462
+
463
+ try {
464
+ const stateIndex = await this.loadStateIndex();
465
+ if (!stateIndex) {
466
+ spinner.fail('No state index found. Run "aiwf state update" first.');
467
+ return;
468
+ }
469
+
470
+ if (!stateIndex.tasks[taskId]) {
471
+ spinner.fail(`Task ${taskId} not found in state index.`);
472
+ return;
473
+ }
474
+
475
+ const task = stateIndex.tasks[taskId];
476
+ stateIndex.current_focus.primary_task = taskId;
477
+ stateIndex.current_focus.last_worked_on = taskId;
478
+ stateIndex.current_focus.session_notes = `Focused on ${task.title}`;
479
+
480
+ // AI 컨텍스트 업데이트
481
+ stateIndex.ai_context.last_session = new Date().toISOString();
482
+ stateIndex.ai_context.session_count++;
483
+
484
+ await this.saveStateIndex(stateIndex);
485
+
486
+ spinner.succeed(`Focus set to ${taskId}: ${task.title}`);
487
+ console.log(chalk.cyan(`\n📍 Task Location: ${task.location}`));
488
+ console.log(chalk.yellow(`📊 Current Status: ${task.status}`));
489
+
490
+ // 관련 태스크 표시
491
+ const relatedTasks = Object.values(stateIndex.tasks)
492
+ .filter(t => t.sprint === task.sprint && t.id !== taskId && t.status !== 'completed');
493
+
494
+ if (relatedTasks.length > 0) {
495
+ console.log(chalk.dim('\n📎 Related tasks in same sprint:'));
496
+ relatedTasks.forEach(t => {
497
+ console.log(chalk.dim(` - ${t.id}: ${t.title} (${t.status})`));
498
+ });
499
+ }
500
+ } catch (error) {
501
+ spinner.fail(`Failed to set focus: ${error.message}`);
502
+ throw error;
503
+ }
504
+ }
505
+
506
+ async completeTask(taskId) {
507
+ if (!taskId) {
508
+ console.error(chalk.red('Please provide a task ID'));
509
+ return;
510
+ }
511
+
512
+ const spinner = ora(`Marking ${taskId} as completed...`).start();
513
+
514
+ try {
515
+ const stateIndex = await this.loadStateIndex();
516
+ if (!stateIndex) {
517
+ spinner.fail('No state index found. Run "aiwf state update" first.');
518
+ return;
519
+ }
520
+
521
+ if (!stateIndex.tasks[taskId]) {
522
+ spinner.fail(`Task ${taskId} not found in state index.`);
523
+ return;
524
+ }
525
+
526
+ const task = stateIndex.tasks[taskId];
527
+ const previousStatus = task.status;
528
+
529
+ // 태스크 상태 업데이트
530
+ task.status = 'completed';
531
+ task.completed = new Date().toISOString();
532
+
533
+ // 메트릭스 업데이트
534
+ if (previousStatus !== 'completed') {
535
+ stateIndex.metrics.completed_tasks++;
536
+ if (previousStatus === 'in_progress') {
537
+ stateIndex.metrics.in_progress_tasks--;
538
+ } else if (previousStatus === 'pending') {
539
+ stateIndex.metrics.pending_tasks--;
540
+ }
541
+
542
+ // 전체 진행률 재계산
543
+ stateIndex.metrics.overall_progress = Math.round(
544
+ (stateIndex.metrics.completed_tasks / stateIndex.metrics.total_tasks) * 100
545
+ );
546
+ }
547
+
548
+ // 현재 포커스가 완료된 태스크였다면 비우기
549
+ if (stateIndex.current_focus.primary_task === taskId) {
550
+ stateIndex.current_focus.primary_task = null;
551
+ stateIndex.current_focus.session_notes = `Completed ${task.title}`;
552
+ }
553
+
554
+ // 스프린트 요약 업데이트
555
+ const sprint = stateIndex.sprint_summary[task.sprint];
556
+ if (sprint && previousStatus !== 'completed') {
557
+ sprint.completed_tasks++;
558
+ sprint.completion_rate = Math.round(
559
+ (sprint.completed_tasks / sprint.total_tasks) * 100
560
+ );
561
+
562
+ if (previousStatus === 'in_progress') {
563
+ sprint.in_progress_tasks--;
564
+ } else if (previousStatus === 'pending') {
565
+ sprint.pending_tasks--;
566
+ }
567
+ }
568
+
569
+ await this.saveStateIndex(stateIndex);
570
+
571
+ spinner.succeed(`Task ${taskId} marked as completed!`);
572
+ console.log(chalk.green(`\n✅ ${task.title}`));
573
+ console.log(chalk.cyan(`📊 Sprint ${task.sprint} progress: ${sprint.completion_rate}%`));
574
+ console.log(chalk.cyan(`📈 Overall progress: ${stateIndex.metrics.overall_progress}%`));
575
+
576
+ // 다음 추천 태스크
577
+ await this.suggestNext();
578
+
579
+ } catch (error) {
580
+ spinner.fail(`Failed to complete task: ${error.message}`);
581
+ throw error;
582
+ }
583
+ }
584
+
585
+ async suggestNext() {
586
+ try {
587
+ const stateIndex = await this.loadStateIndex();
588
+ if (!stateIndex) {
589
+ console.log(chalk.yellow('No state index found. Run "aiwf state update" first.'));
590
+ return;
591
+ }
592
+
593
+ if (!this.workflowRules) {
594
+ this.workflowRules = await this.loadWorkflowRules();
595
+ }
596
+
597
+ console.log(chalk.bold('\n🎯 Workflow-Based Next Actions:\n'));
598
+
599
+ // 워크플로우 검증 결과 표시
600
+ if (stateIndex.workflow_validation) {
601
+ const { errors, warnings, suggestions } = stateIndex.workflow_validation;
602
+
603
+ if (errors.length > 0) {
604
+ console.log(chalk.red('❌ Workflow Errors:'));
605
+ errors.forEach(error => {
606
+ console.log(` - ${error.message}`);
607
+ });
608
+ console.log('');
609
+ }
610
+
611
+ if (suggestions.length > 0) {
612
+ console.log(chalk.yellow('💡 Workflow Suggestions:'));
613
+ suggestions.forEach(suggestion => {
614
+ console.log(` - ${suggestion.message}`);
615
+ });
616
+ console.log('');
617
+ }
618
+ }
619
+
620
+ // 우선순위 기반 액션 표시
621
+ const actions = stateIndex.next_actions || [];
622
+ const inProgress = actions.filter(a => a.task_id && stateIndex.tasks[a.task_id]?.status === 'in_progress');
623
+ const ready = actions.filter(a => a.priority !== 'blocked' && !inProgress.find(ip => ip.task_id === a.task_id));
624
+ const blocked = actions.filter(a => a.priority === 'blocked');
625
+
626
+ if (inProgress.length > 0) {
627
+ console.log(chalk.yellow('🔄 Continue In-Progress Tasks:'));
628
+ inProgress.forEach(action => {
629
+ const task = stateIndex.tasks[action.task_id];
630
+ console.log(` ${chalk.yellow('→')} ${task.id}: ${task.title}`);
631
+ console.log(chalk.dim(` Priority Score: ${action.score}/100`));
632
+ console.log(chalk.dim(` Location: ${task.location}`));
633
+ if (task.blocks?.length > 0) {
634
+ console.log(chalk.cyan(` 🔗 Blocks: ${task.blocks.join(', ')}`));
635
+ }
636
+ });
637
+ }
638
+
639
+ if (ready.length > 0) {
640
+ console.log(chalk.blue('\n📋 Ready to Start (Priority Order):'));
641
+ ready.slice(0, 5).forEach((action, i) => {
642
+ const task = stateIndex.tasks[action.task_id];
643
+ const priorityIcon = action.priority === 'high' ? '🔴' : action.priority === 'medium' ? '🟡' : '🟢';
644
+ console.log(` ${i + 1}. ${priorityIcon} ${task.id}: ${task.title}`);
645
+ console.log(chalk.dim(` Priority Score: ${action.score}/100 - ${action.reason}`));
646
+ console.log(chalk.dim(` Location: ${task.location}`));
647
+ if (task.blocks?.length > 0) {
648
+ console.log(chalk.cyan(` 🔗 Unblocks: ${task.blocks.join(', ')}`));
649
+ }
650
+ });
651
+ }
652
+
653
+ if (blocked.length > 0) {
654
+ console.log(chalk.red('\n⛔ Blocked Tasks:'));
655
+ blocked.slice(0, 3).forEach(action => {
656
+ const task = stateIndex.tasks[action.task_id];
657
+ console.log(` ❌ ${task.id}: ${task.title}`);
658
+ console.log(chalk.dim(` ${action.reason}`));
659
+ console.log(chalk.dim(` Priority Score: ${action.score}/100 (when unblocked)`));
660
+ });
661
+ }
662
+
663
+ // 병렬 작업 기회 식별
664
+ if (this.workflowRules.ai_behavior.suggest_parallelization && ready.length >= 2) {
665
+ const parallelizable = ready.filter(a => {
666
+ const task = stateIndex.tasks[a.task_id];
667
+ // 서로 의존하지 않는 태스크 찾기
668
+ return !ready.some(other =>
669
+ other.task_id !== a.task_id &&
670
+ (task.dependencies.includes(other.task_id) ||
671
+ stateIndex.tasks[other.task_id].dependencies.includes(task.id))
672
+ );
673
+ });
674
+
675
+ if (parallelizable.length >= 2) {
676
+ console.log(chalk.magenta('\n⚡ Parallel Work Opportunity:'));
677
+ console.log(' These tasks can be worked on simultaneously:');
678
+ parallelizable.slice(0, 3).forEach(action => {
679
+ const task = stateIndex.tasks[action.task_id];
680
+ console.log(` - ${task.id}: ${task.title}`);
681
+ });
682
+ }
683
+ }
684
+
685
+ // 스프린트 전환 조건 확인
686
+ const currentSprint = stateIndex.project_info.current_sprint;
687
+ if (currentSprint && stateIndex.sprint_summary[currentSprint]) {
688
+ const sprint = stateIndex.sprint_summary[currentSprint];
689
+
690
+ if (sprint.completion_rate === 100) {
691
+ console.log(chalk.green(`\n🎉 Sprint ${currentSprint} Complete!`));
692
+ console.log(' Next actions:');
693
+ console.log(' 1. Run sprint review: aiwf sprint review');
694
+ console.log(' 2. Transition to next sprint: aiwf transition sprint');
695
+ console.log(' 3. Update project documentation');
696
+ } else if (sprint.completion_rate >= 80) {
697
+ console.log(chalk.yellow(`\n📊 Sprint ${currentSprint} is ${sprint.completion_rate}% complete`));
698
+ console.log(' Consider:');
699
+ console.log(' - Preparing next sprint tasks');
700
+ console.log(' - Reviewing remaining tasks');
701
+ console.log(' - Planning sprint transition');
702
+ }
703
+ }
704
+
705
+ console.log(chalk.dim('\n💡 Commands:'));
706
+ console.log(chalk.dim(' Start task: aiwf state focus <task-id>'));
707
+ console.log(chalk.dim(' Update state: aiwf state update'));
708
+ console.log(chalk.dim(' Validate workflow: aiwf validate workflow'));
709
+
710
+ } catch (error) {
711
+ console.error(chalk.red(`Failed to suggest next actions: ${error.message}`));
712
+ throw error;
713
+ }
714
+ }
715
+
716
+ async loadStateIndex() {
717
+ try {
718
+ const indexPath = path.join(this.aiwfPath, this.stateFile);
719
+ const exists = await this.fileExists(indexPath);
720
+
721
+ if (!exists) {
722
+ return null;
723
+ }
724
+
725
+ const content = await fs.readFile(indexPath, 'utf-8');
726
+ return JSON.parse(content);
727
+ } catch (error) {
728
+ throw new Error(`Failed to load state index: ${error.message}`);
729
+ }
730
+ }
731
+
732
+ async loadWorkflowRules() {
733
+ try {
734
+ const rulesPath = path.join(this.aiwfPath, this.workflowRulesFile);
735
+ const exists = await this.fileExists(rulesPath);
736
+
737
+ if (!exists) {
738
+ // 기본 워크플로우 규칙 생성
739
+ const defaultRules = {
740
+ version: '1.0.0',
741
+ hierarchy: {
742
+ milestone: {
743
+ contains: 'sprints',
744
+ completion_rule: 'all_sprints_completed',
745
+ transition_rule: 'manual_review_required'
746
+ },
747
+ sprint: {
748
+ contains: 'tasks',
749
+ completion_rule: 'all_tasks_completed',
750
+ transition_rule: 'auto_when_complete',
751
+ preparation_rule: '80_percent_trigger'
752
+ },
753
+ task: {
754
+ completion_rule: 'acceptance_criteria_met',
755
+ transition_rule: 'immediate'
756
+ }
757
+ },
758
+ priority_matrix: {
759
+ factors: {
760
+ urgency: { weight: 0.4, range: [1, 5] },
761
+ importance: { weight: 0.3, range: [1, 5] },
762
+ dependencies_blocking: { weight: 0.2, range: [0, 10] },
763
+ effort: { weight: 0.1, range: [1, 10] }
764
+ },
765
+ calculation: 'weighted_sum'
766
+ },
767
+ dependency_rules: {
768
+ strict_mode: true,
769
+ allow_circular: false,
770
+ max_chain_length: 10
771
+ },
772
+ transition_rules: {
773
+ task_to_task: {
774
+ conditions: ['current_complete', 'next_unblocked'],
775
+ auto_transition: true
776
+ },
777
+ sprint_to_sprint: {
778
+ conditions: ['current_80_percent', 'next_planned'],
779
+ auto_transition: false,
780
+ requires_approval: true
781
+ },
782
+ milestone_to_milestone: {
783
+ conditions: ['current_complete', 'review_passed'],
784
+ auto_transition: false,
785
+ requires_approval: true
786
+ }
787
+ },
788
+ ai_behavior: {
789
+ decision_mode: 'conservative',
790
+ auto_prioritize: true,
791
+ suggest_parallelization: true,
792
+ risk_tolerance: 'low'
793
+ }
794
+ };
795
+
796
+ await fs.writeFile(rulesPath, JSON.stringify(defaultRules, null, 2));
797
+ return defaultRules;
798
+ }
799
+
800
+ const content = await fs.readFile(rulesPath, 'utf-8');
801
+ return JSON.parse(content);
802
+ } catch (error) {
803
+ throw new Error(`Failed to load workflow rules: ${error.message}`);
804
+ }
805
+ }
806
+
807
+ async saveStateIndex(stateIndex) {
808
+ try {
809
+ const indexPath = path.join(this.aiwfPath, this.stateFile);
810
+ stateIndex.last_updated = new Date().toISOString();
811
+ await fs.writeFile(indexPath, JSON.stringify(stateIndex, null, 2));
812
+ } catch (error) {
813
+ throw new Error(`Failed to save state index: ${error.message}`);
814
+ }
815
+ }
816
+
817
+ async fileExists(filePath) {
818
+ try {
819
+ await fs.access(filePath);
820
+ return true;
821
+ } catch {
822
+ return false;
823
+ }
824
+ }
825
+
826
+ createProgressBar(percentage) {
827
+ const width = 20;
828
+ const filled = Math.round((percentage / 100) * width);
829
+ const empty = width - filled;
830
+ return `[${chalk.green('█'.repeat(filled))}${chalk.gray('░'.repeat(empty))}]`;
831
+ }
832
+
833
+ calculateTaskPriority(task, stateIndex) {
834
+ if (!this.workflowRules || !this.workflowRules.priority_matrix) {
835
+ return 50; // 기본 우선순위
836
+ }
837
+
838
+ const factors = this.workflowRules.priority_matrix.factors;
839
+ let totalWeight = 0;
840
+ let weightedSum = 0;
841
+
842
+ // 긴급도 계산 (마감일 기반)
843
+ const urgency = task.deadline ? this.calculateUrgency(task.deadline) : 3;
844
+ weightedSum += urgency * factors.urgency.weight;
845
+ totalWeight += factors.urgency.weight;
846
+
847
+ // 중요도 (마일스톤/스프린트 우선순위 기반)
848
+ const importance = task.priority === 'high' ? 5 : task.priority === 'medium' ? 3 : 1;
849
+ weightedSum += importance * factors.importance.weight;
850
+ totalWeight += factors.importance.weight;
851
+
852
+ // 블로킹 의존성 수
853
+ const blockingCount = this.countBlockingDependencies(task, stateIndex);
854
+ weightedSum += blockingCount * factors.dependencies_blocking.weight;
855
+ totalWeight += factors.dependencies_blocking.weight;
856
+
857
+ // 노력 (예상 시간 기반)
858
+ const effort = task.estimated_hours ? Math.min(task.estimated_hours / 8, 10) : 5;
859
+ weightedSum += (10 - effort) * factors.effort.weight; // 낮은 노력이 높은 우선순위
860
+
861
+ return Math.round((weightedSum / totalWeight) * 20); // 0-100 스케일로 변환
862
+ }
863
+
864
+ calculateUrgency(deadline) {
865
+ const now = new Date();
866
+ const deadlineDate = new Date(deadline);
867
+ const daysUntilDeadline = Math.floor((deadlineDate - now) / (1000 * 60 * 60 * 24));
868
+
869
+ if (daysUntilDeadline <= 1) return 5;
870
+ if (daysUntilDeadline <= 3) return 4;
871
+ if (daysUntilDeadline <= 7) return 3;
872
+ if (daysUntilDeadline <= 14) return 2;
873
+ return 1;
874
+ }
875
+
876
+ countBlockingDependencies(task, stateIndex) {
877
+ // 이 태스크를 의존하는 다른 태스크 수 계산
878
+ let count = 0;
879
+ Object.values(stateIndex.tasks).forEach(otherTask => {
880
+ if (otherTask.dependencies && otherTask.dependencies.includes(task.id)) {
881
+ count++;
882
+ }
883
+ });
884
+ return Math.min(count, 10);
885
+ }
886
+
887
+ async analyzeDependencies(stateIndex) {
888
+ const dependencies = {};
889
+
890
+ // 태스크 파일에서 의존성 정보 추출
891
+ for (const [taskId, task] of Object.entries(stateIndex.tasks)) {
892
+ dependencies[taskId] = {
893
+ dependsOn: [],
894
+ blockedBy: [],
895
+ blocks: []
896
+ };
897
+
898
+ // 태스크 파일 읽기
899
+ try {
900
+ const taskPath = path.join(this.projectRoot, task.location);
901
+ const taskContent = await fs.readFile(taskPath, 'utf-8');
902
+
903
+ // 의존성 섹션 찾기
904
+ const dependencyMatch = taskContent.match(/##\s*의존성.*?\n([\s\S]*?)(?=\n##|$)/i);
905
+ if (dependencyMatch) {
906
+ const depSection = dependencyMatch[1];
907
+ const taskRefs = depSection.match(/T\d+_S\d+/g) || [];
908
+ dependencies[taskId].dependsOn = taskRefs.filter(ref => ref !== taskId);
909
+ }
910
+ } catch (error) {
911
+ console.warn(`Could not analyze dependencies for ${taskId}: ${error.message}`);
912
+ }
913
+ }
914
+
915
+ // 역방향 의존성 계산
916
+ for (const [taskId, deps] of Object.entries(dependencies)) {
917
+ deps.dependsOn.forEach(depId => {
918
+ if (dependencies[depId]) {
919
+ dependencies[depId].blocks.push(taskId);
920
+ }
921
+ });
922
+ }
923
+
924
+ // 블로킹 태스크 확인
925
+ for (const [taskId, deps] of Object.entries(dependencies)) {
926
+ deps.dependsOn.forEach(depId => {
927
+ const depTask = stateIndex.tasks[depId];
928
+ if (depTask && depTask.status !== 'completed') {
929
+ deps.blockedBy.push(depId);
930
+ }
931
+ });
932
+ }
933
+
934
+ return dependencies;
935
+ }
936
+
937
+ async validateWorkflow(stateIndex) {
938
+ const errors = [];
939
+ const warnings = [];
940
+ const suggestions = [];
941
+
942
+ if (!this.workflowRules) {
943
+ this.workflowRules = await this.loadWorkflowRules();
944
+ }
945
+
946
+ // 스프린트-태스크 일관성 검증
947
+ for (const [sprintId, sprint] of Object.entries(stateIndex.sprint_summary)) {
948
+ if (sprint.status === 'completed') {
949
+ const incompleteTasks = Object.values(stateIndex.tasks)
950
+ .filter(t => t.sprint === sprintId && t.status !== 'completed');
951
+
952
+ if (incompleteTasks.length > 0) {
953
+ errors.push({
954
+ type: 'INCONSISTENT_STATE',
955
+ message: `Sprint ${sprintId} marked complete but has ${incompleteTasks.length} incomplete tasks`,
956
+ sprint: sprintId,
957
+ tasks: incompleteTasks.map(t => t.id)
958
+ });
959
+ }
960
+ }
961
+ }
962
+
963
+ // 의존성 순환 확인
964
+ const dependencies = await this.analyzeDependencies(stateIndex);
965
+ const cycles = this.detectCycles(dependencies);
966
+ if (cycles.length > 0) {
967
+ errors.push({
968
+ type: 'CIRCULAR_DEPENDENCY',
969
+ message: 'Circular dependencies detected',
970
+ cycles: cycles
971
+ });
972
+ }
973
+
974
+ // 80% 규칙 확인
975
+ const currentSprint = stateIndex.project_info.current_sprint;
976
+ if (currentSprint && stateIndex.sprint_summary[currentSprint]) {
977
+ const sprint = stateIndex.sprint_summary[currentSprint];
978
+ if (sprint.completion_rate >= 80 && sprint.completion_rate < 100) {
979
+ suggestions.push({
980
+ type: 'SPRINT_PREPARATION',
981
+ message: `Sprint ${currentSprint} is ${sprint.completion_rate}% complete. Consider preparing the next sprint.`,
982
+ sprint: currentSprint
983
+ });
984
+ }
985
+ }
986
+
987
+ return { errors, warnings, suggestions };
988
+ }
989
+
990
+ detectCycles(dependencies) {
991
+ const cycles = [];
992
+ const visited = new Set();
993
+ const recursionStack = new Set();
994
+
995
+ const dfs = (taskId, path = []) => {
996
+ if (recursionStack.has(taskId)) {
997
+ const cycleStart = path.indexOf(taskId);
998
+ cycles.push(path.slice(cycleStart));
999
+ return;
1000
+ }
1001
+
1002
+ if (visited.has(taskId)) return;
1003
+
1004
+ visited.add(taskId);
1005
+ recursionStack.add(taskId);
1006
+ path.push(taskId);
1007
+
1008
+ const deps = dependencies[taskId]?.dependsOn || [];
1009
+ deps.forEach(depId => dfs(depId, [...path]));
1010
+
1011
+ recursionStack.delete(taskId);
1012
+ };
1013
+
1014
+ Object.keys(dependencies).forEach(taskId => {
1015
+ if (!visited.has(taskId)) {
1016
+ dfs(taskId);
1017
+ }
1018
+ });
1019
+
1020
+ return cycles;
1021
+ }
1022
+
1023
+ async validateCommand() {
1024
+ const spinner = ora('Validating workflow...').start();
1025
+
1026
+ try {
1027
+ // 상태 인덱스 로드
1028
+ const stateIndex = await this.loadStateIndex();
1029
+ if (!stateIndex) {
1030
+ spinner.fail('No state index found. Run "aiwf state update" first.');
1031
+ return;
1032
+ }
1033
+
1034
+ // 워크플로우 규칙 로드
1035
+ if (!this.workflowRules) {
1036
+ this.workflowRules = await this.loadWorkflowRules();
1037
+ }
1038
+
1039
+ // 검증 실행
1040
+ const validation = await this.validateWorkflow(stateIndex);
1041
+ spinner.stop();
1042
+
1043
+ console.log(chalk.bold('\n🔍 Workflow Validation Report\n'));
1044
+
1045
+ const { errors, warnings, suggestions } = validation;
1046
+ const totalIssues = errors.length + warnings.length;
1047
+
1048
+ if (totalIssues === 0) {
1049
+ console.log(chalk.green('✅ Workflow validation passed!'));
1050
+ console.log(chalk.dim(' No errors or warnings found.'));
1051
+ } else {
1052
+ console.log(chalk.yellow(`Found ${totalIssues} issue(s):`));
1053
+ }
1054
+
1055
+ // 오류 표시
1056
+ if (errors.length > 0) {
1057
+ console.log(chalk.red(`\n❌ Errors (${errors.length}):`));
1058
+ errors.forEach((error, i) => {
1059
+ console.log(chalk.red(` ${i + 1}. ${error.type}`));
1060
+ console.log(` ${error.message}`);
1061
+ if (error.tasks) {
1062
+ console.log(chalk.dim(` Affected tasks: ${error.tasks.join(', ')}`));
1063
+ }
1064
+ if (error.cycles) {
1065
+ error.cycles.forEach(cycle => {
1066
+ console.log(chalk.dim(` Cycle: ${cycle.join(' → ')} → ${cycle[0]}`));
1067
+ });
1068
+ }
1069
+ });
1070
+ }
1071
+
1072
+ // 경고 표시
1073
+ if (warnings.length > 0) {
1074
+ console.log(chalk.yellow(`\n⚠️ Warnings (${warnings.length}):`));
1075
+ warnings.forEach((warning, i) => {
1076
+ console.log(chalk.yellow(` ${i + 1}. ${warning.type}`));
1077
+ console.log(` ${warning.message}`);
1078
+ });
1079
+ }
1080
+
1081
+ // 제안사항 표시
1082
+ if (suggestions.length > 0) {
1083
+ console.log(chalk.cyan(`\n💡 Suggestions (${suggestions.length}):`));
1084
+ suggestions.forEach((suggestion, i) => {
1085
+ console.log(chalk.cyan(` ${i + 1}. ${suggestion.type}`));
1086
+ console.log(` ${suggestion.message}`);
1087
+ });
1088
+ }
1089
+
1090
+ // 통계 표시
1091
+ console.log(chalk.bold('\n📊 Workflow Statistics:'));
1092
+ console.log(` Total Tasks: ${Object.keys(stateIndex.tasks).length}`);
1093
+ console.log(` Active Sprints: ${Object.values(stateIndex.sprint_summary).filter(s => s.status === 'active').length}`);
1094
+ console.log(` Overall Progress: ${stateIndex.metrics.overall_progress}%`);
1095
+
1096
+ // 의존성 분석
1097
+ const dependencies = await this.analyzeDependencies(stateIndex);
1098
+ const tasksWithDeps = Object.values(dependencies).filter(d => d.dependsOn.length > 0).length;
1099
+ const blockedTasks = Object.values(dependencies).filter(d => d.blockedBy.length > 0).length;
1100
+
1101
+ console.log(chalk.bold('\n🔗 Dependency Analysis:'));
1102
+ console.log(` Tasks with dependencies: ${tasksWithDeps}`);
1103
+ console.log(` Currently blocked tasks: ${blockedTasks}`);
1104
+ console.log(` Circular dependencies: ${errors.filter(e => e.type === 'CIRCULAR_DEPENDENCY').length}`);
1105
+
1106
+ // 권장 조치
1107
+ if (totalIssues > 0 || suggestions.length > 0) {
1108
+ console.log(chalk.bold('\n🎯 Recommended Actions:'));
1109
+ if (errors.some(e => e.type === 'INCONSISTENT_STATE')) {
1110
+ console.log(' 1. Fix inconsistent sprint/task states');
1111
+ console.log(' - Update task statuses to match sprint status');
1112
+ console.log(' - Or reopen completed sprints if needed');
1113
+ }
1114
+ if (errors.some(e => e.type === 'CIRCULAR_DEPENDENCY')) {
1115
+ console.log(' 2. Resolve circular dependencies');
1116
+ console.log(' - Review and break dependency cycles');
1117
+ console.log(' - Restructure tasks if necessary');
1118
+ }
1119
+ if (suggestions.some(s => s.type === 'SPRINT_PREPARATION')) {
1120
+ console.log(' 3. Prepare next sprint');
1121
+ console.log(' - Current sprint is nearing completion');
1122
+ console.log(' - Create tasks for the next sprint');
1123
+ }
1124
+ }
1125
+
1126
+ console.log('');
1127
+
1128
+ } catch (error) {
1129
+ spinner.fail(`Validation failed: ${error.message}`);
1130
+ throw error;
1131
+ }
1132
+ }
1133
+
1134
+ showHelp() {
1135
+ console.log('\nUsage: aiwf state <subcommand> [options]');
1136
+ console.log('\nSubcommands:');
1137
+ console.log(' init Initialize a new state index');
1138
+ console.log(' update Update state index by scanning all task files');
1139
+ console.log(' show Show current project state');
1140
+ console.log(' focus <id> Set focus to a specific task');
1141
+ console.log(' complete <id> Mark a task as completed');
1142
+ console.log(' next Suggest next actions based on workflow rules');
1143
+ console.log(' validate Validate workflow consistency and dependencies');
1144
+ console.log('\nExamples:');
1145
+ console.log(' aiwf state update # Scan and update all task states');
1146
+ console.log(' aiwf state show # Display current project state');
1147
+ console.log(' aiwf state focus T03_S02 # Start working on a task');
1148
+ console.log(' aiwf state complete T03_S02 # Mark task as completed');
1149
+ console.log(' aiwf state next # Get smart task recommendations');
1150
+ console.log(' aiwf state validate # Check workflow health');
1151
+ console.log('\nWorkflow Features:');
1152
+ console.log(' - Priority-based task recommendations');
1153
+ console.log(' - Dependency tracking and validation');
1154
+ console.log(' - Sprint 80% rule notifications');
1155
+ console.log(' - Parallel work opportunity detection');
1156
+ console.log(' - Workflow consistency validation');
1157
+ }
1158
+ }
1159
+
1160
+ // CLI 실행
1161
+ if (import.meta.url === `file://${process.argv[1]}`) {
1162
+ const command = new StateCommand();
1163
+ command.execute(process.argv.slice(2));
1164
+ }