aiwf 0.3.22 β†’ 0.4.0

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 (456) hide show
  1. package/.claude-plugin/marketplace.json +146 -0
  2. package/CHANGELOG.md +49 -1
  3. package/README.ko.md +118 -309
  4. package/README.md +68 -254
  5. package/docs/modernization/BROWNFIELD-GREENFIELD.ko.md +105 -0
  6. package/docs/modernization/CLAUDE-PLAN-REVIEW-2026-10-03.ko.md +77 -0
  7. package/docs/modernization/CLI-PRODUCTIVITY-REVIEWED-2026-10-03.ko.md +177 -0
  8. package/docs/modernization/CLI-PRODUCTIVITY.ko.md +193 -0
  9. package/docs/modernization/CORE-PACKAGE-PLAN.md +7 -0
  10. package/docs/modernization/DEEP-REVERSE-ENGINEERING.ko.md +88 -0
  11. package/docs/modernization/DELEGATION-OPTIONAL.ko.md +57 -0
  12. package/docs/modernization/DIRECTION.ko.md +56 -0
  13. package/docs/modernization/FULL-TEST-2026-10-03.md +49 -0
  14. package/docs/modernization/LEGACY-REMOVAL-PLAN.md +9 -0
  15. package/docs/modernization/PILOT-RESULT-2026-10-03.ko.md +85 -0
  16. package/docs/modernization/PILOT-UC-001.ko.md +79 -0
  17. package/docs/modernization/PLAN.md +28 -0
  18. package/docs/modernization/SKILLS.ko.md +105 -0
  19. package/docs/modernization/SPRINTABLE.ko.md +47 -0
  20. package/docs/modernization/SYNC-DOCS-VALIDATION-2026-10-04.ko.md +38 -0
  21. package/docs/modernization/VALIDATION.md +79 -0
  22. package/docs/modernization/evidence/example-review-packet.json +115 -0
  23. package/docs/modernization/evidence/example-spec-pin.json +48 -0
  24. package/docs/modernization/evidence/full-test-20261003/claude-lint.md +22 -0
  25. package/docs/modernization/evidence/full-test-20261003/claude-review-retry.md +56 -0
  26. package/docs/modernization/evidence/full-test-20261003/codex-review-packet.json +159 -0
  27. package/docs/modernization/evidence/full-test-20261003/src/expense.mjs +40 -0
  28. package/docs/modernization/evidence/full-test-20261003/summary.json +106 -0
  29. package/docs/modernization/evidence/full-test-20261003/tests/expense.test.mjs +61 -0
  30. package/docs/modernization/evidence/local-pilot-20261003/README.ko.md +40 -0
  31. package/docs/modernization/evidence/local-pilot-20261003/execution.json +1055 -0
  32. package/docs/modernization/evidence/local-pilot-20261003/maintenance/dependencies.json +24 -0
  33. package/docs/modernization/evidence/local-pilot-20261003/maintenance/dependencies.stderr.txt +0 -0
  34. package/docs/modernization/evidence/local-pilot-20261003/maintenance/dependencies.stdout.txt +5 -0
  35. package/docs/modernization/evidence/local-pilot-20261003/maintenance/docs.json +24 -0
  36. package/docs/modernization/evidence/local-pilot-20261003/maintenance/docs.stderr.txt +0 -0
  37. package/docs/modernization/evidence/local-pilot-20261003/maintenance/docs.stdout.txt +6 -0
  38. package/docs/modernization/evidence/local-pilot-20261003/maintenance/example.json +24 -0
  39. package/docs/modernization/evidence/local-pilot-20261003/maintenance/example.stderr.txt +0 -0
  40. package/docs/modernization/evidence/local-pilot-20261003/maintenance/example.stdout.txt +5 -0
  41. package/docs/modernization/evidence/local-pilot-20261003/maintenance/local-docs.json +24 -0
  42. package/docs/modernization/evidence/local-pilot-20261003/maintenance/local-docs.stderr.txt +0 -0
  43. package/docs/modernization/evidence/local-pilot-20261003/maintenance/local-docs.stdout.txt +6 -0
  44. package/docs/modernization/evidence/local-pilot-20261003/maintenance/node.json +23 -0
  45. package/docs/modernization/evidence/local-pilot-20261003/maintenance/node.stderr.txt +0 -0
  46. package/docs/modernization/evidence/local-pilot-20261003/maintenance/node.stdout.txt +535 -0
  47. package/docs/modernization/evidence/local-pilot-20261003/maintenance/provenance.json +24 -0
  48. package/docs/modernization/evidence/local-pilot-20261003/maintenance/provenance.stderr.txt +0 -0
  49. package/docs/modernization/evidence/local-pilot-20261003/maintenance/provenance.stdout.txt +5 -0
  50. package/docs/modernization/evidence/local-pilot-20261003/maintenance/readme-replay.json +24 -0
  51. package/docs/modernization/evidence/local-pilot-20261003/maintenance/readme-replay.stderr.txt +0 -0
  52. package/docs/modernization/evidence/local-pilot-20261003/maintenance/readme-replay.stdout.txt +273 -0
  53. package/docs/modernization/evidence/local-pilot-20261003/maintenance/upstream.json +24 -0
  54. package/docs/modernization/evidence/local-pilot-20261003/maintenance/upstream.stderr.txt +0 -0
  55. package/docs/modernization/evidence/local-pilot-20261003/maintenance/upstream.stdout.txt +7 -0
  56. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/archive-service.stderr.txt +0 -0
  57. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/archive-service.stdout.txt +148 -0
  58. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/archive-structure.stderr.txt +0 -0
  59. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/archive-structure.stdout.txt +9 -0
  60. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-check.stderr.txt +0 -0
  61. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-check.stdout.txt +67 -0
  62. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-evidence.json +34 -0
  63. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-packet.json +128 -0
  64. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-packet.stderr.txt +0 -0
  65. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-packet.stdout.txt +128 -0
  66. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-pin.json +54 -0
  67. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-pin.stderr.txt +0 -0
  68. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-pin.stdout.txt +60 -0
  69. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-readback.json +15 -0
  70. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-service.stderr.txt +0 -0
  71. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-service.stdout.txt +82 -0
  72. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-structure.stderr.txt +0 -0
  73. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/baseline-structure.stdout.txt +9 -0
  74. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/changed-check.stderr.txt +0 -0
  75. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/changed-check.stdout.txt +79 -0
  76. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/changed-packet-refused.stderr.txt +0 -0
  77. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/changed-packet-refused.stdout.txt +7 -0
  78. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/changed-pin-refresh.stderr.txt +0 -0
  79. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/changed-pin-refresh.stdout.txt +66 -0
  80. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/changed-pin.json +60 -0
  81. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/changed-structure.stderr.txt +0 -0
  82. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/changed-structure.stdout.txt +9 -0
  83. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-check.stderr.txt +0 -0
  84. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-check.stdout.txt +73 -0
  85. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-evidence.json +34 -0
  86. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-packet.json +134 -0
  87. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-packet.stderr.txt +0 -0
  88. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-packet.stdout.txt +134 -0
  89. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-readback.json +15 -0
  90. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-service.stderr.txt +0 -0
  91. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-service.stdout.txt +148 -0
  92. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-structure.stderr.txt +0 -0
  93. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/final-structure.stdout.txt +9 -0
  94. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/node-version.stderr.txt +0 -0
  95. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/node-version.stdout.txt +1 -0
  96. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/python-version.stderr.txt +0 -0
  97. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/python-version.stdout.txt +1 -0
  98. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/red-evidence.json +34 -0
  99. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/red-packet.json +134 -0
  100. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/red-packet.stderr.txt +0 -0
  101. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/red-packet.stdout.txt +134 -0
  102. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/red-readback.json +15 -0
  103. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/red-service.stderr.txt +0 -0
  104. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/red-service.stdout.txt +266 -0
  105. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/red-structure.stderr.txt +0 -0
  106. package/docs/modernization/evidence/local-pilot-20261003/project/artifacts/red-structure.stdout.txt +9 -0
  107. package/docs/modernization/evidence/local-pilot-20261003/project/docs/entity_model.md +33 -0
  108. package/docs/modernization/evidence/local-pilot-20261003/project/docs/glossary.md +9 -0
  109. package/docs/modernization/evidence/local-pilot-20261003/project/docs/plans/UC-001.md +20 -0
  110. package/docs/modernization/evidence/local-pilot-20261003/project/docs/requirements.md +10 -0
  111. package/docs/modernization/evidence/local-pilot-20261003/project/docs/test_cases/TC-001-submit-expense.md +37 -0
  112. package/docs/modernization/evidence/local-pilot-20261003/project/docs/test_cases/TC-002-description-limit.md +42 -0
  113. package/docs/modernization/evidence/local-pilot-20261003/project/docs/use_cases/UC-001-submit-expense.md +76 -0
  114. package/docs/modernization/evidence/local-pilot-20261003/project/docs/use_cases.puml +12 -0
  115. package/docs/modernization/evidence/local-pilot-20261003/project/docs/vision.md +21 -0
  116. package/docs/modernization/evidence/local-pilot-20261003/project/src/expense.mjs +48 -0
  117. package/docs/modernization/evidence/local-pilot-20261003/project/tests/expense.test.mjs +116 -0
  118. package/docs/modernization/evidence/local-pilot-20261003/scope.json +31 -0
  119. package/docs/modernization/reviews/2026-10-03-claude-cli/CONTRACTS.ko.md +122 -0
  120. package/docs/modernization/reviews/2026-10-03-claude-cli/DIRECTION.ko.md +84 -0
  121. package/examples/spec-workflow/README.md +54 -0
  122. package/examples/spec-workflow/docs/entity_model.md +33 -0
  123. package/examples/spec-workflow/docs/glossary.md +9 -0
  124. package/examples/spec-workflow/docs/requirements.md +10 -0
  125. package/examples/spec-workflow/docs/test_cases/TC-001-submit-expense.md +37 -0
  126. package/examples/spec-workflow/docs/use_cases/UC-001-submit-expense.md +63 -0
  127. package/examples/spec-workflow/docs/use_cases.puml +12 -0
  128. package/examples/spec-workflow/docs/vision.md +21 -0
  129. package/package.json +37 -104
  130. package/plugins/aiwf-angular-jpa/.claude-plugin/plugin.json +11 -0
  131. package/plugins/aiwf-angular-jpa/LICENSE +201 -0
  132. package/plugins/aiwf-angular-jpa/NOTICE +16 -0
  133. package/plugins/aiwf-angular-jpa/README.md +54 -0
  134. package/plugins/aiwf-angular-jpa/UPSTREAM.json +35 -0
  135. package/plugins/aiwf-angular-jpa/agents/uc-coverage.md +263 -0
  136. package/plugins/aiwf-angular-jpa/rules/mcp-servers.md +64 -0
  137. package/plugins/aiwf-angular-jpa/skills/coverage-check/SKILL.md +190 -0
  138. package/plugins/aiwf-angular-jpa/skills/flyway-migration/SKILL.md +119 -0
  139. package/plugins/aiwf-angular-jpa/skills/implement/SKILL.md +528 -0
  140. package/plugins/aiwf-angular-jpa/skills/implement/references/module-layout.md +95 -0
  141. package/plugins/aiwf-angular-jpa/skills/playwright-test/SKILL.md +360 -0
  142. package/plugins/aiwf-angular-jpa/skills/spring-boot-test/SKILL.md +504 -0
  143. package/plugins/aiwf-angular-jpa/skills/vitest-test/SKILL.md +309 -0
  144. package/plugins/aiwf-blazor-dotnet/.claude-plugin/plugin.json +11 -0
  145. package/plugins/aiwf-blazor-dotnet/LICENSE +201 -0
  146. package/plugins/aiwf-blazor-dotnet/NOTICE +16 -0
  147. package/plugins/aiwf-blazor-dotnet/README.md +53 -0
  148. package/plugins/aiwf-blazor-dotnet/UPSTREAM.json +31 -0
  149. package/plugins/aiwf-blazor-dotnet/rules/mcp-servers.md +25 -0
  150. package/plugins/aiwf-blazor-dotnet/skills/bunit-test/SKILL.md +110 -0
  151. package/plugins/aiwf-blazor-dotnet/skills/dotnet-test/SKILL.md +108 -0
  152. package/plugins/aiwf-blazor-dotnet/skills/ef-migration/SKILL.md +43 -0
  153. package/plugins/aiwf-blazor-dotnet/skills/implement/SKILL.md +149 -0
  154. package/plugins/aiwf-blazor-dotnet/skills/playwright-test/SKILL.md +130 -0
  155. package/plugins/aiwf-core/.claude-plugin/plugin.json +11 -0
  156. package/plugins/aiwf-core/LICENSE +201 -0
  157. package/plugins/aiwf-core/NOTICE +20 -0
  158. package/plugins/aiwf-core/README.md +38 -0
  159. package/plugins/aiwf-core/UPSTREAM.json +50 -0
  160. package/plugins/aiwf-core/skills/entity-model/SKILL.md +160 -0
  161. package/plugins/aiwf-core/skills/entity-model/references/REFERENCE.md +36 -0
  162. package/plugins/aiwf-core/skills/requirements/SKILL.md +157 -0
  163. package/plugins/aiwf-core/skills/requirements/references/REFERENCE.md +70 -0
  164. package/plugins/aiwf-core/skills/requirements/references/glossary.md +7 -0
  165. package/plugins/aiwf-core/skills/reverse-engineer/SKILL.md +509 -0
  166. package/plugins/aiwf-core/skills/reverse-engineer/references/stack-signals.md +210 -0
  167. package/plugins/aiwf-core/skills/spec-review/SKILL.md +197 -0
  168. package/plugins/aiwf-core/skills/spec-review/references/lint-codes.md +63 -0
  169. package/plugins/aiwf-core/skills/spec-review/references/review-checklist.md +189 -0
  170. package/plugins/aiwf-core/skills/spec-review/scripts/spec_lint.py +1216 -0
  171. package/plugins/aiwf-core/skills/test-case/SKILL.md +138 -0
  172. package/plugins/aiwf-core/skills/test-case/references/example-process.bpmn +118 -0
  173. package/plugins/aiwf-core/skills/test-case/references/example.md +38 -0
  174. package/plugins/aiwf-core/skills/test-case/references/test-case.md +35 -0
  175. package/plugins/aiwf-core/skills/test-case/scripts/bpmn_paths.py +542 -0
  176. package/plugins/aiwf-core/skills/use-case-diagram/SKILL.md +99 -0
  177. package/plugins/aiwf-core/skills/use-case-spec/SKILL.md +257 -0
  178. package/plugins/aiwf-core/skills/use-case-spec/references/clarify-checklist.md +70 -0
  179. package/plugins/aiwf-core/skills/use-case-spec/references/example.md +88 -0
  180. package/plugins/aiwf-core/skills/use-case-spec/references/format-spec.md +246 -0
  181. package/plugins/aiwf-core/skills/use-case-spec/references/use-case.md +50 -0
  182. package/plugins/aiwf-core/skills/use-case-spec/scripts/validate_use_case.py +941 -0
  183. package/plugins/aiwf-delegate-claude/.claude-plugin/plugin.json +9 -0
  184. package/{src/lib/resources/templates/npm-library/template β†’ plugins/aiwf-delegate-claude}/LICENSE +2 -2
  185. package/plugins/aiwf-delegate-claude/NOTICE +4 -0
  186. package/plugins/aiwf-delegate-claude/README.md +10 -0
  187. package/plugins/aiwf-delegate-claude/plugin.json +13 -0
  188. package/plugins/aiwf-delegate-claude/skills/delegate-claude/LICENSE +21 -0
  189. package/plugins/aiwf-delegate-claude/skills/delegate-claude/NOTICE +4 -0
  190. package/plugins/aiwf-delegate-claude/skills/delegate-claude/SKILL.md +49 -0
  191. package/plugins/aiwf-delegate-claude/skills/delegate-claude/agents/openai.yaml +2 -0
  192. package/plugins/aiwf-delegate-codex/.claude-plugin/plugin.json +9 -0
  193. package/plugins/aiwf-delegate-codex/LICENSE +21 -0
  194. package/plugins/aiwf-delegate-codex/NOTICE +4 -0
  195. package/plugins/aiwf-delegate-codex/README.md +10 -0
  196. package/plugins/aiwf-delegate-codex/plugin.json +13 -0
  197. package/plugins/aiwf-delegate-codex/skills/delegate-codex/LICENSE +21 -0
  198. package/plugins/aiwf-delegate-codex/skills/delegate-codex/NOTICE +4 -0
  199. package/plugins/aiwf-delegate-codex/skills/delegate-codex/SKILL.md +47 -0
  200. package/plugins/aiwf-delegate-codex/skills/delegate-codex/agents/openai.yaml +2 -0
  201. package/plugins/aiwf-nestjs-nextjs/.claude-plugin/plugin.json +11 -0
  202. package/plugins/aiwf-nestjs-nextjs/LICENSE +201 -0
  203. package/plugins/aiwf-nestjs-nextjs/NOTICE +16 -0
  204. package/plugins/aiwf-nestjs-nextjs/README.md +53 -0
  205. package/plugins/aiwf-nestjs-nextjs/UPSTREAM.json +32 -0
  206. package/plugins/aiwf-nestjs-nextjs/rules/mcp-servers.md +59 -0
  207. package/plugins/aiwf-nestjs-nextjs/skills/drizzle-migration/SKILL.md +222 -0
  208. package/plugins/aiwf-nestjs-nextjs/skills/implement/SKILL.md +393 -0
  209. package/plugins/aiwf-nestjs-nextjs/skills/implement/references/project-layout.md +158 -0
  210. package/plugins/aiwf-nestjs-nextjs/skills/nest-test/SKILL.md +300 -0
  211. package/plugins/aiwf-nestjs-nextjs/skills/playwright-test/SKILL.md +245 -0
  212. package/plugins/aiwf-nestjs-nextjs/skills/react-test/SKILL.md +217 -0
  213. package/plugins/aiwf-spec/.claude-plugin/plugin.json +9 -0
  214. package/plugins/aiwf-spec/LICENSE +201 -0
  215. package/plugins/aiwf-spec/NOTICE +20 -0
  216. package/plugins/aiwf-spec/README.md +36 -0
  217. package/plugins/aiwf-spec/skills/sync-docs/SKILL.md +47 -0
  218. package/plugins/aiwf-spec/skills/workflow/SKILL.md +42 -0
  219. package/plugins/aiwf-vaadin-jooq/.claude-plugin/plugin.json +11 -0
  220. package/plugins/aiwf-vaadin-jooq/LICENSE +201 -0
  221. package/plugins/aiwf-vaadin-jooq/NOTICE +16 -0
  222. package/plugins/aiwf-vaadin-jooq/README.md +56 -0
  223. package/plugins/aiwf-vaadin-jooq/UPSTREAM.json +43 -0
  224. package/plugins/aiwf-vaadin-jooq/agents/uc-coverage.md +260 -0
  225. package/plugins/aiwf-vaadin-jooq/rules/mcp-servers.md +44 -0
  226. package/plugins/aiwf-vaadin-jooq/skills/browserless-test/SKILL.md +407 -0
  227. package/plugins/aiwf-vaadin-jooq/skills/browserless-test/references/UC001ManagePersonsTest.java +111 -0
  228. package/plugins/aiwf-vaadin-jooq/skills/coverage-check/SKILL.md +190 -0
  229. package/plugins/aiwf-vaadin-jooq/skills/flyway-migration/SKILL.md +70 -0
  230. package/plugins/aiwf-vaadin-jooq/skills/hilla-test/SKILL.md +350 -0
  231. package/plugins/aiwf-vaadin-jooq/skills/hilla-test/references/UC001ManagePersonsServiceTest.java +81 -0
  232. package/plugins/aiwf-vaadin-jooq/skills/hilla-test/references/UC001ManagePersonsViewTest.tsx +87 -0
  233. package/plugins/aiwf-vaadin-jooq/skills/implement/SKILL.md +196 -0
  234. package/plugins/aiwf-vaadin-jooq/skills/implement-hilla/SKILL.md +216 -0
  235. package/plugins/aiwf-vaadin-jooq/skills/karibu-test/SKILL.md +298 -0
  236. package/plugins/aiwf-vaadin-jooq/skills/karibu-test/references/UC001ManagePersonsTest.java +93 -0
  237. package/plugins/aiwf-vaadin-jooq/skills/playwright-test/SKILL.md +237 -0
  238. package/plugins/aiwf-vaadin-jooq/skills/playwright-test/references/ExampleViewIT.java +143 -0
  239. package/plugins/aiwf-vaadin-jooq/skills/playwright-test/references/TC001CustomerOnboardingIT.java +144 -0
  240. package/plugins/aiwf-vaadin-jooq/skills/playwright-test/references/dramafinder-api.md +190 -0
  241. package/scripts/check-dependencies.js +26 -96
  242. package/scripts/install-spec-skills.mjs +126 -0
  243. package/scripts/validate-spec-plugin.mjs +145 -0
  244. package/src/cli/spec-cli.js +292 -0
  245. package/src/lib/spec-workflow.js +982 -0
  246. package/docs/ADR_MANAGEMENT_GUIDE.ko.md +0 -602
  247. package/docs/ADR_MANAGEMENT_GUIDE.md +0 -602
  248. package/docs/AI-WORKFLOW.ko.md +0 -299
  249. package/docs/AI-WORKFLOW.md +0 -401
  250. package/docs/API_REFERENCE_FULL.ko.md +0 -1135
  251. package/docs/API_REFERENCE_FULL.md +0 -1135
  252. package/docs/ARCHITECTURE.ko.md +0 -314
  253. package/docs/ARCHITECTURE.md +0 -314
  254. package/docs/CLI_USAGE_GUIDE.ko.md +0 -634
  255. package/docs/CLI_USAGE_GUIDE.md +0 -640
  256. package/docs/CODE_CLEANUP_GUIDE.ko.md +0 -415
  257. package/docs/CODE_CLEANUP_GUIDE.md +0 -415
  258. package/docs/COMMANDS_GUIDE.ko.md +0 -1037
  259. package/docs/COMMANDS_GUIDE.md +0 -1037
  260. package/docs/CONTRIBUTING.ko.md +0 -408
  261. package/docs/CONTRIBUTING.md +0 -408
  262. package/docs/DEVELOPMENT_GUIDE.ko.md +0 -440
  263. package/docs/DEVELOPMENT_GUIDE.md +0 -727
  264. package/docs/EXAMPLES.ko.md +0 -695
  265. package/docs/EXAMPLES.md +0 -693
  266. package/docs/GETTING_STARTED.ko.md +0 -219
  267. package/docs/GETTING_STARTED.md +0 -476
  268. package/docs/MODULE_MANAGEMENT_GUIDE.ko.md +0 -289
  269. package/docs/MODULE_MANAGEMENT_GUIDE.md +0 -289
  270. package/docs/PERFORMANCE_ARCHITECTURE.md +0 -494
  271. package/docs/PERFORMANCE_GUIDELINES.ko.md +0 -388
  272. package/docs/PERFORMANCE_GUIDELINES.md +0 -553
  273. package/docs/PRD.ko.md +0 -148
  274. package/docs/PRD.md +0 -150
  275. package/docs/ROADMAP_v0.4.0.md +0 -286
  276. package/docs/STATE_MANAGEMENT_GUIDE.ko.md +0 -278
  277. package/docs/STATE_MANAGEMENT_GUIDE.md +0 -278
  278. package/docs/TROUBLESHOOTING.ko.md +0 -366
  279. package/docs/TROUBLESHOOTING.md +0 -722
  280. package/docs/VALIDATOR_API.ko.md +0 -324
  281. package/docs/VALIDATOR_API.md +0 -324
  282. package/docs/YOLO_SYSTEM_GUIDE.ko.md +0 -542
  283. package/docs/YOLO_SYSTEM_GUIDE.md +0 -542
  284. package/docs/designs/AI_PERSONA_SYSTEM_DESIGN.md +0 -516
  285. package/docs/designs/API_DOCUMENTATION.md +0 -932
  286. package/docs/designs/API_REFERENCE.md +0 -979
  287. package/docs/designs/Enhanced_Installation_Flow_Design.md +0 -498
  288. package/docs/designs/aiwf-metadata-system-prd.md +0 -127
  289. package/docs/designs/offline-template-cache.md +0 -323
  290. package/docs/designs/persona-aware-compression.md +0 -168
  291. package/docs/guides/ai-personas-guide-ko.md +0 -239
  292. package/docs/guides/ai-personas-guide.md +0 -239
  293. package/docs/guides/checkpoint-system-guide-ko.md +0 -356
  294. package/docs/guides/checkpoint-system-guide.md +0 -356
  295. package/docs/guides/context-compression-guide-ko.md +0 -313
  296. package/docs/guides/context-compression-guide.md +0 -313
  297. package/docs/guides/independent-sprint-guide-ko.md +0 -321
  298. package/docs/guides/independent-sprint-guide.md +0 -321
  299. package/rules/global/aiwf-code-style-guide.md +0 -30
  300. package/rules/global/aiwf-coding-principles.md +0 -33
  301. package/rules/global/aiwf-development-process.md +0 -41
  302. package/rules/global/aiwf-global-rules.md +0 -84
  303. package/rules/manual/aiwf-generate-plan-docs.md +0 -280
  304. package/scripts/run-integration-tests.js +0 -317
  305. package/scripts/update-file-lists.js +0 -267
  306. package/scripts/validate-commands.js +0 -254
  307. package/src/DEPENDENCY_MAP.md +0 -90
  308. package/src/cli/cache-cli.js +0 -459
  309. package/src/cli/checkpoint-cli.js +0 -417
  310. package/src/cli/index.js +0 -481
  311. package/src/cli/language-cli.js +0 -286
  312. package/src/cli/sprint-cli.js +0 -287
  313. package/src/commands/ai-tool.js +0 -383
  314. package/src/commands/compress.js +0 -60
  315. package/src/commands/create-project.js +0 -160
  316. package/src/commands/evaluate.js +0 -459
  317. package/src/commands/persona.js +0 -309
  318. package/src/commands/sprint-independent.js +0 -393
  319. package/src/commands/sprint-task.js +0 -262
  320. package/src/commands/state.js +0 -1164
  321. package/src/commands/token.js +0 -312
  322. package/src/commands/yolo-config.js +0 -502
  323. package/src/config/file-lists.js +0 -147
  324. package/src/config/yolo-config-template.yaml +0 -168
  325. package/src/lib/ai-persona-manager.js +0 -711
  326. package/src/lib/backup-manager.js +0 -271
  327. package/src/lib/cache-system.js +0 -332
  328. package/src/lib/context-engine.js +0 -568
  329. package/src/lib/file-downloader.js +0 -304
  330. package/src/lib/github-integration.js +0 -402
  331. package/src/lib/installer.js +0 -1066
  332. package/src/lib/memory-profiler.js +0 -471
  333. package/src/lib/metrics-collector.js +0 -885
  334. package/src/lib/offline-detector.js +0 -386
  335. package/src/lib/resource-loader-enhanced.js +0 -399
  336. package/src/lib/resource-loader.js +0 -250
  337. package/src/lib/resources/commands/ai-persona.js +0 -602
  338. package/src/lib/resources/commands/compress-context.js +0 -389
  339. package/src/lib/resources/commands/evaluate.js +0 -246
  340. package/src/lib/resources/commands/persona-context-apply.js +0 -562
  341. package/src/lib/resources/commands/token-tracking.js +0 -443
  342. package/src/lib/resources/config/commit-patterns.js +0 -103
  343. package/src/lib/resources/config/language.json +0 -6
  344. package/src/lib/resources/personas/PERSONA_INDEX.md +0 -57
  345. package/src/lib/resources/personas/analyst.json +0 -44
  346. package/src/lib/resources/personas/architect/best_practices.md +0 -136
  347. package/src/lib/resources/personas/architect/knowledge_base.md +0 -377
  348. package/src/lib/resources/personas/architect.json +0 -44
  349. package/src/lib/resources/personas/backend/best_practices.md +0 -766
  350. package/src/lib/resources/personas/backend/knowledge_base.md +0 -1070
  351. package/src/lib/resources/personas/data_analyst/best_practices.md +0 -594
  352. package/src/lib/resources/personas/data_analyst/knowledge_base.md +0 -1057
  353. package/src/lib/resources/personas/developer.json +0 -44
  354. package/src/lib/resources/personas/developer.md +0 -37
  355. package/src/lib/resources/personas/evaluation_criteria.json +0 -137
  356. package/src/lib/resources/personas/frontend/best_practices.md +0 -445
  357. package/src/lib/resources/personas/frontend/knowledge_base.md +0 -729
  358. package/src/lib/resources/personas/persona-index.json +0 -31
  359. package/src/lib/resources/personas/reviewer.json +0 -44
  360. package/src/lib/resources/personas/security/best_practices.md +0 -307
  361. package/src/lib/resources/personas/security/knowledge_base.md +0 -498
  362. package/src/lib/resources/personas/tester.json +0 -44
  363. package/src/lib/resources/templates/README.md +0 -78
  364. package/src/lib/resources/templates/api-server/config.json +0 -64
  365. package/src/lib/resources/templates/api-server/template/.aiwf/config.json +0 -56
  366. package/src/lib/resources/templates/api-server/template/.aiwf/feature-ledger.json +0 -42
  367. package/src/lib/resources/templates/api-server/template/.aiwf/personas/backend-engineer.json +0 -40
  368. package/src/lib/resources/templates/api-server/template/.aiwf/scripts/cli.js +0 -111
  369. package/src/lib/resources/templates/api-server/template/.env.example +0 -29
  370. package/src/lib/resources/templates/api-server/template/.eslintrc.json +0 -23
  371. package/src/lib/resources/templates/api-server/template/README.md +0 -171
  372. package/src/lib/resources/templates/api-server/template/jest.config.js +0 -26
  373. package/src/lib/resources/templates/api-server/template/nodemon.json +0 -9
  374. package/src/lib/resources/templates/api-server/template/package.json +0 -61
  375. package/src/lib/resources/templates/api-server/template/src/app.ts +0 -60
  376. package/src/lib/resources/templates/api-server/template/src/config/swagger.ts +0 -38
  377. package/src/lib/resources/templates/api-server/template/src/controllers/aiwfController.ts +0 -54
  378. package/src/lib/resources/templates/api-server/template/src/controllers/authController.ts +0 -128
  379. package/src/lib/resources/templates/api-server/template/src/controllers/statusController.ts +0 -28
  380. package/src/lib/resources/templates/api-server/template/src/index.ts +0 -28
  381. package/src/lib/resources/templates/api-server/template/src/middleware/aiwfMiddleware.ts +0 -50
  382. package/src/lib/resources/templates/api-server/template/src/middleware/authMiddleware.ts +0 -41
  383. package/src/lib/resources/templates/api-server/template/src/middleware/errorHandler.ts +0 -42
  384. package/src/lib/resources/templates/api-server/template/src/middleware/notFoundHandler.ts +0 -14
  385. package/src/lib/resources/templates/api-server/template/src/middleware/requestLogger.ts +0 -20
  386. package/src/lib/resources/templates/api-server/template/src/routes/aiwf.ts +0 -31
  387. package/src/lib/resources/templates/api-server/template/src/routes/index.ts +0 -13
  388. package/src/lib/resources/templates/api-server/template/src/routes/v1/index.ts +0 -67
  389. package/src/lib/resources/templates/api-server/template/src/utils/logger.ts +0 -37
  390. package/src/lib/resources/templates/api-server/template/tests/app.test.ts +0 -40
  391. package/src/lib/resources/templates/api-server/template/tsconfig.json +0 -43
  392. package/src/lib/resources/templates/npm-library/config.json +0 -61
  393. package/src/lib/resources/templates/npm-library/template/README.md +0 -201
  394. package/src/lib/resources/templates/npm-library/template/package.json +0 -78
  395. package/src/lib/resources/templates/web-app/config.json +0 -53
  396. package/src/lib/resources/templates/web-app/template/.aiwf/config.json +0 -54
  397. package/src/lib/resources/templates/web-app/template/.aiwf/feature-ledger.json +0 -37
  398. package/src/lib/resources/templates/web-app/template/.aiwf/personas/fullstack-developer.json +0 -40
  399. package/src/lib/resources/templates/web-app/template/.aiwf/scripts/cli.js +0 -110
  400. package/src/lib/resources/templates/web-app/template/.eslintrc.cjs +0 -20
  401. package/src/lib/resources/templates/web-app/template/README.md +0 -151
  402. package/src/lib/resources/templates/web-app/template/index.html +0 -14
  403. package/src/lib/resources/templates/web-app/template/package.json +0 -44
  404. package/src/lib/resources/templates/web-app/template/postcss.config.js +0 -6
  405. package/src/lib/resources/templates/web-app/template/public/vite.svg +0 -1
  406. package/src/lib/resources/templates/web-app/template/src/App.tsx +0 -21
  407. package/src/lib/resources/templates/web-app/template/src/components/Layout.tsx +0 -57
  408. package/src/lib/resources/templates/web-app/template/src/components/aiwf/ContextStatus.tsx +0 -107
  409. package/src/lib/resources/templates/web-app/template/src/components/aiwf/TokenUsage.tsx +0 -71
  410. package/src/lib/resources/templates/web-app/template/src/index.css +0 -60
  411. package/src/lib/resources/templates/web-app/template/src/main.tsx +0 -10
  412. package/src/lib/resources/templates/web-app/template/src/pages/AiwfDashboard.tsx +0 -57
  413. package/src/lib/resources/templates/web-app/template/src/pages/HomePage.tsx +0 -89
  414. package/src/lib/resources/templates/web-app/template/src/pages/NotFound.tsx +0 -25
  415. package/src/lib/resources/templates/web-app/template/src/stores/aiwfStore.ts +0 -126
  416. package/src/lib/resources/templates/web-app/template/src/types/global.d.ts +0 -9
  417. package/src/lib/resources/templates/web-app/template/src/vite-env.d.ts +0 -1
  418. package/src/lib/resources/templates/web-app/template/tailwind.config.js +0 -30
  419. package/src/lib/resources/templates/web-app/template/tsconfig.json +0 -37
  420. package/src/lib/resources/templates/web-app/template/tsconfig.node.json +0 -10
  421. package/src/lib/resources/templates/web-app/template/vite.config.ts +0 -23
  422. package/src/lib/resources/utils/background-monitor.js +0 -223
  423. package/src/lib/resources/utils/compression-metrics.js +0 -1031
  424. package/src/lib/resources/utils/compression-strategies.js +0 -557
  425. package/src/lib/resources/utils/content-normalizer.js +0 -455
  426. package/src/lib/resources/utils/context-compressor.js +0 -583
  427. package/src/lib/resources/utils/context-rule-parser.js +0 -180
  428. package/src/lib/resources/utils/context-token-monitor.js +0 -463
  429. package/src/lib/resources/utils/context-update-manager.js +0 -502
  430. package/src/lib/resources/utils/git-utils.js +0 -220
  431. package/src/lib/resources/utils/importance-classifier.js +0 -645
  432. package/src/lib/resources/utils/information-filter.js +0 -710
  433. package/src/lib/resources/utils/persona-aware-compressor.js +0 -598
  434. package/src/lib/resources/utils/prompt-injector.js +0 -242
  435. package/src/lib/resources/utils/simplified-evaluator.js +0 -119
  436. package/src/lib/resources/utils/text-summarizer.js +0 -492
  437. package/src/lib/resources/utils/token-counter.js +0 -177
  438. package/src/lib/resources/utils/token-monitor.js +0 -484
  439. package/src/lib/resources/utils/token-reporter.js +0 -452
  440. package/src/lib/resources/utils/token-storage.js +0 -433
  441. package/src/lib/resources/utils/token-tracker.js +0 -283
  442. package/src/lib/rollback-manager.js +0 -418
  443. package/src/lib/state/priority-calculator.js +0 -217
  444. package/src/lib/state/state-index.js +0 -155
  445. package/src/lib/state/task-scanner.js +0 -328
  446. package/src/lib/task-analyzer.js +0 -599
  447. package/src/lib/template-cache-system.js +0 -559
  448. package/src/lib/template-downloader.js +0 -467
  449. package/src/lib/template-version-manager.js +0 -491
  450. package/src/lib/token-optimizer.js +0 -517
  451. package/src/lib/validator.js +0 -376
  452. package/src/utils/checkpoint-manager.js +0 -435
  453. package/src/utils/engineering-guard.js +0 -399
  454. package/src/utils/language-utils.js +0 -331
  455. package/src/utils/messages.js +0 -166
  456. package/src/utils/paths.js +0 -112
@@ -1,1066 +0,0 @@
1
- import fs from 'fs/promises';
2
- import path from 'path';
3
- import os from 'os';
4
- import ora from 'ora';
5
- import chalk from 'chalk';
6
- import prompts from 'prompts';
7
- import {
8
- fetchContent,
9
- downloadFile,
10
- downloadDirectory,
11
- GITHUB_RAW_URL,
12
- GITHUB_CONTENT_PREFIX
13
- } from './file-downloader.js';
14
- import {
15
- backupCommandsAndDocs,
16
- restoreFromBackup,
17
- getCurrentBackupDir,
18
- setBackupDir
19
- } from './backup-manager.js';
20
- import { getMessages } from '../utils/messages.js';
21
- import {
22
- validateInstallation,
23
- displaySpecCompliantValidationResults
24
- } from './validator.js';
25
- import { rollbackTool } from './rollback-manager.js';
26
- import {
27
- detectLanguage,
28
- loadUserLanguageConfig,
29
- saveUserLanguageConfig,
30
- getInstallationLanguagePath,
31
- SUPPORTED_LANGUAGES,
32
- DEFAULT_LANGUAGE
33
- } from '../utils/language-utils.js';
34
- import {
35
- FILES,
36
- TOOL_DIRS,
37
- AIWF_DIRS,
38
- BASE_DIRS,
39
- getAllAiwfDirectories,
40
- getAllClaudeMdFiles
41
- } from '../utils/paths.js';
42
-
43
- /**
44
- * Check if AIWF is already installed
45
- * @returns {Promise<boolean>} Installation status
46
- */
47
- async function checkExistingInstallation() {
48
- const flagExists = await fs
49
- .access(FILES.INSTALLED_FLAG)
50
- .then(() => true)
51
- .catch(() => false);
52
- return flagExists;
53
- }
54
-
55
- /**
56
- * Check if existing project files exist
57
- * @returns {Promise<{hasProject: boolean, projectFiles: string[]}>} Project status
58
- */
59
- async function checkExistingProject() {
60
- const projectFiles = [];
61
- let hasProject = false;
62
-
63
- // Check for key project files
64
- const keyFiles = [
65
- FILES.PROJECT_MANIFEST,
66
- path.join(AIWF_DIRS.PROJECT_DOCS, 'README.md'),
67
- path.join(AIWF_DIRS.REQUIREMENTS, 'requirements.md'),
68
- path.join(AIWF_DIRS.SPRINTS, 'sprint-01.md'),
69
- path.join(AIWF_DIRS.GENERAL_TASKS, 'tasks.md'),
70
- path.join(AIWF_DIRS.ARCHITECTURAL_DECISIONS, 'decisions.md'),
71
- path.join(AIWF_DIRS.STATE_OF_PROJECT, 'current-state.md')
72
- ];
73
-
74
- for (const file of keyFiles) {
75
- try {
76
- await fs.access(file);
77
- projectFiles.push(file);
78
- hasProject = true;
79
- } catch (error) {
80
- // File doesn't exist, continue
81
- }
82
- }
83
-
84
- // Check for any .md files in project directories
85
- const projectDirs = [
86
- AIWF_DIRS.PROJECT_DOCS,
87
- AIWF_DIRS.REQUIREMENTS,
88
- AIWF_DIRS.SPRINTS,
89
- AIWF_DIRS.GENERAL_TASKS,
90
- AIWF_DIRS.ARCHITECTURAL_DECISIONS,
91
- AIWF_DIRS.STATE_OF_PROJECT
92
- ];
93
-
94
- for (const dir of projectDirs) {
95
- try {
96
- const files = await fs.readdir(dir);
97
- const mdFiles = files.filter(file => file.endsWith('.md'));
98
- if (mdFiles.length > 0) {
99
- hasProject = true;
100
- projectFiles.push(...mdFiles.map(file => path.join(dir, file)));
101
- }
102
- } catch (error) {
103
- // Directory doesn't exist, continue
104
- }
105
- }
106
-
107
- return { hasProject, projectFiles };
108
- }
109
-
110
- /**
111
- * Log with spinner for debug mode
112
- * @param {Object} spinner - Ora spinner instance
113
- * @param {string} message - Message to log
114
- * @param {boolean} debugLog - Debug mode flag
115
- */
116
- function logWithSpinner(spinner, message, debugLog) {
117
- if (debugLog) console.log(chalk.gray(message));
118
- if (spinner) spinner.text = message;
119
- }
120
-
121
- /**
122
- * Select language for installation
123
- * @param {Object} options - Installation options
124
- * @returns {Promise<string>} Selected language
125
- */
126
- async function selectLanguage(options) {
127
- let selectedLanguage = DEFAULT_LANGUAGE;
128
-
129
- if (!options.force) {
130
- // 1. Check existing configuration
131
- const existingConfig = await loadUserLanguageConfig();
132
-
133
- if (existingConfig && existingConfig.language) {
134
- selectedLanguage = existingConfig.language;
135
- console.log(
136
- chalk.blue(
137
- `🌐 κΈ°μ‘΄ μ–Έμ–΄ 섀정을 μ‚¬μš©ν•©λ‹ˆλ‹€ / Using existing language setting: ${selectedLanguage}`
138
- )
139
- );
140
- } else {
141
- // 2. Try auto-detection
142
- const detectedLang = await detectLanguage();
143
-
144
- console.log(
145
- chalk.gray(`πŸ” μ‹œμŠ€ν…œ μ–Έμ–΄ 감지 / System language detected: ${detectedLang}`)
146
- );
147
-
148
- // 3. Prompt user for language selection
149
- const languageResponse = await prompts({
150
- type: 'select',
151
- name: 'language',
152
- message: 'Please select language / μ–Έμ–΄λ₯Ό μ„ νƒν•΄μ£Όμ„Έμš”:',
153
- choices: [
154
- { title: 'English', value: 'en' },
155
- { title: 'ν•œκ΅­μ–΄ (Korean)', value: 'ko' }
156
- ],
157
- initial:
158
- SUPPORTED_LANGUAGES.indexOf(detectedLang) !== -1
159
- ? SUPPORTED_LANGUAGES.indexOf(detectedLang)
160
- : 0
161
- });
162
-
163
- if (languageResponse.language) {
164
- selectedLanguage = languageResponse.language;
165
- } else {
166
- selectedLanguage = detectedLang;
167
- }
168
-
169
- // 4. Save selected language
170
- try {
171
- await saveUserLanguageConfig(selectedLanguage, {
172
- autoDetect: true,
173
- fallback: DEFAULT_LANGUAGE
174
- });
175
- console.log(
176
- chalk.green(
177
- `βœ… μ–Έμ–΄ 섀정이 μ €μž₯λ˜μ—ˆμŠ΅λ‹ˆλ‹€ / Language preference saved: ${selectedLanguage}`
178
- )
179
- );
180
- } catch (error) {
181
- console.warn(
182
- chalk.yellow(
183
- `⚠️ μ–Έμ–΄ μ„€μ • μ €μž₯ μ‹€νŒ¨ / Failed to save language preference: ${error.message}`
184
- )
185
- );
186
- }
187
- }
188
- } else {
189
- // Force mode: try auto-detection
190
- try {
191
- selectedLanguage = await detectLanguage();
192
- } catch (error) {
193
- selectedLanguage = DEFAULT_LANGUAGE;
194
- }
195
- }
196
-
197
- return selectedLanguage;
198
- }
199
-
200
- /**
201
- * Handle existing installation
202
- * @param {Object} msg - Localized messages
203
- * @param {Object} options - Installation options
204
- * @returns {Promise<{continue: boolean, installType: string, preserveProject: boolean}>} Installation decision
205
- */
206
- async function handleExistingInstallation(msg, options) {
207
-
208
- if (options.force) {
209
- return { continue: true, installType: 'reinstall', preserveProject: false };
210
- }
211
-
212
- // First, ask about installation type
213
- const installResponse = await prompts({
214
- type: 'select',
215
- name: 'action',
216
- message: msg.existingDetected,
217
- choices: [
218
- { title: msg.updateOption, value: 'update' },
219
- { title: msg.reinstallOption, value: 'reinstall' },
220
- { title: msg.skipOption, value: 'skip' },
221
- { title: msg.cancelOption, value: 'cancel' }
222
- ]
223
- });
224
-
225
-
226
-
227
- if (installResponse.action === 'skip' || installResponse.action === 'cancel') {
228
- console.log(chalk.yellow(msg.installCancelled));
229
- process.exit(0);
230
- }
231
-
232
- let preserveProject = true; // Default to preserve
233
-
234
- // If reinstalling, don't preserve project (complete fresh install)
235
- if (installResponse.action === 'reinstall') {
236
- preserveProject = false;
237
- }
238
-
239
- // Backup if updating
240
- if (installResponse.action === 'update') {
241
- await backupCommandsAndDocs(msg);
242
- }
243
-
244
- return {
245
- continue: true,
246
- installType: installResponse.action,
247
- preserveProject
248
- };
249
- }
250
-
251
- /**
252
- * Backup project files
253
- * @param {string[]} projectFiles - List of project files to backup
254
- * @param {Object} msg - Localized messages
255
- * @returns {Promise<string>} Backup directory path
256
- */
257
- async function backupProjectFiles(projectFiles, msg) {
258
- if (projectFiles.length === 0) {
259
- return null;
260
- }
261
-
262
- const backupDir = path.join(os.tmpdir(), `aiwf-project-backup-${Date.now()}`);
263
- await fs.mkdir(backupDir, { recursive: true });
264
-
265
- console.log(chalk.cyan('πŸ’Ύ Backing up project files...'));
266
-
267
- for (const file of projectFiles) {
268
- try {
269
- const relativePath = path.relative(process.cwd(), file);
270
- const backupPath = path.join(backupDir, relativePath);
271
- const backupDirPath = path.dirname(backupPath);
272
-
273
- await fs.mkdir(backupDirPath, { recursive: true });
274
- await fs.copyFile(file, backupPath);
275
- } catch (error) {
276
- console.log(chalk.yellow(`Warning: Could not backup ${file}: ${error.message}`));
277
- }
278
- }
279
-
280
- console.log(chalk.green(`βœ… Project files backed up to: ${backupDir}`));
281
- return backupDir;
282
- }
283
-
284
- /**
285
- * Restore project files from backup
286
- * @param {string} backupDir - Backup directory path
287
- * @param {Object} msg - Localized messages
288
- */
289
- async function restoreProjectFiles(backupDir, msg) {
290
- if (!backupDir) {
291
- return;
292
- }
293
-
294
- console.log(chalk.cyan('πŸ”„ Restoring project files...'));
295
-
296
- try {
297
- const backupFiles = await fs.readdir(backupDir, { recursive: true });
298
-
299
- for (const file of backupFiles) {
300
- const backupFilePath = path.join(backupDir, file);
301
- const stat = await fs.stat(backupFilePath);
302
-
303
- if (stat.isFile()) {
304
- const targetPath = path.join(process.cwd(), file);
305
- const targetDir = path.dirname(targetPath);
306
-
307
- await fs.mkdir(targetDir, { recursive: true });
308
- await fs.copyFile(backupFilePath, targetPath);
309
- }
310
- }
311
-
312
- console.log(chalk.green(msg.projectPreserved));
313
-
314
- // Clean up backup directory
315
- await fs.rm(backupDir, { recursive: true, force: true });
316
- } catch (error) {
317
- console.log(chalk.yellow(`Warning: Could not restore some project files: ${error.message}`));
318
- console.log(chalk.yellow(`Backup preserved at: ${backupDir}`));
319
- }
320
- }
321
-
322
- /**
323
- * Remove project files
324
- * @param {string[]} projectFiles - List of project files to remove
325
- * @param {Object} msg - Localized messages
326
- */
327
- async function removeProjectFiles(projectFiles, msg) {
328
- if (projectFiles.length === 0) {
329
- return;
330
- }
331
-
332
- console.log(chalk.cyan('πŸ—‘οΈ Removing existing project files...'));
333
-
334
- for (const file of projectFiles) {
335
- try {
336
- await fs.unlink(file);
337
- } catch (error) {
338
- // File might already be deleted, continue
339
- }
340
- }
341
-
342
- console.log(chalk.green(msg.projectOverwritten));
343
- }
344
-
345
- /**
346
- * Create AIWF directory structure
347
- */
348
- async function createDirectoryStructure() {
349
- const aiwfDirs = getAllAiwfDirectories();
350
-
351
- // Create AIWF directories
352
- for (const dir of aiwfDirs) {
353
- await fs.mkdir(dir, { recursive: true });
354
- }
355
-
356
- // Create tool-specific directories
357
- await fs.mkdir(TOOL_DIRS.CURSOR_RULES, { recursive: true });
358
- await fs.mkdir(TOOL_DIRS.WINDSURF_RULES, { recursive: true });
359
- await fs.mkdir(TOOL_DIRS.CLAUDE_AGENTS, { recursive: true });
360
- }
361
-
362
- /**
363
- * Download manifest file
364
- * @param {string} languagePath - Language path
365
- * @param {Object} spinner - Ora spinner instance
366
- * @param {Object} msg - Localized messages
367
- * @param {boolean} debugLog - Debug mode flag
368
- */
369
- async function downloadManifest(languagePath, spinner, msg, debugLog) {
370
- logWithSpinner(spinner, msg.downloading, debugLog);
371
- try {
372
- const manifestUrl = `${GITHUB_RAW_URL}/${GITHUB_CONTENT_PREFIX}/${languagePath}/.aiwf/00_PROJECT_MANIFEST.md`;
373
- await downloadFile(manifestUrl, FILES.PROJECT_MANIFEST);
374
- } catch (error) {
375
- // If manifest doesn't exist, that's okay
376
- }
377
- }
378
-
379
- /**
380
- * Download templates
381
- * @param {string} languagePath - Language path
382
- * @param {Object} spinner - Ora spinner instance
383
- * @param {Object} msg - Localized messages
384
- * @param {boolean} debugLog - Debug mode flag
385
- */
386
- async function downloadTemplates(languagePath, spinner, msg, debugLog) {
387
- try {
388
- logWithSpinner(spinner, msg.downloadingTemplates, debugLog);
389
-
390
- // .aiwf 전체 디렉토리λ₯Ό λ™μ μœΌλ‘œ λ‹€μš΄λ‘œλ“œ
391
- logWithSpinner(spinner, `Downloading .aiwf directory structure...`, debugLog);
392
- await downloadDirectory(
393
- `${GITHUB_CONTENT_PREFIX}/${languagePath}/.aiwf`,
394
- AIWF_DIRS.ROOT,
395
- spinner,
396
- msg,
397
- languagePath,
398
- true // useDynamicFetch = true
399
- );
400
-
401
- logWithSpinner(spinner, `Successfully downloaded .aiwf directory`, debugLog);
402
- } catch (error) {
403
- logWithSpinner(spinner, `Error downloading .aiwf: ${error.message}`, debugLog);
404
-
405
- // Fallback: κ°œλ³„ 디렉토리 λ‹€μš΄λ‘œλ“œ μ‹œλ„
406
- try {
407
- logWithSpinner(spinner, `Trying individual directory downloads...`, debugLog);
408
-
409
- await downloadDirectory(
410
- `${GITHUB_CONTENT_PREFIX}/${languagePath}/.aiwf/98_PROMPTS`,
411
- AIWF_DIRS.PROMPTS,
412
- spinner,
413
- msg,
414
- languagePath,
415
- true
416
- );
417
-
418
- await downloadDirectory(
419
- `${GITHUB_CONTENT_PREFIX}/${languagePath}/.aiwf/99_TEMPLATES`,
420
- AIWF_DIRS.TEMPLATES,
421
- spinner,
422
- msg,
423
- languagePath,
424
- true
425
- );
426
- } catch (fallbackError) {
427
- logWithSpinner(spinner, msg.templatesNotFound, debugLog);
428
- }
429
- }
430
- }
431
-
432
- /**
433
- * Update CLAUDE.md documentation files
434
- * @param {string} languagePath - Language path
435
- * @param {Object} spinner - Ora spinner instance
436
- * @param {Object} msg - Localized messages
437
- * @param {boolean} debugLog - Debug mode flag
438
- */
439
- async function updateDocumentation(languagePath, spinner, msg, debugLog) {
440
- logWithSpinner(spinner, msg.updatingDocs, debugLog);
441
- const claudeFiles = getAllClaudeMdFiles();
442
-
443
- for (const claudeFile of claudeFiles) {
444
- try {
445
- const relativePath = claudeFile.replace(process.cwd() + '/', '');
446
- const claudeUrl = `${GITHUB_RAW_URL}/${GITHUB_CONTENT_PREFIX}/${languagePath}/${relativePath}`;
447
- await downloadFile(claudeUrl, claudeFile);
448
- } catch (error) {
449
- // If CLAUDE.md doesn't exist, that's okay
450
- }
451
- }
452
- }
453
-
454
- /**
455
- * Update Claude commands and agents
456
- * @param {string} languagePath - Language path
457
- * @param {Object} spinner - Ora spinner instance
458
- * @param {Object} msg - Localized messages
459
- * @param {boolean} debugLog - Debug mode flag
460
- */
461
- async function updateCommands(languagePath, spinner, msg, debugLog) {
462
- // Delete existing commands folder if it exists
463
- if (await fs.access(TOOL_DIRS.CLAUDE_COMMANDS).then(() => true).catch(() => false)) {
464
- logWithSpinner(spinner, msg.deletingOldCommands, debugLog);
465
- await fs.rm(TOOL_DIRS.CLAUDE_COMMANDS, { recursive: true, force: true });
466
- }
467
-
468
- // Delete existing agents folder if it exists
469
- if (await fs.access(TOOL_DIRS.CLAUDE_AGENTS).then(() => true).catch(() => false)) {
470
- logWithSpinner(spinner, 'Deleting old agents...', debugLog);
471
- await fs.rm(TOOL_DIRS.CLAUDE_AGENTS, { recursive: true, force: true });
472
- }
473
-
474
- await fs.mkdir(TOOL_DIRS.CLAUDE_COMMANDS, { recursive: true });
475
- await fs.mkdir(TOOL_DIRS.CLAUDE_AGENTS, { recursive: true });
476
-
477
- // Download commands
478
- logWithSpinner(spinner, msg.downloadingCommands, debugLog);
479
- try {
480
- await downloadDirectory(
481
- `${GITHUB_CONTENT_PREFIX}/${languagePath}/${TOOL_DIRS.CLAUDE_COMMANDS}`,
482
- TOOL_DIRS.CLAUDE_COMMANDS,
483
- spinner,
484
- msg,
485
- languagePath,
486
- true // commands도 동적 디렉터리 탐색 μ‚¬μš© (파일 리슀트 의쑴 제거)
487
- );
488
- } catch (error) {
489
- logWithSpinner(spinner, msg.commandsNotFound, debugLog);
490
- }
491
-
492
- // Download agents
493
- logWithSpinner(spinner, 'Downloading agents...', debugLog);
494
- try {
495
- await downloadDirectory(
496
- `${GITHUB_CONTENT_PREFIX}/${languagePath}/${TOOL_DIRS.CLAUDE_AGENTS}`,
497
- TOOL_DIRS.CLAUDE_AGENTS,
498
- spinner,
499
- msg,
500
- languagePath,
501
- true // agents도 동적 디렉터리 탐색 μ‚¬μš© (파일 리슀트 의쑴 제거)
502
- );
503
- logWithSpinner(spinner, 'Successfully downloaded agents', debugLog);
504
- } catch (error) {
505
- logWithSpinner(spinner, 'Agents not found or failed to download', debugLog);
506
- }
507
-
508
- // Download full .claude directory to include tools, workflow, and any other subfolders
509
- logWithSpinner(spinner, 'Downloading full .claude directory (tools, workflow, etc.)...', debugLog);
510
- try {
511
- await downloadDirectory(
512
- `${GITHUB_CONTENT_PREFIX}/${languagePath}/.claude`,
513
- '.claude',
514
- spinner,
515
- msg,
516
- languagePath,
517
- true // 전체 .claude 폴더 동적 λ‹€μš΄λ‘œλ“œ
518
- );
519
- logWithSpinner(spinner, 'Successfully downloaded .claude directory', debugLog);
520
- } catch (error) {
521
- logWithSpinner(spinner, `Failed to download full .claude directory: ${error.message}`, debugLog);
522
- }
523
- }
524
-
525
- /**
526
- * Check if tool directories exist and handle them
527
- * @param {Object} spinner - Ora spinner instance
528
- * @param {Object} msg - Localized messages
529
- * @param {boolean} debugLog - Debug mode flag
530
- * @returns {Promise<Object>} Directory status info
531
- */
532
- async function checkAndHandleExistingToolDirs(spinner, msg, debugLog) {
533
- const toolDirStatus = {
534
- cursor: {
535
- exists: false,
536
- hadFiles: false,
537
- backedUp: false
538
- },
539
- windsurf: {
540
- exists: false,
541
- hadFiles: false,
542
- backedUp: false
543
- }
544
- };
545
-
546
- // Check Cursor directory
547
- try {
548
- await fs.access(TOOL_DIRS.CURSOR_RULES);
549
- toolDirStatus.cursor.exists = true;
550
-
551
- const cursorFiles = await fs.readdir(TOOL_DIRS.CURSOR_RULES);
552
- const mdcFiles = cursorFiles.filter(file => file.endsWith('.mdc'));
553
-
554
- if (mdcFiles.length > 0) {
555
- toolDirStatus.cursor.hadFiles = true;
556
- logWithSpinner(spinner, `${msg.foundExistingCursor} (${mdcFiles.length} files)`, debugLog);
557
-
558
- // Backup existing files
559
- logWithSpinner(spinner, msg.backingUpToolFiles, debugLog);
560
- const backupDir = path.join(TOOL_DIRS.CURSOR_RULES, `backup_${Date.now()}`);
561
- await fs.mkdir(backupDir, { recursive: true });
562
-
563
- for (const file of mdcFiles) {
564
- const srcPath = path.join(TOOL_DIRS.CURSOR_RULES, file);
565
- const backupPath = path.join(backupDir, file);
566
- await fs.copyFile(srcPath, backupPath);
567
- }
568
-
569
- toolDirStatus.cursor.backedUp = true;
570
- logWithSpinner(spinner, `${msg.toolBackupCreated}: ${backupDir}`, debugLog);
571
-
572
- // Remove existing files
573
- for (const file of mdcFiles) {
574
- await fs.unlink(path.join(TOOL_DIRS.CURSOR_RULES, file));
575
- }
576
- }
577
- } catch (error) {
578
- // Directory doesn't exist, that's fine
579
- logWithSpinner(spinner, `Cursor rules directory not found, will create new`, debugLog);
580
- }
581
-
582
- // Check Windsurf directory
583
- try {
584
- await fs.access(TOOL_DIRS.WINDSURF_RULES);
585
- toolDirStatus.windsurf.exists = true;
586
-
587
- const windsurfFiles = await fs.readdir(TOOL_DIRS.WINDSURF_RULES);
588
- const mdFiles = windsurfFiles.filter(file => file.endsWith('.md'));
589
-
590
- if (mdFiles.length > 0) {
591
- toolDirStatus.windsurf.hadFiles = true;
592
- logWithSpinner(spinner, `${msg.foundExistingWindsurf} (${mdFiles.length} files)`, debugLog);
593
-
594
- // Backup existing files
595
- logWithSpinner(spinner, msg.backingUpToolFiles, debugLog);
596
- const backupDir = path.join(TOOL_DIRS.WINDSURF_RULES, `backup_${Date.now()}`);
597
- await fs.mkdir(backupDir, { recursive: true });
598
-
599
- for (const file of mdFiles) {
600
- const srcPath = path.join(TOOL_DIRS.WINDSURF_RULES, file);
601
- const backupPath = path.join(backupDir, file);
602
- await fs.copyFile(srcPath, backupPath);
603
- }
604
-
605
- toolDirStatus.windsurf.backedUp = true;
606
- logWithSpinner(spinner, `${msg.toolBackupCreated}: ${backupDir}`, debugLog);
607
-
608
- // Remove existing files
609
- for (const file of mdFiles) {
610
- await fs.unlink(path.join(TOOL_DIRS.WINDSURF_RULES, file));
611
- }
612
- }
613
- } catch (error) {
614
- // Directory doesn't exist, that's fine
615
- logWithSpinner(spinner, `Windsurf rules directory not found, will create new`, debugLog);
616
- }
617
-
618
- return toolDirStatus;
619
- }
620
-
621
- /**
622
- * Download and process rules
623
- * @param {Object} spinner - Ora spinner instance
624
- * @param {Object} msg - Localized messages
625
- * @param {boolean} debugLog - Debug mode flag
626
- */
627
- async function downloadAndProcessRules(spinner, msg, debugLog) {
628
- // Check and handle existing tool directories first
629
- logWithSpinner(spinner, msg.checkingExistingTools, debugLog);
630
- const toolDirStatus = await checkAndHandleExistingToolDirs(spinner, msg, debugLog);
631
- // Try to download from GitHub first, fallback to local files
632
- const tmpRulesGlobal = path.join(os.tmpdir(), 'aiwf-rules-global');
633
- const tmpRulesManual = path.join(os.tmpdir(), 'aiwf-rules-manual');
634
-
635
- let useLocalGlobal = false;
636
- let useLocalManual = false;
637
-
638
- // Try to download rules/global from GitHub
639
- try {
640
- await downloadDirectory(
641
- `rules/global`,
642
- tmpRulesGlobal,
643
- spinner,
644
- debugLog
645
- );
646
- logWithSpinner(spinner, `Downloaded rules/global from GitHub`, debugLog);
647
- } catch (error) {
648
- logWithSpinner(spinner, `Failed to download rules/global from GitHub, trying local files`, debugLog);
649
- // Fallback to local files
650
- const localRulesGlobal = path.join(process.cwd(), 'rules/global');
651
- try {
652
- logWithSpinner(spinner, `Trying to access: ${localRulesGlobal}`, debugLog);
653
- await fs.access(localRulesGlobal);
654
- logWithSpinner(spinner, `Successfully accessed local rules/global`, debugLog);
655
- // Copy local files to temp directory
656
- await fs.mkdir(tmpRulesGlobal, { recursive: true });
657
- const files = await fs.readdir(localRulesGlobal);
658
- logWithSpinner(spinner, `Found ${files.length} files in rules/global: ${files.join(', ')}`, debugLog);
659
- for (const file of files) {
660
- const srcPath = path.join(localRulesGlobal, file);
661
- const destPath = path.join(tmpRulesGlobal, file);
662
- await fs.copyFile(srcPath, destPath);
663
- logWithSpinner(spinner, `Copied: ${file}`, debugLog);
664
- }
665
- useLocalGlobal = true;
666
- logWithSpinner(spinner, `Using local rules/global directory`, debugLog);
667
- } catch (localError) {
668
- logWithSpinner(spinner, `Local rules/global error: ${localError.message}`, debugLog);
669
- logWithSpinner(spinner, msg.rulesGlobalNotFound, debugLog);
670
- }
671
- }
672
-
673
- // Try to download rules/manual from GitHub
674
- try {
675
- await downloadDirectory(
676
- `rules/manual`,
677
- tmpRulesManual,
678
- spinner,
679
- debugLog
680
- );
681
- logWithSpinner(spinner, `Downloaded rules/manual from GitHub`, debugLog);
682
- } catch (error) {
683
- logWithSpinner(spinner, `Failed to download rules/manual from GitHub, trying local files`, debugLog);
684
- // Fallback to local files
685
- const localRulesManual = path.join(process.cwd(), 'rules/manual');
686
- try {
687
- await fs.access(localRulesManual);
688
- // Copy local files to temp directory
689
- await fs.mkdir(tmpRulesManual, { recursive: true });
690
- const files = await fs.readdir(localRulesManual);
691
- for (const file of files) {
692
- const srcPath = path.join(localRulesManual, file);
693
- const destPath = path.join(tmpRulesManual, file);
694
- await fs.copyFile(srcPath, destPath);
695
- }
696
- useLocalManual = true;
697
- logWithSpinner(spinner, `Using local rules/manual directory`, debugLog);
698
- } catch (localError) {
699
- logWithSpinner(spinner, msg.rulesManualNotFound, debugLog);
700
- }
701
- }
702
-
703
- // Process rules/global
704
- try {
705
- await fs.access(tmpRulesGlobal);
706
- await fs.mkdir(TOOL_DIRS.CURSOR_RULES, { recursive: true });
707
- await fs.mkdir(TOOL_DIRS.WINDSURF_RULES, { recursive: true });
708
- const files = await fs.readdir(tmpRulesGlobal);
709
- for (const file of files) {
710
- const srcPath = path.join(tmpRulesGlobal, file);
711
- const stat = await fs.stat(srcPath);
712
- if (!stat.isFile()) continue;
713
-
714
- // .cursor/rules: add .mdc extension and header
715
- const base = path.parse(file).name;
716
- const cursorTarget = path.join(TOOL_DIRS.CURSOR_RULES, base + '.mdc');
717
- const content = await fs.readFile(srcPath, 'utf8');
718
- const header = '---\ndescription: \nglobs: \nalwaysApply: true\n---\n';
719
- await fs.writeFile(cursorTarget, header + content, 'utf8');
720
- logWithSpinner(
721
- spinner,
722
- `[rules/global] ${file} -> ${TOOL_DIRS.CURSOR_RULES}/${base}.mdc`,
723
- debugLog
724
- );
725
-
726
- // .windsurf/rules: keep extension, no header
727
- const windsurfTarget = path.join(TOOL_DIRS.WINDSURF_RULES, file);
728
- const windsurfContent = await fs.readFile(srcPath, 'utf8');
729
- const windsurfHeader = '---\ntrigger: always_on\n---\n';
730
- await fs.writeFile(windsurfTarget, windsurfHeader + windsurfContent, 'utf8');
731
- logWithSpinner(
732
- spinner,
733
- `[rules/global] ${file} -> ${TOOL_DIRS.WINDSURF_RULES}/${file}`,
734
- debugLog
735
- );
736
- }
737
- // Clean up temp folder (only if not using local files)
738
- if (!useLocalGlobal) {
739
- await fs.rm(tmpRulesGlobal, { recursive: true, force: true });
740
- }
741
- } catch (error) {
742
- logWithSpinner(spinner, `No rules/global directory found`, debugLog);
743
- }
744
-
745
- // Process rules/manual
746
- try {
747
- await fs.access(tmpRulesManual);
748
- await fs.mkdir(TOOL_DIRS.CURSOR_RULES, { recursive: true });
749
- await fs.mkdir(TOOL_DIRS.WINDSURF_RULES, { recursive: true });
750
- const files = await fs.readdir(tmpRulesManual);
751
- for (const file of files) {
752
- const srcPath = path.join(tmpRulesManual, file);
753
- const stat = await fs.stat(srcPath);
754
- if (!stat.isFile()) continue;
755
-
756
- // .cursor/rules: add .mdc extension and header (alwaysApply: false)
757
- const base = path.parse(file).name;
758
- const cursorTarget = path.join(TOOL_DIRS.CURSOR_RULES, base + '.mdc');
759
- const content = await fs.readFile(srcPath, 'utf8');
760
- const header = '---\ndescription: \nglobs: \nalwaysApply: false\n---\n';
761
- await fs.writeFile(cursorTarget, header + content, 'utf8');
762
- logWithSpinner(
763
- spinner,
764
- `[rules/manual] ${file} -> ${TOOL_DIRS.CURSOR_RULES}/${base}.mdc`,
765
- debugLog
766
- );
767
-
768
- // .windsurf/rules: keep extension, no header
769
- const windsurfTarget = path.join(TOOL_DIRS.WINDSURF_RULES, file);
770
- const windsurfContent = await fs.readFile(srcPath, 'utf8');
771
- const windsurfHeader = '---\ntrigger: manual\n---\n';
772
- await fs.writeFile(windsurfTarget, windsurfHeader + windsurfContent, 'utf8');
773
- logWithSpinner(
774
- spinner,
775
- `[rules/manual] ${file} -> ${TOOL_DIRS.WINDSURF_RULES}/${file}`,
776
- debugLog
777
- );
778
- }
779
- // Clean up temp folder (only if not using local files)
780
- if (!useLocalManual) {
781
- await fs.rm(tmpRulesManual, { recursive: true, force: true });
782
- }
783
- } catch (error) {
784
- logWithSpinner(spinner, `No rules/manual directory found`, debugLog);
785
- }
786
-
787
- // Success message for tool rules installation
788
- logWithSpinner(spinner, msg.toolRulesInstalled, debugLog);
789
-
790
- // Display installation results for tool directories
791
- if (toolDirStatus.cursor.backedUp || toolDirStatus.windsurf.backedUp) {
792
- console.log(chalk.cyan(`\nπŸ“‚ Tool Directory Installation Results:`));
793
-
794
- if (toolDirStatus.cursor.backedUp) {
795
- console.log(chalk.yellow(` β€’ Cursor: Existing rules backed up and replaced`));
796
- } else if (toolDirStatus.cursor.exists) {
797
- console.log(chalk.green(` β€’ Cursor: Rules installed (directory was empty)`));
798
- } else {
799
- console.log(chalk.green(` β€’ Cursor: Rules installed (new directory)`));
800
- }
801
-
802
- if (toolDirStatus.windsurf.backedUp) {
803
- console.log(chalk.yellow(` β€’ Windsurf: Existing rules backed up and replaced`));
804
- } else if (toolDirStatus.windsurf.exists) {
805
- console.log(chalk.green(` β€’ Windsurf: Rules installed (directory was empty)`));
806
- } else {
807
- console.log(chalk.green(` β€’ Windsurf: Rules installed (new directory)`));
808
- }
809
- }
810
-
811
- return toolDirStatus;
812
- }
813
-
814
- /**
815
- * Display installation summary
816
- * @param {boolean} hasExisting - Has existing installation
817
- * @param {Object} msg - Localized messages
818
- */
819
- function displaySummary(hasExisting, msg) {
820
- if (hasExisting) {
821
- console.log(chalk.blue(`\n${msg.updateHistory}`));
822
- console.log(chalk.gray(` β€’ ${TOOL_DIRS.CLAUDE_COMMANDS}${msg.updatedCommands}`));
823
- console.log(chalk.gray(` β€’ ${msg.updatedDocs}`));
824
- console.log(chalk.green(`\n${msg.workPreserved}`));
825
- console.log(chalk.gray(` β€’ ${msg.allFilesPreserved}`));
826
- console.log(chalk.gray(` β€’ ${msg.backupCreated}`));
827
- } else {
828
- console.log(chalk.blue(`\n${msg.structureCreated}`));
829
- console.log(chalk.gray(` ${AIWF_DIRS.ROOT}/ - ${msg.aiwfRoot}`));
830
- console.log(chalk.gray(` ${TOOL_DIRS.CLAUDE_COMMANDS}/ - ${msg.claudeCommands}`));
831
-
832
- console.log(chalk.green(`\n${msg.nextSteps}`));
833
- console.log(chalk.white(` 1. ${msg.nextStep1}`));
834
- console.log(chalk.white(` 2. ${msg.nextStep2}`));
835
- console.log(chalk.white(` 3. ${msg.nextStep3}\n`));
836
-
837
- console.log(chalk.blue(`\n${msg.gettingStarted}`));
838
- console.log(chalk.gray(` 1. ${msg.startStep1}`));
839
- console.log(chalk.gray(` 2. ${msg.startStep2}`));
840
- console.log(chalk.gray(`\n${msg.checkDocs}`));
841
- }
842
- }
843
-
844
- /**
845
- * Offer reinstallation options
846
- * @param {Object} validationResults - Validation results
847
- * @param {string} language - Language code
848
- * @returns {Promise<string>} Selected action
849
- */
850
- async function offerReinstallationOptions(validationResults, language) {
851
- console.log(
852
- chalk.yellow(
853
- language === 'ko'
854
- ? '\n⚠️ 일뢀 μ„€μΉ˜κ°€ μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€. 무엇을 ν•˜μ‹œκ² μŠ΅λ‹ˆκΉŒ?'
855
- : '\n⚠️ Some installations failed. What would you like to do?'
856
- )
857
- );
858
-
859
- // List failed tools
860
- const failedTools = validationResults.failed.map(({ tool }) => tool);
861
-
862
- if (failedTools.length > 0) {
863
- console.log(
864
- chalk.red(
865
- language === 'ko'
866
- ? `μ‹€νŒ¨ν•œ 도ꡬ: ${failedTools.join(', ')}`
867
- : `Failed tools: ${failedTools.join(', ')}`
868
- )
869
- );
870
- }
871
-
872
- const response = await prompts({
873
- type: 'select',
874
- name: 'action',
875
- message:
876
- language === 'ko' ? 'μ–΄λ–€ μž‘μ—…μ„ μˆ˜ν–‰ν•˜μ‹œκ² μŠ΅λ‹ˆκΉŒ?' : 'What would you like to do?',
877
- choices: [
878
- {
879
- title: language === 'ko' ? '전체 μž¬μ„€μΉ˜' : 'Full reinstallation',
880
- value: 'reinstall'
881
- },
882
- {
883
- title: language === 'ko' ? 'μ‹€νŒ¨ν•œ λ„κ΅¬λ§Œ λ‘€λ°±' : 'Rollback failed tools only',
884
- value: 'rollback'
885
- },
886
- {
887
- title: language === 'ko' ? 'ν˜„μž¬ μƒνƒœ μœ μ§€' : 'Keep current state',
888
- value: 'keep'
889
- }
890
- ]
891
- });
892
-
893
- return response.action;
894
- }
895
-
896
- /**
897
- * Main installation function
898
- * @param {Object} options - Installation options
899
- */
900
- export async function installAIWF(options = {}) {
901
- const debugLog = options.debugLog || false;
902
-
903
- // Select language
904
- const selectedLanguage = await selectLanguage(options);
905
- const msg = getMessages(selectedLanguage);
906
-
907
- console.log(chalk.blue.bold(msg.welcome));
908
- console.log(chalk.gray(msg.description));
909
- console.log(chalk.gray(msg.optimized));
910
-
911
- // Set language path
912
- const languagePath = getInstallationLanguagePath(selectedLanguage);
913
- const GITHUB_CONTENT_LANGUAGE_PREFIX = `${GITHUB_CONTENT_PREFIX}/${languagePath}`;
914
-
915
- // Check existing installation
916
- const hasExisting = await checkExistingInstallation();
917
-
918
- let installDecision = { continue: true, installType: 'fresh', preserveProject: false };
919
- let projectBackupDir = null;
920
-
921
- if (hasExisting) {
922
-
923
- installDecision = await handleExistingInstallation(msg, options);
924
-
925
- if (!installDecision.continue) return;
926
-
927
- // If reinstalling and preserving project, backup project files
928
- if (installDecision.installType === 'reinstall' && installDecision.preserveProject) {
929
- const { hasProject, projectFiles } = await checkExistingProject();
930
- if (hasProject) {
931
- projectBackupDir = await backupProjectFiles(projectFiles, msg);
932
- }
933
- }
934
- }
935
-
936
- const spinner = ora(msg.fetching).start();
937
-
938
- try {
939
- // Create directory structure
940
- await createDirectoryStructure();
941
-
942
- // Download manifest (fresh installs only or complete reinstall)
943
- if (!hasExisting || installDecision.installType === 'reinstall') {
944
- await downloadManifest(languagePath, spinner, msg, debugLog);
945
- }
946
-
947
- // Download templates (fresh installs and complete reinstall only)
948
- if (!hasExisting || installDecision.installType === 'reinstall') {
949
- await downloadTemplates(languagePath, spinner, msg, debugLog);
950
- }
951
-
952
- // Update documentation (fresh installs and complete reinstall only)
953
- if (!hasExisting || installDecision.installType === 'reinstall') {
954
- await updateDocumentation(languagePath, spinner, msg, debugLog);
955
- }
956
-
957
- // Update commands
958
- await updateCommands(languagePath, spinner, msg, debugLog);
959
-
960
- // Download and process rules
961
- const toolDirStatus = await downloadAndProcessRules(spinner, msg, debugLog);
962
-
963
- // Restore project files if needed
964
- if (projectBackupDir) {
965
- await restoreProjectFiles(projectBackupDir, msg);
966
- }
967
-
968
- // Success
969
- if (hasExisting && installDecision.installType === 'update') {
970
- spinner.succeed(chalk.green(msg.updateSuccess));
971
- } else {
972
- spinner.succeed(chalk.green(msg.installSuccess));
973
- }
974
-
975
- // Display summary
976
- displaySummary(hasExisting, msg);
977
-
978
- // Run validation
979
- console.log(
980
- chalk.blue('\nπŸ” Installation Validation / μ„€μΉ˜ 검증을 μ‹œμž‘ν•©λ‹ˆλ‹€...')
981
- );
982
- const selectedTools = ['claude-code', 'cursor', 'windsurf'];
983
- const validationResults = await validateInstallation(
984
- selectedTools,
985
- selectedLanguage
986
- );
987
- displaySpecCompliantValidationResults(validationResults, selectedLanguage);
988
-
989
- // Handle partial failures
990
- if (validationResults.failed.length > 0) {
991
- const action = await offerReinstallationOptions(
992
- validationResults,
993
- selectedLanguage
994
- );
995
-
996
- if (action === 'reinstall') {
997
- console.log(
998
- chalk.blue('\nπŸ”„ μž¬μ„€μΉ˜λ₯Ό μ‹œμž‘ν•©λ‹ˆλ‹€... / Starting reinstallation...')
999
- );
1000
- // Retry installation once
1001
- if (!options.isRetry) {
1002
- return await installAIWF({ ...options, isRetry: true });
1003
- }
1004
- } else if (action === 'rollback') {
1005
- console.log(
1006
- chalk.blue('\n↩️ μ‹€νŒ¨ν•œ 도ꡬλ₯Ό λ‘€λ°±ν•©λ‹ˆλ‹€... / Rolling back failed tools...')
1007
- );
1008
-
1009
- // Rollback failed tools
1010
- const failedTools = validationResults.failed.map(({ tool }) => tool);
1011
- const backupDir = getCurrentBackupDir();
1012
- let rollbackResults = {};
1013
-
1014
- for (const tool of failedTools) {
1015
- if (backupDir) {
1016
- const rollbackResult = await rollbackTool(
1017
- tool,
1018
- backupDir,
1019
- selectedLanguage
1020
- );
1021
- rollbackResults[tool] = rollbackResult;
1022
- }
1023
- }
1024
-
1025
- // Re-validate after rollback
1026
- console.log(
1027
- chalk.blue('\nπŸ” λ‘€λ°± ν›„ μž¬κ²€μ¦... / Re-validating after rollback...')
1028
- );
1029
- const postRollbackValidation = await validateInstallation(
1030
- selectedTools,
1031
- selectedLanguage
1032
- );
1033
- displaySpecCompliantValidationResults(
1034
- postRollbackValidation,
1035
- selectedLanguage
1036
- );
1037
-
1038
- // Rollback summary
1039
- console.log(chalk.blue('\n=== Rollback Summary / λ‘€λ°± μš”μ•½ ==='));
1040
- for (const [tool, result] of Object.entries(rollbackResults)) {
1041
- if (result.success) {
1042
- console.log(
1043
- chalk.green(`βœ… ${tool}: ${result.restoredCount} files restored`)
1044
- );
1045
- } else {
1046
- console.log(chalk.red(`❌ ${tool}: ${result.error}`));
1047
- }
1048
- }
1049
- }
1050
- }
1051
-
1052
- console.log(chalk.green(msg.enjoy));
1053
- } catch (error) {
1054
- if (hasExisting) {
1055
- spinner.fail(chalk.red(msg.updateFailed));
1056
- await restoreFromBackup(spinner, msg);
1057
- } else {
1058
- spinner.fail(chalk.red(msg.installFailed));
1059
- }
1060
- console.error(chalk.red(error.message));
1061
- process.exit(1);
1062
- }
1063
-
1064
- // Create installation flag file
1065
- await fs.writeFile(FILES.INSTALLED_FLAG, 'installed', 'utf8');
1066
- }