aiwf 0.3.22 โ†’ 0.3.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/package.json +3 -2
  2. package/src/cli/index.js +39 -336
  3. package/src/lib/installer.js +294 -90
  4. package/src/utils/messages.js +24 -0
  5. package/src/DEPENDENCY_MAP.md +0 -90
  6. package/src/cli/cache-cli.js +0 -459
  7. package/src/cli/checkpoint-cli.js +0 -417
  8. package/src/cli/language-cli.js +0 -286
  9. package/src/cli/sprint-cli.js +0 -287
  10. package/src/commands/ai-tool.js +0 -383
  11. package/src/commands/compress.js +0 -60
  12. package/src/commands/create-project.js +0 -160
  13. package/src/commands/evaluate.js +0 -459
  14. package/src/commands/persona.js +0 -309
  15. package/src/commands/sprint-task.js +0 -262
  16. package/src/commands/token.js +0 -312
  17. package/src/lib/ai-persona-manager.js +0 -711
  18. package/src/lib/cache-system.js +0 -332
  19. package/src/lib/context-engine.js +0 -568
  20. package/src/lib/github-integration.js +0 -402
  21. package/src/lib/memory-profiler.js +0 -471
  22. package/src/lib/metrics-collector.js +0 -885
  23. package/src/lib/offline-detector.js +0 -386
  24. package/src/lib/resource-loader-enhanced.js +0 -399
  25. package/src/lib/resource-loader.js +0 -250
  26. package/src/lib/resources/commands/ai-persona.js +0 -602
  27. package/src/lib/resources/commands/compress-context.js +0 -389
  28. package/src/lib/resources/commands/evaluate.js +0 -246
  29. package/src/lib/resources/commands/persona-context-apply.js +0 -562
  30. package/src/lib/resources/commands/token-tracking.js +0 -443
  31. package/src/lib/resources/config/commit-patterns.js +0 -103
  32. package/src/lib/resources/config/language.json +0 -6
  33. package/src/lib/resources/personas/PERSONA_INDEX.md +0 -57
  34. package/src/lib/resources/personas/analyst.json +0 -44
  35. package/src/lib/resources/personas/architect/best_practices.md +0 -136
  36. package/src/lib/resources/personas/architect/knowledge_base.md +0 -377
  37. package/src/lib/resources/personas/architect.json +0 -44
  38. package/src/lib/resources/personas/backend/best_practices.md +0 -766
  39. package/src/lib/resources/personas/backend/knowledge_base.md +0 -1070
  40. package/src/lib/resources/personas/data_analyst/best_practices.md +0 -594
  41. package/src/lib/resources/personas/data_analyst/knowledge_base.md +0 -1057
  42. package/src/lib/resources/personas/developer.json +0 -44
  43. package/src/lib/resources/personas/developer.md +0 -37
  44. package/src/lib/resources/personas/evaluation_criteria.json +0 -137
  45. package/src/lib/resources/personas/frontend/best_practices.md +0 -445
  46. package/src/lib/resources/personas/frontend/knowledge_base.md +0 -729
  47. package/src/lib/resources/personas/persona-index.json +0 -31
  48. package/src/lib/resources/personas/reviewer.json +0 -44
  49. package/src/lib/resources/personas/security/best_practices.md +0 -307
  50. package/src/lib/resources/personas/security/knowledge_base.md +0 -498
  51. package/src/lib/resources/personas/tester.json +0 -44
  52. package/src/lib/resources/templates/README.md +0 -78
  53. package/src/lib/resources/templates/api-server/config.json +0 -64
  54. package/src/lib/resources/templates/api-server/template/.aiwf/config.json +0 -56
  55. package/src/lib/resources/templates/api-server/template/.aiwf/feature-ledger.json +0 -42
  56. package/src/lib/resources/templates/api-server/template/.aiwf/personas/backend-engineer.json +0 -40
  57. package/src/lib/resources/templates/api-server/template/.aiwf/scripts/cli.js +0 -111
  58. package/src/lib/resources/templates/api-server/template/.env.example +0 -29
  59. package/src/lib/resources/templates/api-server/template/.eslintrc.json +0 -23
  60. package/src/lib/resources/templates/api-server/template/README.md +0 -171
  61. package/src/lib/resources/templates/api-server/template/jest.config.js +0 -26
  62. package/src/lib/resources/templates/api-server/template/nodemon.json +0 -9
  63. package/src/lib/resources/templates/api-server/template/package.json +0 -61
  64. package/src/lib/resources/templates/api-server/template/src/app.ts +0 -60
  65. package/src/lib/resources/templates/api-server/template/src/config/swagger.ts +0 -38
  66. package/src/lib/resources/templates/api-server/template/src/controllers/aiwfController.ts +0 -54
  67. package/src/lib/resources/templates/api-server/template/src/controllers/authController.ts +0 -128
  68. package/src/lib/resources/templates/api-server/template/src/controllers/statusController.ts +0 -28
  69. package/src/lib/resources/templates/api-server/template/src/index.ts +0 -28
  70. package/src/lib/resources/templates/api-server/template/src/middleware/aiwfMiddleware.ts +0 -50
  71. package/src/lib/resources/templates/api-server/template/src/middleware/authMiddleware.ts +0 -41
  72. package/src/lib/resources/templates/api-server/template/src/middleware/errorHandler.ts +0 -42
  73. package/src/lib/resources/templates/api-server/template/src/middleware/notFoundHandler.ts +0 -14
  74. package/src/lib/resources/templates/api-server/template/src/middleware/requestLogger.ts +0 -20
  75. package/src/lib/resources/templates/api-server/template/src/routes/aiwf.ts +0 -31
  76. package/src/lib/resources/templates/api-server/template/src/routes/index.ts +0 -13
  77. package/src/lib/resources/templates/api-server/template/src/routes/v1/index.ts +0 -67
  78. package/src/lib/resources/templates/api-server/template/src/utils/logger.ts +0 -37
  79. package/src/lib/resources/templates/api-server/template/tests/app.test.ts +0 -40
  80. package/src/lib/resources/templates/api-server/template/tsconfig.json +0 -43
  81. package/src/lib/resources/templates/npm-library/config.json +0 -61
  82. package/src/lib/resources/templates/npm-library/template/LICENSE +0 -21
  83. package/src/lib/resources/templates/npm-library/template/README.md +0 -201
  84. package/src/lib/resources/templates/npm-library/template/package.json +0 -78
  85. package/src/lib/resources/templates/web-app/config.json +0 -53
  86. package/src/lib/resources/templates/web-app/template/.aiwf/config.json +0 -54
  87. package/src/lib/resources/templates/web-app/template/.aiwf/feature-ledger.json +0 -37
  88. package/src/lib/resources/templates/web-app/template/.aiwf/personas/fullstack-developer.json +0 -40
  89. package/src/lib/resources/templates/web-app/template/.aiwf/scripts/cli.js +0 -110
  90. package/src/lib/resources/templates/web-app/template/.eslintrc.cjs +0 -20
  91. package/src/lib/resources/templates/web-app/template/README.md +0 -151
  92. package/src/lib/resources/templates/web-app/template/index.html +0 -14
  93. package/src/lib/resources/templates/web-app/template/package.json +0 -44
  94. package/src/lib/resources/templates/web-app/template/postcss.config.js +0 -6
  95. package/src/lib/resources/templates/web-app/template/public/vite.svg +0 -1
  96. package/src/lib/resources/templates/web-app/template/src/App.tsx +0 -21
  97. package/src/lib/resources/templates/web-app/template/src/components/Layout.tsx +0 -57
  98. package/src/lib/resources/templates/web-app/template/src/components/aiwf/ContextStatus.tsx +0 -107
  99. package/src/lib/resources/templates/web-app/template/src/components/aiwf/TokenUsage.tsx +0 -71
  100. package/src/lib/resources/templates/web-app/template/src/index.css +0 -60
  101. package/src/lib/resources/templates/web-app/template/src/main.tsx +0 -10
  102. package/src/lib/resources/templates/web-app/template/src/pages/AiwfDashboard.tsx +0 -57
  103. package/src/lib/resources/templates/web-app/template/src/pages/HomePage.tsx +0 -89
  104. package/src/lib/resources/templates/web-app/template/src/pages/NotFound.tsx +0 -25
  105. package/src/lib/resources/templates/web-app/template/src/stores/aiwfStore.ts +0 -126
  106. package/src/lib/resources/templates/web-app/template/src/types/global.d.ts +0 -9
  107. package/src/lib/resources/templates/web-app/template/src/vite-env.d.ts +0 -1
  108. package/src/lib/resources/templates/web-app/template/tailwind.config.js +0 -30
  109. package/src/lib/resources/templates/web-app/template/tsconfig.json +0 -37
  110. package/src/lib/resources/templates/web-app/template/tsconfig.node.json +0 -10
  111. package/src/lib/resources/templates/web-app/template/vite.config.ts +0 -23
  112. package/src/lib/resources/utils/background-monitor.js +0 -223
  113. package/src/lib/resources/utils/compression-metrics.js +0 -1031
  114. package/src/lib/resources/utils/compression-strategies.js +0 -557
  115. package/src/lib/resources/utils/content-normalizer.js +0 -455
  116. package/src/lib/resources/utils/context-compressor.js +0 -583
  117. package/src/lib/resources/utils/context-rule-parser.js +0 -180
  118. package/src/lib/resources/utils/context-token-monitor.js +0 -463
  119. package/src/lib/resources/utils/context-update-manager.js +0 -502
  120. package/src/lib/resources/utils/git-utils.js +0 -220
  121. package/src/lib/resources/utils/importance-classifier.js +0 -645
  122. package/src/lib/resources/utils/information-filter.js +0 -710
  123. package/src/lib/resources/utils/persona-aware-compressor.js +0 -598
  124. package/src/lib/resources/utils/prompt-injector.js +0 -242
  125. package/src/lib/resources/utils/simplified-evaluator.js +0 -119
  126. package/src/lib/resources/utils/text-summarizer.js +0 -492
  127. package/src/lib/resources/utils/token-counter.js +0 -177
  128. package/src/lib/resources/utils/token-monitor.js +0 -484
  129. package/src/lib/resources/utils/token-reporter.js +0 -452
  130. package/src/lib/resources/utils/token-storage.js +0 -433
  131. package/src/lib/resources/utils/token-tracker.js +0 -283
  132. package/src/lib/state/priority-calculator.js +0 -217
  133. package/src/lib/state/state-index.js +0 -155
  134. package/src/lib/state/task-scanner.js +0 -328
  135. package/src/lib/task-analyzer.js +0 -599
  136. package/src/lib/template-cache-system.js +0 -559
  137. package/src/lib/template-downloader.js +0 -467
  138. package/src/lib/template-version-manager.js +0 -491
  139. package/src/lib/token-optimizer.js +0 -517
  140. package/src/utils/engineering-guard.js +0 -399
@@ -893,6 +893,221 @@ async function offerReinstallationOptions(validationResults, language) {
893
893
  return response.action;
894
894
  }
895
895
 
896
+ /**
897
+ * ์‚ฌ์šฉ์ž ์„ค์น˜ ์˜ต์…˜ ์„ ํƒ
898
+ * @param {Object} msg - ์ง€์—ญํ™”๋œ ๋ฉ”์‹œ์ง€
899
+ * @returns {Promise<Array>} ์„ ํƒ๋œ ์„ค์น˜ ์˜ต์…˜ ๋ชฉ๋ก
900
+ */
901
+ async function selectInstallationOptions(msg) {
902
+ console.log(chalk.cyan(`\n${msg.installationOptions}`));
903
+
904
+ const installOptions = [
905
+ {
906
+ title: msg.aiwfDocs,
907
+ value: 'aiwf-docs',
908
+ description: 'AIWF ๋ฌธ์„œ ํด๋”'
909
+ },
910
+ {
911
+ title: msg.claudeCodeCommands,
912
+ value: 'claude-code-commands',
913
+ description: 'Claude Code ๋ช…๋ น์–ด ๋ฐ ์—์ด์ „ํŠธ'
914
+ },
915
+ {
916
+ title: msg.windsurfRules,
917
+ value: 'windsurf-rules',
918
+ description: 'Windsurf ๊ทœ์น™ ํŒŒ์ผ'
919
+ },
920
+ {
921
+ title: msg.cursorRules,
922
+ value: 'cursor-rules',
923
+ description: 'Cursor ๊ทœ์น™ ํŒŒ์ผ'
924
+ }
925
+ ];
926
+
927
+ // 1๋‹จ๊ณ„: ์ „์ฒด ์„ค์น˜ vs ๊ฐœ๋ณ„ ์„ ํƒ
928
+ const installTypeResponse = await prompts({
929
+ type: 'select',
930
+ name: 'installType',
931
+ message: msg.installationOptions || '์„ค์น˜ ์˜ต์…˜์„ ์„ ํƒํ•˜์„ธ์š”:',
932
+ choices: [
933
+ {
934
+ title: msg.selectAll || 'โœ… ๋ชจ๋“  ํ•ญ๋ชฉ ์„ค์น˜ (๊ถŒ์žฅ)',
935
+ value: 'all',
936
+ description: '๋ชจ๋“  AIWF ์ปดํฌ๋„ŒํŠธ๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค'
937
+ },
938
+ {
939
+ title: '๐ŸŽฏ ๊ฐœ๋ณ„ ํ•ญ๋ชฉ ์„ ํƒ',
940
+ value: 'custom',
941
+ description: '์›ํ•˜๋Š” ํ•ญ๋ชฉ๋งŒ ์„ ํƒํ•˜์—ฌ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค'
942
+ }
943
+ ]
944
+ });
945
+
946
+ // ์ทจ์†Œ๋œ ๊ฒฝ์šฐ
947
+ if (!installTypeResponse.installType) {
948
+ console.log(chalk.yellow(msg.noOptionsSelected || '์„ค์น˜๊ฐ€ ์ทจ์†Œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.'));
949
+ process.exit(0);
950
+ }
951
+
952
+ // ์ „์ฒด ์„ค์น˜ ์„ ํƒ
953
+ if (installTypeResponse.installType === 'all') {
954
+ return installOptions.map(opt => opt.value);
955
+ }
956
+
957
+ // 2๋‹จ๊ณ„: ๊ฐœ๋ณ„ ํ•ญ๋ชฉ ์„ ํƒ
958
+ const customResponse = await prompts({
959
+ type: 'multiselect',
960
+ name: 'selectedOptions',
961
+ message: '์„ค์น˜ํ•  ํ•ญ๋ชฉ์„ ์„ ํƒํ•˜์„ธ์š” (์ŠคํŽ˜์ด์Šค๋กœ ์„ ํƒ/ํ•ด์ œ, ์—”ํ„ฐ๋กœ ํ™•์ธ):',
962
+ choices: installOptions,
963
+ hint: 'โ†‘โ†“ ์ด๋™, ์ŠคํŽ˜์ด์Šค ์„ ํƒ/ํ•ด์ œ, ์—”ํ„ฐ ํ™•์ธ',
964
+ instructions: false
965
+ });
966
+
967
+ // ์ทจ์†Œ๋˜๊ฑฐ๋‚˜ ์•„๋ฌด๊ฒƒ๋„ ์„ ํƒํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
968
+ if (!customResponse.selectedOptions || customResponse.selectedOptions.length === 0) {
969
+ console.log(chalk.yellow(msg.noOptionsSelected || '์„ ํƒ๋œ ํ•ญ๋ชฉ์ด ์—†์Šต๋‹ˆ๋‹ค.'));
970
+ process.exit(0);
971
+ }
972
+
973
+ return customResponse.selectedOptions;
974
+ }
975
+
976
+ /**
977
+ * ์„ ํƒ๋œ ์˜ต์…˜๋ณ„ ์„ค์น˜ ์‹คํ–‰
978
+ * @param {Array} selectedOptions - ์„ ํƒ๋œ ์„ค์น˜ ์˜ต์…˜๋“ค
979
+ * @param {string} languagePath - ์–ธ์–ด ๊ฒฝ๋กœ
980
+ * @param {Object} msg - ์ง€์—ญํ™”๋œ ๋ฉ”์‹œ์ง€
981
+ * @param {boolean} debugLog - ๋””๋ฒ„๊ทธ ๋กœ๊ทธ ์—ฌ๋ถ€
982
+ */
983
+ async function installSelectedOptions(selectedOptions, languagePath, msg, debugLog) {
984
+ for (const option of selectedOptions) {
985
+ const spinner = ora(`${msg.installingOption}${option}...`).start();
986
+
987
+ try {
988
+ switch (option) {
989
+ case 'aiwf-docs':
990
+ await installAIWFDocs(languagePath, debugLog);
991
+ break;
992
+ case 'claude-code-commands':
993
+ await installClaudeCodeCommands(languagePath, debugLog);
994
+ break;
995
+ case 'windsurf-rules':
996
+ await installWindsurfRules(debugLog);
997
+ break;
998
+ case 'cursor-rules':
999
+ await installCursorRules(debugLog);
1000
+ break;
1001
+ default:
1002
+ spinner.warn(`Unknown option: ${option}`);
1003
+ continue;
1004
+ }
1005
+
1006
+ spinner.succeed(`${msg.optionInstalled}${option}`);
1007
+ } catch (error) {
1008
+ spinner.fail(`Failed to install ${option}: ${error.message}`);
1009
+ if (debugLog) {
1010
+ console.error(error);
1011
+ }
1012
+ }
1013
+ }
1014
+ }
1015
+
1016
+ /**
1017
+ * AIWF ๋ฌธ์„œ ์„ค์น˜
1018
+ */
1019
+ async function installAIWFDocs(languagePath, debugLog) {
1020
+ await createDirectoryStructure();
1021
+ const spinner = ora('Downloading AIWF files...').start();
1022
+ const msg = {
1023
+ downloading: 'Downloading AIWF documentation...',
1024
+ downloadingTemplates: 'Downloading templates...',
1025
+ templatesNotFound: 'Templates not found'
1026
+ };
1027
+
1028
+ try {
1029
+ // ๋งค๋‹ˆํŽ˜์ŠคํŠธ ๋‹ค์šด๋กœ๋“œ
1030
+ await downloadManifest(languagePath, spinner, msg, debugLog);
1031
+
1032
+ // ์ „์ฒด .aiwf ๋””๋ ‰ํ† ๋ฆฌ ๋‹ค์šด๋กœ๋“œ
1033
+ await downloadTemplates(languagePath, spinner, msg, debugLog);
1034
+
1035
+ spinner.succeed('AIWF documentation installed successfully');
1036
+ } catch (error) {
1037
+ spinner.fail('Failed to install AIWF documentation');
1038
+ if (debugLog) {
1039
+ console.error(error);
1040
+ }
1041
+ throw error;
1042
+ }
1043
+ }
1044
+
1045
+ /**
1046
+ * Claude Code ๋ช…๋ น์–ด ์„ค์น˜
1047
+ */
1048
+ async function installClaudeCodeCommands(languagePath, debugLog) {
1049
+ const GITHUB_CONTENT_LANGUAGE_PREFIX = `${GITHUB_CONTENT_PREFIX}/${languagePath}`;
1050
+ const dummySpinner = null;
1051
+ const dummyMsg = { downloadingCommands: 'Downloading Claude Code commands...' };
1052
+ await updateCommands(languagePath, dummySpinner, dummyMsg, debugLog);
1053
+ }
1054
+
1055
+ /**
1056
+ * Windsurf ๊ทœ์น™ ์„ค์น˜
1057
+ */
1058
+ async function installWindsurfRules(debugLog) {
1059
+ const spinner = ora('Installing Windsurf rules...').start();
1060
+ const msg = {
1061
+ checkingExistingTools: 'Checking existing tools...',
1062
+ foundExistingCursor: 'Found existing Cursor rules',
1063
+ foundExistingWindsurf: 'Found existing Windsurf rules',
1064
+ backingUpToolFiles: 'Backing up tool files...',
1065
+ toolBackupCreated: 'Tool backup created',
1066
+ rulesGlobalNotFound: 'Rules global not found',
1067
+ rulesManualNotFound: 'Rules manual not found',
1068
+ toolRulesInstalled: 'Tool rules installed successfully'
1069
+ };
1070
+
1071
+ try {
1072
+ await downloadAndProcessRules(spinner, msg, debugLog);
1073
+ spinner.succeed('Windsurf rules installed successfully');
1074
+ } catch (error) {
1075
+ spinner.fail('Failed to install Windsurf rules');
1076
+ if (debugLog) {
1077
+ console.error(error);
1078
+ }
1079
+ throw error;
1080
+ }
1081
+ }
1082
+
1083
+ /**
1084
+ * Cursor ๊ทœ์น™ ์„ค์น˜
1085
+ */
1086
+ async function installCursorRules(debugLog) {
1087
+ const spinner = ora('Installing Cursor rules...').start();
1088
+ const msg = {
1089
+ checkingExistingTools: 'Checking existing tools...',
1090
+ foundExistingCursor: 'Found existing Cursor rules',
1091
+ foundExistingWindsurf: 'Found existing Windsurf rules',
1092
+ backingUpToolFiles: 'Backing up tool files...',
1093
+ toolBackupCreated: 'Tool backup created',
1094
+ rulesGlobalNotFound: 'Rules global not found',
1095
+ rulesManualNotFound: 'Rules manual not found',
1096
+ toolRulesInstalled: 'Tool rules installed successfully'
1097
+ };
1098
+
1099
+ try {
1100
+ await downloadAndProcessRules(spinner, msg, debugLog);
1101
+ spinner.succeed('Cursor rules installed successfully');
1102
+ } catch (error) {
1103
+ spinner.fail('Failed to install Cursor rules');
1104
+ if (debugLog) {
1105
+ console.error(error);
1106
+ }
1107
+ throw error;
1108
+ }
1109
+ }
1110
+
896
1111
  /**
897
1112
  * Main installation function
898
1113
  * @param {Object} options - Installation options
@@ -910,7 +1125,6 @@ export async function installAIWF(options = {}) {
910
1125
 
911
1126
  // Set language path
912
1127
  const languagePath = getInstallationLanguagePath(selectedLanguage);
913
- const GITHUB_CONTENT_LANGUAGE_PREFIX = `${GITHUB_CONTENT_PREFIX}/${languagePath}`;
914
1128
 
915
1129
  // Check existing installation
916
1130
  const hasExisting = await checkExistingInstallation();
@@ -919,11 +1133,9 @@ export async function installAIWF(options = {}) {
919
1133
  let projectBackupDir = null;
920
1134
 
921
1135
  if (hasExisting) {
922
-
923
1136
  installDecision = await handleExistingInstallation(msg, options);
924
-
925
1137
  if (!installDecision.continue) return;
926
-
1138
+
927
1139
  // If reinstalling and preserving project, backup project files
928
1140
  if (installDecision.installType === 'reinstall' && installDecision.preserveProject) {
929
1141
  const { hasProject, projectFiles } = await checkExistingProject();
@@ -933,120 +1145,112 @@ export async function installAIWF(options = {}) {
933
1145
  }
934
1146
  }
935
1147
 
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
- }
1148
+ // ์„ค์น˜ ์˜ต์…˜ ์„ ํƒ
1149
+ let selectedOptions = ['aiwf-docs', 'claude-code-commands', 'windsurf-rules', 'cursor-rules'];
1150
+
1151
+ if (options.preselectedOptions) {
1152
+ // CLI์—์„œ ๋ฏธ๋ฆฌ ์„ ํƒ๋œ ์˜ต์…˜๋“ค์„ ์‚ฌ์šฉ
1153
+ selectedOptions = options.preselectedOptions;
1154
+ } else if (!options.force && !options.interactive) {
1155
+ // ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” ๋Œ€ํ™”ํ˜• ์„ ํƒ์„ ์‚ฌ์šฉ
1156
+ selectedOptions = await selectInstallationOptions(msg);
1157
+ } else if (options.interactive) {
1158
+ // --interactive ํ”Œ๋ž˜๊ทธ๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •๋œ ๊ฒฝ์šฐ
1159
+ selectedOptions = await selectInstallationOptions(msg);
1160
+ }
956
1161
 
957
- // Update commands
958
- await updateCommands(languagePath, spinner, msg, debugLog);
1162
+ console.log(chalk.blue(`\n์„ค์น˜ํ•  ์˜ต์…˜: ${selectedOptions.join(', ')}`));
959
1163
 
960
- // Download and process rules
961
- const toolDirStatus = await downloadAndProcessRules(spinner, msg, debugLog);
1164
+ try {
1165
+ // ์„ ํƒ๋œ ์˜ต์…˜๋“ค์„ ์„ค์น˜
1166
+ await installSelectedOptions(selectedOptions, languagePath, msg, debugLog);
962
1167
 
963
1168
  // Restore project files if needed
964
1169
  if (projectBackupDir) {
965
1170
  await restoreProjectFiles(projectBackupDir, msg);
966
1171
  }
967
1172
 
968
- // Success
1173
+ // Success message
969
1174
  if (hasExisting && installDecision.installType === 'update') {
970
- spinner.succeed(chalk.green(msg.updateSuccess));
1175
+ console.log(chalk.green(`\nโœ… ${msg.updateSuccess}`));
971
1176
  } else {
972
- spinner.succeed(chalk.green(msg.installSuccess));
1177
+ console.log(chalk.green(`\nโœ… ${msg.installSuccess}`));
973
1178
  }
974
1179
 
975
1180
  // Display summary
976
1181
  displaySummary(hasExisting, msg);
977
1182
 
978
- // Run validation
1183
+ // Run validation based on selected options
979
1184
  console.log(
980
1185
  chalk.blue('\n๐Ÿ” Installation Validation / ์„ค์น˜ ๊ฒ€์ฆ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค...')
981
1186
  );
982
- const selectedTools = ['claude-code', 'cursor', 'windsurf'];
983
- const validationResults = await validateInstallation(
984
- selectedTools,
985
- selectedLanguage
986
- );
987
- displaySpecCompliantValidationResults(validationResults, selectedLanguage);
988
1187
 
989
- // Handle partial failures
990
- if (validationResults.failed.length > 0) {
991
- const action = await offerReinstallationOptions(
992
- validationResults,
1188
+ // Map selected options to validation tools
1189
+ const validationTools = [];
1190
+ if (selectedOptions.includes('claude-code-commands')) {
1191
+ validationTools.push('claude-code');
1192
+ }
1193
+ if (selectedOptions.includes('cursor-rules')) {
1194
+ validationTools.push('cursor');
1195
+ }
1196
+ if (selectedOptions.includes('windsurf-rules')) {
1197
+ validationTools.push('windsurf');
1198
+ }
1199
+
1200
+ if (validationTools.length > 0) {
1201
+ const validationResults = await validateInstallation(
1202
+ validationTools,
993
1203
  selectedLanguage
994
1204
  );
1205
+ displaySpecCompliantValidationResults(validationResults, selectedLanguage);
995
1206
 
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,
1207
+ // Handle partial failures
1208
+ if (validationResults.failed.length > 0) {
1209
+ const action = await offerReinstallationOptions(
1210
+ validationResults,
1035
1211
  selectedLanguage
1036
1212
  );
1037
1213
 
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}`));
1214
+ if (action === 'reinstall') {
1215
+ console.log(
1216
+ chalk.blue('\n๐Ÿ”„ ์žฌ์„ค์น˜๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค... / Starting reinstallation...')
1217
+ );
1218
+ // Retry installation once
1219
+ if (!options.isRetry) {
1220
+ return await installAIWF({ ...options, isRetry: true });
1047
1221
  }
1222
+ } else if (action === 'rollback') {
1223
+ console.log(
1224
+ chalk.blue('\nโ†ฉ๏ธ ์‹คํŒจํ•œ ๋„๊ตฌ๋ฅผ ๋กค๋ฐฑํ•ฉ๋‹ˆ๋‹ค... / Rolling back failed tools...')
1225
+ );
1226
+
1227
+ // Rollback failed tools
1228
+ const failedTools = validationResults.failed.map(({ tool }) => tool);
1229
+ const backupDir = getCurrentBackupDir();
1230
+
1231
+ for (const tool of failedTools) {
1232
+ if (backupDir) {
1233
+ await rollbackTool(
1234
+ tool,
1235
+ backupDir,
1236
+ selectedLanguage
1237
+ );
1238
+ }
1239
+ }
1240
+
1241
+ // Re-validate after rollback
1242
+ console.log(
1243
+ chalk.blue('\n๐Ÿ” ๋กค๋ฐฑ ํ›„ ์žฌ๊ฒ€์ฆ... / Re-validating after rollback...')
1244
+ );
1245
+ const postRollbackValidation = await validateInstallation(
1246
+ validationTools,
1247
+ selectedLanguage
1248
+ );
1249
+ displaySpecCompliantValidationResults(postRollbackValidation, selectedLanguage);
1048
1250
  }
1049
1251
  }
1252
+ } else {
1253
+ console.log(chalk.yellow('\nโš ๏ธ ๊ฒ€์ฆํ•  ๋„๊ตฌ๊ฐ€ ์„ ํƒ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.'));
1050
1254
  }
1051
1255
 
1052
1256
  console.log(chalk.green(msg.enjoy));
@@ -77,6 +77,18 @@ export const messages = {
77
77
  toolBackupCreated: '๋„๊ตฌ ํŒŒ์ผ ๋ฐฑ์—…์ด ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค',
78
78
  installingToolRules: '๋„๊ตฌ ๊ทœ์น™์„ ์„ค์น˜ํ•˜๋Š” ์ค‘...',
79
79
  toolRulesInstalled: '๋„๊ตฌ ๊ทœ์น™์ด ์„ฑ๊ณต์ ์œผ๋กœ ์„ค์น˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค',
80
+
81
+ // ์„ค์น˜ ์˜ต์…˜ ๊ด€๋ จ
82
+ installationOptions: 'AIWF ์„ค์น˜ ์˜ต์…˜์„ ์„ ํƒํ•˜์„ธ์š”:',
83
+ aiwfDocs: 'AIWF ๋ฌธ์„œ ํด๋” (.aiwf/docs)',
84
+ claudeCodeCommands: 'Claude Code ๋ช…๋ น์–ด ๋ฐ ์—์ด์ „ํŠธ',
85
+ windsurfRules: 'Windsurf ๊ทœ์น™ ํŒŒ์ผ',
86
+ cursorRules: 'Cursor ๊ทœ์น™ ํŒŒ์ผ',
87
+ selectAll: '๋ชจ๋“  ์˜ต์…˜ ์„ ํƒ',
88
+ installSelected: '์„ ํƒํ•œ ํ•ญ๋ชฉ๋“ค์„ ์„ค์น˜ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?',
89
+ installingOption: '์„ค์น˜ ์ค‘: ',
90
+ optionInstalled: '์™„๋ฃŒ: ',
91
+ noOptionsSelected: '์„ ํƒ๋œ ์˜ต์…˜์ด ์—†์Šต๋‹ˆ๋‹ค.',
80
92
  },
81
93
  en: {
82
94
  welcome: '\n๐ŸŽ‰ Welcome to AIWF!\n',
@@ -153,6 +165,18 @@ export const messages = {
153
165
  toolBackupCreated: 'Tool files backup created',
154
166
  installingToolRules: 'Installing tool rules...',
155
167
  toolRulesInstalled: 'Tool rules installed successfully',
168
+
169
+ // Installation options
170
+ installationOptions: 'Select AIWF installation options:',
171
+ aiwfDocs: 'AIWF Documentation folder (.aiwf/docs)',
172
+ claudeCodeCommands: 'Claude Code commands and agents',
173
+ windsurfRules: 'Windsurf rules files',
174
+ cursorRules: 'Cursor rules files',
175
+ selectAll: 'Select all options',
176
+ installSelected: 'Install selected items?',
177
+ installingOption: 'Installing: ',
178
+ optionInstalled: 'Completed: ',
179
+ noOptionsSelected: 'No options selected.',
156
180
  }
157
181
  };
158
182
 
@@ -1,90 +0,0 @@
1
- # AIWF ๋ชจ๋“ˆ ์˜์กด์„ฑ ๋งคํŠธ๋ฆญ์Šค
2
-
3
- ## ๐Ÿ“Š CLI ๋ช…๋ น์–ด๋ณ„ ์˜์กด์„ฑ
4
-
5
- | ๋ช…๋ น์–ด | ์ง์ ‘ ์˜์กด์„ฑ | ๊ฐ„์ ‘ ์˜์กด์„ฑ | ํŠน์ˆ˜ ์‚ฌ์šฉ |
6
- |--------|-------------|-------------|-----------|
7
- | `aiwf install` | installer.js | backup-manager.js, file-downloader.js, rollback-manager.js, validator.js | - |
8
- | `aiwf persona` | persona.js, ai-persona-manager.js | context-engine.js, metrics-collector.js, task-analyzer.js, token-optimizer.js | - |
9
- | `aiwf compress` | compress.js, resource-loader.js | - | - |
10
- | `aiwf token` | token.js, resource-loader.js | - | - |
11
- | `aiwf evaluate` | evaluate.js, resource-loader.js | - | - |
12
- | `aiwf state` | state.js | - | - |
13
- | `aiwf create-project` | create-project.js, resource-loader.js | - | - |
14
- | `aiwf ai-tool` | ai-tool.js | - | - |
15
- | `aiwf sprint-task` | sprint-task.js | - | - |
16
- | `aiwf sprint` | sprint-independent.js | - | - |
17
- | `aiwf yolo-config` | yolo-config.js | - | - |
18
- | `aiwf checkpoint` | checkpoint-manager.js | - | โš ๏ธ YOLO ์ „์šฉ |
19
- | `aiwf-checkpoint` | checkpoint-manager.js | - | โš ๏ธ YOLO ์ „์šฉ |
20
- | `aiwf cache` | cache-cli.js | template-cache-system.js, offline-detector.js, template-downloader.js, template-version-manager.js | - |
21
- | `aiwf github` | github-integration.js | state/state-index.js | - |
22
- | `YOLO ๋ชจ๋“œ` | engineering-guard.js | - | โš ๏ธ ๋™์  import |
23
-
24
- ## ๐Ÿ—๏ธ ๋ชจ๋“ˆ ๋ถ„๋ฅ˜
25
-
26
- ### ๐Ÿ”ง ํ•ต์‹ฌ ์œ ํ‹ธ๋ฆฌํ‹ฐ (์‚ญ์ œ ๊ธˆ์ง€)
27
- - **paths.js** - ๊ฒฝ๋กœ ๊ด€๋ฆฌ (8๊ณณ์—์„œ ์‚ฌ์šฉ)
28
- - **messages.js** - ๋‹ค๊ตญ์–ด ๋ฉ”์‹œ์ง€ ์‹œ์Šคํ…œ (5๊ณณ์—์„œ ์‚ฌ์šฉ)
29
- - **language-utils.js** - ์–ธ์–ด ์„ค์ • ๊ด€๋ฆฌ (3๊ณณ์—์„œ ์‚ฌ์šฉ)
30
-
31
- ### ๐Ÿš€ YOLO ์‹œ์Šคํ…œ (์‚ญ์ œ ๊ธˆ์ง€)
32
- - **engineering-guard.js** - ์˜ค๋ฒ„์—”์ง€๋‹ˆ์–ด๋ง ๋ฐฉ์ง€ โš ๏ธ ๋™์  ๋กœ๋“œ
33
- - **checkpoint-manager.js** - ์ฒดํฌํฌ์ธํŠธ ๊ด€๋ฆฌ
34
-
35
- ### ๐ŸŽฏ ๋ช…๋ น์–ด๋ณ„ ์ „์šฉ ๋ชจ๋“ˆ
36
-
37
- #### AI Persona ์‹œ์Šคํ…œ
38
- - **ai-persona-manager.js** โ†’ persona ๋ช…๋ น์–ด
39
- - **context-engine.js** โ†’ ai-persona-manager๊ฐ€ ์‚ฌ์šฉ
40
- - **metrics-collector.js** โ†’ ai-persona-manager๊ฐ€ ์‚ฌ์šฉ
41
- - **task-analyzer.js** โ†’ ai-persona-manager๊ฐ€ ์‚ฌ์šฉ
42
- - **token-optimizer.js** โ†’ context-engine์ด ์‚ฌ์šฉ
43
-
44
- #### ์„ค์น˜/๋ฐฑ์—… ์‹œ์Šคํ…œ
45
- - **installer.js** โ†’ install ๋ช…๋ น์–ด
46
- - **backup-manager.js** โ†’ installer๊ฐ€ ์‚ฌ์šฉ
47
- - **file-downloader.js** โ†’ installer๊ฐ€ ์‚ฌ์šฉ
48
- - **rollback-manager.js** โ†’ installer๊ฐ€ ์‚ฌ์šฉ
49
- - **validator.js** โ†’ installer๊ฐ€ ์‚ฌ์šฉ
50
-
51
- #### ์บ์‹œ ์‹œ์Šคํ…œ
52
- - **template-cache-system.js** โ†’ cache ๋ช…๋ น์–ด
53
- - **offline-detector.js** โ†’ cache ๋ช…๋ น์–ด
54
- - **template-downloader.js** โ†’ cache ๋ช…๋ น์–ด
55
- - **template-version-manager.js** โ†’ cache ๋ช…๋ น์–ด
56
-
57
- #### GitHub ํ†ตํ•ฉ
58
- - **github-integration.js** โ†’ github ๋ช…๋ น์–ด
59
- - **state/state-index.js** โ†’ github-integration์ด ์‚ฌ์šฉ
60
-
61
- #### ๊ณตํ†ต ๋ฆฌ์†Œ์Šค
62
- - **resource-loader.js** โ†’ 5๊ฐœ ๋ช…๋ น์–ด์—์„œ ์‚ฌ์šฉ
63
-
64
- ## โš ๏ธ ์‚ญ์ œ ์œ„ํ—˜ ๋ชจ๋“ˆ
65
-
66
- ### ๋™์  ๋กœ๋“œ ๋ชจ๋“ˆ (CLI์—์„œ ์ง์ ‘ ์ฐธ์กฐ๋˜์ง€ ์•Š์Œ)
67
- - **engineering-guard.js** - YOLO ํ…œํ”Œ๋ฆฟ์—์„œ `import()`๋กœ ๋กœ๋“œ
68
- - **state/priority-calculator.js** - github-integration์—์„œ ์‚ฌ์šฉ
69
- - **state/task-scanner.js** - github-integration์—์„œ ์‚ฌ์šฉ
70
-
71
- ### ๊ฐ„์ ‘ ์˜์กด์„ฑ ๋ชจ๋“ˆ
72
- - AI Persona ์‹œ์Šคํ…œ์˜ ํ•˜์œ„ ๋ชจ๋“ˆ๋“ค
73
- - ์„ค์น˜ ์‹œ์Šคํ…œ์˜ ๋ฐฑ์—…/๋ณต๊ตฌ ๋ชจ๋“ˆ๋“ค
74
-
75
- ## ๐Ÿšจ ์‚ญ์ œํ•˜๊ธฐ ์ „ ํ™•์ธ์‚ฌํ•ญ
76
-
77
- 1. **์ด ํŒŒ์ผ์—์„œ ๋ชจ๋“ˆ ์œ„์น˜ ํ™•์ธ**
78
- 2. **`@warning ์‚ญ์ œ ๊ธˆ์ง€` ์ฃผ์„ ํ™•์ธ**
79
- 3. **YOLO ์ „์šฉ ๋ชจ๋“ˆ์ธ์ง€ ํ™•์ธ**
80
- 4. **๋™์  import ์‚ฌ์šฉ ์—ฌ๋ถ€ ํ™•์ธ**
81
- 5. **๊ฐ„์ ‘ ์˜์กด์„ฑ ์ฒด์ธ ํ™•์ธ**
82
-
83
- ## ๐Ÿ“ ๋ฏธ์‚ฌ์šฉ ๋ชจ๋“ˆ (์‚ญ์ œ ๊ฐ€๋Šฅ)
84
-
85
- ํ˜„์žฌ ์™„์ „ํžˆ ๋ฏธ์‚ฌ์šฉ๋˜๋Š” ๋ชจ๋“ˆ์€ ์—†์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ๋ชจ๋“ˆ์ด ์ง๊ฐ„์ ‘์ ์œผ๋กœ CLI ์‹œ์Šคํ…œ์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
86
-
87
- ---
88
-
89
- **๋งˆ์ง€๋ง‰ ์—…๋ฐ์ดํŠธ**: 2024-01-27
90
- **๊ฒ€์ฆ ๋ฐฉ๋ฒ•**: `grep -r "๋ชจ๋“ˆ๋ช…" src/` ์œผ๋กœ ์‚ฌ์šฉ์ฒ˜ ํ™•์ธ