aiwf 0.3.2 → 0.3.4

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 (214) hide show
  1. package/.aiwf/config/language.json +1 -1
  2. package/.aiwf/installed.flag +1 -0
  3. package/.aiwf/sessions/session_1752877859489_1t7n2fhdb.json +7 -0
  4. package/.aiwf/sessions/session_1752877859515_cwdv211ry.json +7 -0
  5. package/.aiwf/sessions/session_1752877860664_huziadmbo.json +7 -0
  6. package/.aiwf/sessions/session_1752877860666_kyr5u1np6.json +7 -0
  7. package/.aiwf/sessions/session_1752877861848_9yinepw3t.json +7 -0
  8. package/.aiwf/sessions/session_1752877861874_y32sputuc.json +7 -0
  9. package/.aiwf/sessions/session_1752877862685_ivxbl5rhz.json +7 -0
  10. package/.aiwf/sessions/session_1752877862820_wnq4glvxi.json +7 -0
  11. package/.aiwf/sessions/session_1752877864632_3ebnpaelb.json +7 -0
  12. package/.aiwf/sessions/session_1752877864879_b9zgjcb7d.json +7 -0
  13. package/.aiwf/sessions/session_1752877865533_x14m1vodi.json +7 -0
  14. package/.aiwf/sessions/session_1752877865562_gkoh19n7d.json +7 -0
  15. package/.aiwf/sessions/session_1752877866333_wp8qpdcoh.json +7 -0
  16. package/.aiwf/sessions/session_1752877866509_dawntfpab.json +7 -0
  17. package/.aiwf/sessions/session_1752877866890_plc5vfucl.json +7 -0
  18. package/.aiwf/sessions/session_1752877866895_ga8hmq3oi.json +7 -0
  19. package/.aiwf/sessions/session_1752877867761_ayjp4v5f5.json +7 -0
  20. package/.aiwf/sessions/session_1752877867892_lfz6jy252.json +7 -0
  21. package/.aiwf/sessions/session_1752877868139_7bqd9ubli.json +7 -0
  22. package/.aiwf/sessions/session_1752877868162_zq3ofjbsh.json +7 -0
  23. package/.aiwf/sessions/session_1752877869054_7rlgm9jt6.json +7 -0
  24. package/.aiwf/sessions/session_1752877869477_ax3nhbxzr.json +7 -0
  25. package/.aiwf/sessions/session_1752877870095_6hgp4vl1e.json +7 -0
  26. package/.aiwf/sessions/session_1752877870381_qfcrdg4li.json +7 -0
  27. package/.aiwf/sessions/session_1752877871895_pgd5vllhz.json +7 -0
  28. package/.aiwf/sessions/session_1752877872199_jbhv2g2da.json +7 -0
  29. package/.aiwf/sessions/session_1752877872680_x04wpffu6.json +7 -0
  30. package/.aiwf/sessions/session_1752877872895_3y4vbeauo.json +7 -0
  31. package/.aiwf/sessions/session_1752877873178_3maolzc6b.json +7 -0
  32. package/.aiwf/sessions/session_1752877873180_ytm83j07f.json +7 -0
  33. package/.aiwf/sessions/session_1752877874217_dp56c9t42.json +7 -0
  34. package/.aiwf/sessions/session_1752877874415_epwp1g1og.json +7 -0
  35. package/.aiwf/sessions/session_1752877874454_heicyuryb.json +7 -0
  36. package/.aiwf/sessions/session_1752877874869_1c2illeu5.json +7 -0
  37. package/.aiwf/sessions/session_1752877874879_k1vo4vxyx.json +7 -0
  38. package/.aiwf/sessions/session_1752877874913_bwgyiz9bp.json +7 -0
  39. package/.aiwf/sessions/session_1752877876218_44807kztz.json +7 -0
  40. package/.aiwf/sessions/session_1752877876515_qkhjv5kpw.json +7 -0
  41. package/.aiwf/sessions/session_1752877876543_p605aud1m.json +7 -0
  42. package/.aiwf/sessions/session_1752877876819_l65w7ifck.json +7 -0
  43. package/.aiwf/sessions/session_1752877876867_xrhzss4we.json +7 -0
  44. package/.aiwf/sessions/session_1752877876872_u7aso54qb.json +7 -0
  45. package/.aiwf/sessions/session_1752877877705_telnfg4o6.json +7 -0
  46. package/.aiwf/sessions/session_1752877878285_6s45im2ib.json +7 -0
  47. package/.aiwf/sessions/session_1752877878506_v0dvguqhz.json +7 -0
  48. package/.aiwf/sessions/session_1752877878581_3ri3yc66a.json +7 -0
  49. package/.aiwf/sessions/session_1752877878756_a82x9s2pd.json +7 -0
  50. package/.aiwf/sessions/session_1752877878886_20pjsfour.json +7 -0
  51. package/.aiwf/sessions/session_1752877880266_fm1ydjw0g.json +7 -0
  52. package/.aiwf/sessions/session_1752877881149_xbat4z03d.json +7 -0
  53. package/.aiwf/sessions/session_1752877881551_qy5sic9qs.json +7 -0
  54. package/.aiwf/sessions/session_1752877881554_24ugd96wu.json +7 -0
  55. package/.aiwf/sessions/session_1752877881797_e9mm25uh0.json +7 -0
  56. package/.aiwf/sessions/session_1752877881822_bxvjj8c9g.json +7 -0
  57. package/.aiwf/sessions/session_1752877881890_jv7l6jve3.json +7 -0
  58. package/.aiwf/sessions/session_1752877881991_f0qugdtcq.json +7 -0
  59. package/.aiwf/sessions/session_1752877883387_0bvw9rvnx.json +7 -0
  60. package/.aiwf/sessions/session_1752877883820_q6g2md2up.json +7 -0
  61. package/.aiwf/sessions/session_1752877884393_sqr7trvjl.json +7 -0
  62. package/.aiwf/sessions/session_1752877884500_whtypmzlf.json +7 -0
  63. package/.aiwf/sessions/session_1752877884645_y9mvvxli1.json +7 -0
  64. package/.aiwf/sessions/session_1752877884733_hk46eenel.json +7 -0
  65. package/.aiwf/sessions/session_1752877884738_c62j6214r.json +7 -0
  66. package/.aiwf/sessions/session_1752877884771_temhxehoz.json +7 -0
  67. package/.aiwf/sessions/session_1752877885643_6v5fcktc7.json +7 -0
  68. package/.aiwf/sessions/session_1752877886426_ee8di2fqh.json +7 -0
  69. package/.aiwf/sessions/session_1752877886549_3xj6tdoew.json +7 -0
  70. package/.aiwf/sessions/session_1752877886604_aj80yyfco.json +7 -0
  71. package/.aiwf/sessions/session_1752877886702_2b8841vyg.json +7 -0
  72. package/.aiwf/sessions/session_1752877886712_ntqc8b8bz.json +7 -0
  73. package/.aiwf/sessions/session_1752877886968_946m8tbw6.json +7 -0
  74. package/.aiwf/sessions/session_1752877887008_wg6zfg8dn.json +7 -0
  75. package/.aiwf/sessions/session_1752877888479_ciiu2qiqs.json +7 -0
  76. package/.aiwf/sessions/session_1752877889330_ravg8l66k.json +7 -0
  77. package/.aiwf/sessions/session_1752877889542_7zepkhjkc.json +7 -0
  78. package/.aiwf/sessions/session_1752877889638_ev4htqiu0.json +7 -0
  79. package/.aiwf/sessions/session_1752877889956_szphy2qma.json +7 -0
  80. package/.aiwf/sessions/session_1752877890220_o6aaa57tt.json +7 -0
  81. package/.aiwf/sessions/session_1752877890527_v2loy5vu1.json +7 -0
  82. package/.aiwf/sessions/session_1752877890572_cwq8fiuma.json +7 -0
  83. package/.aiwf/sessions/session_1752877892200_sgcwq1alt.json +7 -0
  84. package/.aiwf/sessions/session_1752877892268_v8kexpbc5.json +7 -0
  85. package/.aiwf/sessions/session_1752877892384_1gbbgrp4y.json +7 -0
  86. package/.aiwf/sessions/session_1752877893568_9p2n5p31a.json +7 -0
  87. package/.aiwf/sessions/session_1752877893727_un34a5tvp.json +7 -0
  88. package/.aiwf/sessions/session_1752877893778_01j79sw9i.json +7 -0
  89. package/.aiwf/sessions/session_1752877894053_jrhba6wko.json +7 -0
  90. package/.aiwf/sessions/session_1752877894082_x3bghawox.json +7 -0
  91. package/.aiwf/sessions/session_1752877894500_iytiav2ku.json +7 -0
  92. package/.aiwf/sessions/session_1752877894667_ucn0gc2ge.json +7 -0
  93. package/.aiwf/test-results-s02.json +4 -4
  94. package/.claude/commands/aiwf/aiwf_changelog.md +82 -0
  95. package/.claude/commands/aiwf/aiwf_code_review.md +88 -0
  96. package/.claude/commands/aiwf/aiwf_commit.md +160 -0
  97. package/.claude/commands/aiwf/aiwf_compress_context.md +116 -0
  98. package/.claude/commands/aiwf/aiwf_create_feature_ledger.md +54 -0
  99. package/.claude/commands/aiwf/aiwf_create_general_task.md +147 -0
  100. package/.claude/commands/aiwf/aiwf_create_milestone_plan.md +194 -0
  101. package/.claude/commands/aiwf/aiwf_create_prd.md +280 -0
  102. package/.claude/commands/aiwf/aiwf_create_sprint_tasks.md +189 -0
  103. package/.claude/commands/aiwf/aiwf_create_sprints_from_milestone.md +121 -0
  104. package/.claude/commands/aiwf/aiwf_default_mode.md +44 -0
  105. package/.claude/commands/aiwf/aiwf_discuss_review.md +29 -0
  106. package/.claude/commands/aiwf/aiwf_do_task.md +109 -0
  107. package/.claude/commands/aiwf/aiwf_docs.md +225 -0
  108. package/.claude/commands/aiwf/aiwf_get_feature_details.md +78 -0
  109. package/.claude/commands/aiwf/aiwf_infinite.md +202 -0
  110. package/.claude/commands/aiwf/aiwf_initialize.md +134 -0
  111. package/.claude/commands/aiwf/aiwf_issue_create.md +65 -0
  112. package/.claude/commands/aiwf/aiwf_link_feature_to_milestone.md +57 -0
  113. package/.claude/commands/aiwf/aiwf_list_features.md +54 -0
  114. package/.claude/commands/aiwf/aiwf_mermaid.md +272 -0
  115. package/.claude/commands/aiwf/aiwf_persona_architect.md +48 -0
  116. package/.claude/commands/aiwf/aiwf_persona_backend.md +37 -0
  117. package/.claude/commands/aiwf/aiwf_persona_data_analyst.md +37 -0
  118. package/.claude/commands/aiwf/aiwf_persona_frontend.md +37 -0
  119. package/.claude/commands/aiwf/aiwf_persona_security.md +48 -0
  120. package/.claude/commands/aiwf/aiwf_persona_status.md +50 -0
  121. package/.claude/commands/aiwf/aiwf_pr_create.md +76 -0
  122. package/.claude/commands/aiwf/aiwf_prime.md +9 -0
  123. package/.claude/commands/aiwf/aiwf_project_review.md +261 -0
  124. package/.claude/commands/aiwf/aiwf_switch_language.md +160 -0
  125. package/.claude/commands/aiwf/aiwf_test.md +124 -0
  126. package/.claude/commands/aiwf/aiwf_testing_review.md +198 -0
  127. package/.claude/commands/aiwf/aiwf_tm-run-all-subtask.md +210 -0
  128. package/.claude/commands/aiwf/aiwf_ultrathink_code_advanced.md +460 -0
  129. package/.claude/commands/aiwf/aiwf_ultrathink_code_basic.md +165 -0
  130. package/.claude/commands/aiwf/aiwf_ultrathink_general.md +305 -0
  131. package/.claude/commands/aiwf/aiwf_update_docs_kr.md +25 -0
  132. package/.claude/commands/aiwf/aiwf_update_feature_status.md +53 -0
  133. package/.claude/commands/aiwf/aiwf_yolo.md +300 -0
  134. package/.eslintrc.json +26 -0
  135. package/.prettierrc +10 -0
  136. package/CLAUDE.md +154 -54
  137. package/README.ko.md +25 -0
  138. package/README.md +25 -0
  139. package/TEST_RECOVERY_PLAN.md +68 -0
  140. package/docs/CLEANUP_RECOMMENDATIONS.md +86 -0
  141. package/docs/CLI_USAGE_GUIDE.md +479 -0
  142. package/package.json +9 -9
  143. package/scripts/update-feature-status.js +70 -0
  144. package/{lib → src/cli}/cache-cli.js +4 -4
  145. package/src/cli/index.js +165 -0
  146. package/{language-cli.js → src/cli/language-cli.js} +11 -4
  147. package/src/commands/cache-templates.js +209 -0
  148. package/src/commands/create-offline.js +86 -0
  149. package/src/commands/create-project.js +151 -0
  150. package/src/lib/backup-manager.js +270 -0
  151. package/src/lib/file-downloader.js +208 -0
  152. package/src/lib/installer.js +676 -0
  153. package/src/lib/rollback-manager.js +418 -0
  154. package/src/lib/validator.js +561 -0
  155. package/src/utils/git-integration.js +173 -0
  156. package/{language-utils.js → src/utils/language-utils.js} +2 -1
  157. package/src/utils/messages.js +136 -0
  158. package/src/utils/paths.js +130 -0
  159. package/tests/application.test.js +2 -2
  160. package/tests/installer.test.js +2 -2
  161. package/tests/integration/ai-persona-system.test.js +4 -4
  162. package/tests/integration/test-persona-system/docs/README.md +1 -0
  163. package/tests/integration/test-persona-system/package.json +1 -0
  164. package/tests/integration/test-persona-system/src/auth.js +1 -0
  165. package/tests/integration/test-persona-system/src/index.js +1 -0
  166. package/tests/integration/test-persona-system/test/test.js +1 -0
  167. package/tests/language-utils.test.js +1 -1
  168. package/tests/temp_invalid_json/invalid.json +1 -0
  169. package/tests/unit/ai-persona-manager.test.js +7 -7
  170. package/.aiwf/05_DOCUMENTATION/performance-report.md +0 -33
  171. package/.aiwf/test-cache/86c7f9e80251abb8bedd58953ab0d1779e46b4f43ea33b63bffdb778106373b0.json +0 -6
  172. package/.aiwf/test-cache/9e252a90b80fce0585d7ed0646e7a9b4343e109f661f42a3ae678ba1ec5e22c7.json +0 -7
  173. package/.aiwf/token-data/alerts.json +0 -293
  174. package/.aiwf/token-data/monitor-config.json +0 -12
  175. package/CHANGELOG_M02.md +0 -52
  176. package/claude-code/aiwf/ko/bin/aiwf-create.js +0 -56
  177. package/claude-code/aiwf/ko/bin/aiwf.js +0 -21
  178. package/claude-code/aiwf/ko/docs/00_PROJECT_MANIFEST.md +0 -183
  179. package/claude-code/aiwf/ko/docs/ARCHITECTURE.md +0 -121
  180. package/claude-code/aiwf/ko/docs/FEATURE_LEDGER_ADVANCED_USE_CASES.md +0 -412
  181. package/claude-code/aiwf/ko/docs/FEATURE_LEDGER_API_REFERENCE.md +0 -361
  182. package/claude-code/aiwf/ko/docs/FEATURE_LEDGER_COMMANDS_GUIDE.md +0 -254
  183. package/claude-code/aiwf/ko/docs/FEATURE_LEDGER_FAQ.md +0 -365
  184. package/claude-code/aiwf/ko/docs/FEATURE_LEDGER_SYSTEM_OVERVIEW.md +0 -305
  185. package/claude-code/aiwf/ko/docs/FEATURE_LEDGER_USER_GUIDE.md +0 -416
  186. package/claude-code/aiwf/ko/docs/FEATURE_LEDGER_/354/213/234/354/236/221_/352/260/200/354/235/264/353/223/234.md +0 -247
  187. package/claude-code/aiwf/ko/token-data/alerts.json +0 -293
  188. package/claude-code/aiwf/ko/token-data/monitor-config.json +0 -12
  189. package/docs/m02-dod-checklist.md +0 -125
  190. package/docs/m02-gap-analysis.md +0 -214
  191. package/docs/m02-milestone-completion-report.md +0 -186
  192. package/docs/m02-milestone-executive-summary.md +0 -68
  193. package/index.js +0 -1947
  194. package/lib/cache-integration.js +0 -401
  195. package/lib/file-batch-processor.js +0 -401
  196. package/lib/performance-benchmark.js +0 -621
  197. package/lib/template-manager.js +0 -310
  198. package/scripts/validate-commands.cjs +0 -338
  199. /package/{.aiwf/.claude → .claude}/commands/aiwf/aiwf_compress_aggressive_persona.md +0 -0
  200. /package/{.aiwf/.claude → .claude}/commands/aiwf/aiwf_compress_minimal_persona.md +0 -0
  201. /package/{.aiwf/.claude → .claude}/commands/aiwf/aiwf_compress_stats.md +0 -0
  202. /package/{.aiwf/.claude → .claude}/commands/aiwf/aiwf_compress_with_persona.md +0 -0
  203. /package/{.aiwf/.claude → .claude}/commands/aiwf/aiwf_evaluate.md +0 -0
  204. /package/{lib → src/lib}/ai-persona-manager.js +0 -0
  205. /package/{lib → src/lib}/cache-system.js +0 -0
  206. /package/{lib → src/lib}/context-engine.js +0 -0
  207. /package/{lib → src/lib}/memory-profiler.js +0 -0
  208. /package/{lib → src/lib}/metrics-collector.js +0 -0
  209. /package/{lib → src/lib}/offline-detector.js +0 -0
  210. /package/{lib → src/lib}/task-analyzer.js +0 -0
  211. /package/{lib → src/lib}/template-cache-system.js +0 -0
  212. /package/{lib → src/lib}/template-downloader.js +0 -0
  213. /package/{lib → src/lib}/template-version-manager.js +0 -0
  214. /package/{lib → src/lib}/token-optimizer.js +0 -0
@@ -0,0 +1,561 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import chalk from 'chalk';
4
+ import { TOOL_DIRS, AIWF_DIRS, FILES } from '../utils/paths.js';
5
+
6
+ // Essential files configuration for each tool
7
+ const ESSENTIAL_FILES = {
8
+ claudeCode: {
9
+ baseDir: TOOL_DIRS.CLAUDE_COMMANDS,
10
+ requiredFiles: [
11
+ 'aiwf_initialize.md',
12
+ 'aiwf_do_task.md',
13
+ 'aiwf_commit.md',
14
+ 'aiwf_create_sprint_tasks.md',
15
+ 'aiwf_code_review.md'
16
+ ],
17
+ minFileCount: 5,
18
+ description: 'Claude Code Commands'
19
+ },
20
+ geminiCLI: {
21
+ baseDir: TOOL_DIRS.GEMINI_PROMPTS,
22
+ requiredFiles: ['README.md'],
23
+ minFileCount: 1,
24
+ description: 'Gemini-CLI Prompts'
25
+ },
26
+ cursor: {
27
+ baseDir: TOOL_DIRS.CURSOR_RULES,
28
+ requiredFiles: [],
29
+ minFileCount: 2,
30
+ fileExtension: '.mdc',
31
+ description: 'Cursor IDE Rules'
32
+ },
33
+ windsurf: {
34
+ baseDir: TOOL_DIRS.WINDSURF_RULES,
35
+ requiredFiles: [],
36
+ minFileCount: 2,
37
+ fileExtension: '.md',
38
+ description: 'Windsurf IDE Rules'
39
+ },
40
+ aiwf: {
41
+ baseDir: AIWF_DIRS.ROOT,
42
+ requiredFiles: ['CLAUDE.md', '00_PROJECT_MANIFEST.md'],
43
+ minFileCount: 2,
44
+ description: 'AIWF Core Structure'
45
+ }
46
+ };
47
+
48
+ /**
49
+ * Validate tool installation based on configuration
50
+ * @param {Object} config - Tool configuration
51
+ * @returns {Promise<Object>} Validation results
52
+ */
53
+ async function validateToolInstallation(config) {
54
+ const results = {
55
+ success: true,
56
+ description: config.description,
57
+ baseDir: config.baseDir,
58
+ checks: {
59
+ directoryExists: false,
60
+ fileCount: 0,
61
+ requiredFiles: [],
62
+ totalSize: 0,
63
+ issues: []
64
+ }
65
+ };
66
+
67
+ try {
68
+ // 1. Check directory exists
69
+ await fs.access(config.baseDir);
70
+ const dirStat = await fs.stat(config.baseDir);
71
+ if (dirStat.isDirectory()) {
72
+ results.checks.directoryExists = true;
73
+ } else {
74
+ results.checks.issues.push(`${config.baseDir} is not a directory`);
75
+ results.success = false;
76
+ return results;
77
+ }
78
+
79
+ // 2. Get file list
80
+ const actualFiles = await fs.readdir(config.baseDir);
81
+ results.checks.fileCount = actualFiles.length;
82
+
83
+ // 3. Check required files
84
+ for (const requiredFile of config.requiredFiles || []) {
85
+ const filePath = path.join(config.baseDir, requiredFile);
86
+ const fileCheck = {
87
+ file: requiredFile,
88
+ exists: false,
89
+ size: 0,
90
+ valid: false
91
+ };
92
+
93
+ if (actualFiles.includes(requiredFile)) {
94
+ fileCheck.exists = true;
95
+ try {
96
+ const stats = await fs.stat(filePath);
97
+ fileCheck.size = stats.size;
98
+ results.checks.totalSize += stats.size;
99
+
100
+ // Validate file size (minimum 10 bytes)
101
+ if (stats.size < 10) {
102
+ results.checks.issues.push(
103
+ `File ${requiredFile} is too small (${stats.size} bytes)`
104
+ );
105
+ results.success = false;
106
+ } else {
107
+ fileCheck.valid = true;
108
+ }
109
+ } catch (error) {
110
+ results.checks.issues.push(
111
+ `Cannot read stats for ${requiredFile}: ${error.message}`
112
+ );
113
+ results.success = false;
114
+ }
115
+ } else {
116
+ results.checks.issues.push(`Required file ${requiredFile} is missing`);
117
+ results.success = false;
118
+ }
119
+
120
+ results.checks.requiredFiles.push(fileCheck);
121
+ }
122
+
123
+ // 4. File extension validation (Cursor/Windsurf)
124
+ if (config.fileExtension) {
125
+ const matchingFiles = actualFiles.filter(f => f.endsWith(config.fileExtension));
126
+ if (matchingFiles.length < config.minFileCount) {
127
+ results.checks.issues.push(
128
+ `Expected at least ${config.minFileCount} ${config.fileExtension} files, found ${matchingFiles.length}`
129
+ );
130
+ results.success = false;
131
+ }
132
+
133
+ // Validate file sizes for extension files
134
+ for (const file of matchingFiles) {
135
+ const filePath = path.join(config.baseDir, file);
136
+ try {
137
+ const stats = await fs.stat(filePath);
138
+ results.checks.totalSize += stats.size;
139
+
140
+ if (stats.size < 50) {
141
+ // Rules files should be at least 50 bytes
142
+ results.checks.issues.push(
143
+ `Rules file ${file} is too small (${stats.size} bytes)`
144
+ );
145
+ results.success = false;
146
+ }
147
+ } catch (error) {
148
+ results.checks.issues.push(`Cannot read ${file}: ${error.message}`);
149
+ results.success = false;
150
+ }
151
+ }
152
+ }
153
+
154
+ // 5. Minimum file count validation
155
+ if (results.checks.fileCount < config.minFileCount) {
156
+ results.checks.issues.push(
157
+ `Expected at least ${config.minFileCount} files, found ${results.checks.fileCount}`
158
+ );
159
+ results.success = false;
160
+ }
161
+ } catch (error) {
162
+ results.success = false;
163
+ results.checks.issues.push(`Validation error: ${error.message}`);
164
+ }
165
+
166
+ return results;
167
+ }
168
+
169
+ /**
170
+ * Validate Claude Code installation
171
+ * @returns {Promise<Object>} Validation results
172
+ */
173
+ export async function validateClaudeInstall() {
174
+ return await validateToolInstallation(ESSENTIAL_FILES.claudeCode);
175
+ }
176
+
177
+ /**
178
+ * Validate Gemini CLI installation
179
+ * @returns {Promise<Object>} Validation results
180
+ */
181
+ export async function validateGeminiInstall() {
182
+ return await validateToolInstallation(ESSENTIAL_FILES.geminiCLI);
183
+ }
184
+
185
+ /**
186
+ * Validate Cursor installation
187
+ * @returns {Promise<Object>} Validation results
188
+ */
189
+ export async function validateCursorInstall() {
190
+ return await validateToolInstallation(ESSENTIAL_FILES.cursor);
191
+ }
192
+
193
+ /**
194
+ * Validate Windsurf installation
195
+ * @returns {Promise<Object>} Validation results
196
+ */
197
+ export async function validateWindsurfInstall() {
198
+ return await validateToolInstallation(ESSENTIAL_FILES.windsurf);
199
+ }
200
+
201
+ /**
202
+ * Validate AIWF Core installation
203
+ * @returns {Promise<Object>} Validation results
204
+ */
205
+ export async function validateAIWFCore() {
206
+ return await validateToolInstallation(ESSENTIAL_FILES.aiwf);
207
+ }
208
+
209
+ /**
210
+ * Validate installation with detailed results
211
+ * @returns {Promise<Object>} Detailed validation results
212
+ */
213
+ export async function validateInstallationDetailed() {
214
+ const validationResults = {
215
+ overall: {
216
+ success: true,
217
+ toolsChecked: 0,
218
+ toolsPassed: 0,
219
+ toolsFailed: 0,
220
+ totalIssues: 0
221
+ },
222
+ tools: {}
223
+ };
224
+
225
+ // Always validate AIWF core
226
+ const aiwfResult = await validateAIWFCore();
227
+ validationResults.tools.aiwf = aiwfResult;
228
+ validationResults.overall.toolsChecked++;
229
+
230
+ if (aiwfResult.success) {
231
+ validationResults.overall.toolsPassed++;
232
+ } else {
233
+ validationResults.overall.toolsFailed++;
234
+ validationResults.overall.success = false;
235
+ validationResults.overall.totalIssues += aiwfResult.checks.issues.length;
236
+ }
237
+
238
+ // Validate all tools
239
+ const toolValidators = {
240
+ claudeCode: validateClaudeInstall,
241
+ geminiCLI: validateGeminiInstall,
242
+ cursor: validateCursorInstall,
243
+ windsurf: validateWindsurfInstall
244
+ };
245
+
246
+ for (const [toolName, validator] of Object.entries(toolValidators)) {
247
+ const result = await validator();
248
+ validationResults.tools[toolName] = result;
249
+ validationResults.overall.toolsChecked++;
250
+
251
+ if (result.success) {
252
+ validationResults.overall.toolsPassed++;
253
+ } else {
254
+ validationResults.overall.toolsFailed++;
255
+ validationResults.overall.success = false;
256
+ validationResults.overall.totalIssues += result.checks.issues.length;
257
+ }
258
+ }
259
+
260
+ return validationResults;
261
+ }
262
+
263
+ /**
264
+ * Enhanced installation validation with tool selection
265
+ * @param {Array|null} selectedTools - Tools to validate
266
+ * @param {string} language - Language code
267
+ * @returns {Promise<Object>} Validation results
268
+ */
269
+ export async function validateInstallationEnhanced(selectedTools = null, language = 'en') {
270
+ const validationResults = {
271
+ overall: {
272
+ success: true,
273
+ toolsChecked: 0,
274
+ toolsPassed: 0,
275
+ toolsFailed: 0,
276
+ totalIssues: 0
277
+ },
278
+ tools: {}
279
+ };
280
+
281
+ // Always validate AIWF core
282
+ const aiwfResult = await validateAIWFCore();
283
+ validationResults.tools.aiwf = aiwfResult;
284
+ validationResults.overall.toolsChecked++;
285
+
286
+ if (aiwfResult.success) {
287
+ validationResults.overall.toolsPassed++;
288
+ } else {
289
+ validationResults.overall.toolsFailed++;
290
+ validationResults.overall.success = false;
291
+ validationResults.overall.totalIssues += aiwfResult.checks.issues.length;
292
+ }
293
+
294
+ // Determine tools to validate
295
+ const toolsToValidate = selectedTools || ['claudeCode', 'geminiCLI', 'cursor', 'windsurf'];
296
+
297
+ const toolValidators = {
298
+ claudeCode: validateClaudeInstall,
299
+ geminiCLI: validateGeminiInstall,
300
+ cursor: validateCursorInstall,
301
+ windsurf: validateWindsurfInstall
302
+ };
303
+
304
+ for (const toolName of toolsToValidate) {
305
+ if (toolValidators[toolName]) {
306
+ const result = await toolValidators[toolName]();
307
+ validationResults.tools[toolName] = result;
308
+ validationResults.overall.toolsChecked++;
309
+
310
+ if (result.success) {
311
+ validationResults.overall.toolsPassed++;
312
+ } else {
313
+ validationResults.overall.toolsFailed++;
314
+ validationResults.overall.success = false;
315
+ validationResults.overall.totalIssues += result.checks.issues.length;
316
+ }
317
+ }
318
+ }
319
+
320
+ return validationResults;
321
+ }
322
+
323
+ /**
324
+ * Simplified validation with clean interface
325
+ * @param {Array} selectedTools - Tools to validate
326
+ * @param {string} language - Language code
327
+ * @returns {Promise<Object>} Validation results
328
+ */
329
+ export async function validateInstallation(selectedTools, language) {
330
+ const results = {
331
+ success: [],
332
+ failed: [],
333
+ warnings: []
334
+ };
335
+
336
+ // Always validate common files (AIWF core)
337
+ const commonValid = await validateCommonFiles();
338
+ if (!commonValid.success) {
339
+ results.failed.push({ tool: 'aiwf', reason: commonValid.reason });
340
+ } else {
341
+ results.success.push('aiwf');
342
+ }
343
+
344
+ // Validate selected tools
345
+ if (selectedTools && selectedTools.length > 0) {
346
+ for (const tool of selectedTools) {
347
+ const validation = await validateTool(tool);
348
+ if (validation.success) {
349
+ results.success.push(tool);
350
+ } else {
351
+ results.failed.push({ tool, reason: validation.reason });
352
+ }
353
+ }
354
+ } else {
355
+ // Default: validate all tools if no selection provided
356
+ const allTools = ['claudeCode', 'geminiCLI', 'cursor', 'windsurf'];
357
+ for (const tool of allTools) {
358
+ const validation = await validateTool(tool);
359
+ if (validation.success) {
360
+ results.success.push(tool);
361
+ } else {
362
+ results.failed.push({ tool, reason: validation.reason });
363
+ }
364
+ }
365
+ }
366
+
367
+ return results;
368
+ }
369
+
370
+ /**
371
+ * Validate common/core files
372
+ * @returns {Promise<Object>} Validation result
373
+ */
374
+ async function validateCommonFiles() {
375
+ try {
376
+ const requiredFiles = [
377
+ FILES.CLAUDE_MD.ROOT,
378
+ FILES.PROJECT_MANIFEST
379
+ ];
380
+
381
+ for (const file of requiredFiles) {
382
+ const exists = await fs
383
+ .access(file)
384
+ .then(() => true)
385
+ .catch(() => false);
386
+ if (!exists) {
387
+ return { success: false, reason: `Missing core file: ${file}` };
388
+ }
389
+ }
390
+
391
+ return { success: true };
392
+ } catch (error) {
393
+ return { success: false, reason: `Core validation error: ${error.message}` };
394
+ }
395
+ }
396
+
397
+ /**
398
+ * Validate specific tool
399
+ * @param {string} tool - Tool name
400
+ * @returns {Promise<Object>} Validation result
401
+ */
402
+ async function validateTool(tool) {
403
+ switch (tool) {
404
+ case 'claudeCode':
405
+ case 'claude-code':
406
+ return validateClaudeCode();
407
+ case 'geminiCLI':
408
+ case 'gemini-cli':
409
+ return validateGeminiCLI();
410
+ case 'cursor':
411
+ return validateCursorTool();
412
+ case 'windsurf':
413
+ return validateWindsurfTool();
414
+ case 'aiwf':
415
+ return validateCommonFiles();
416
+ default:
417
+ return { success: false, reason: `Unknown tool: ${tool}` };
418
+ }
419
+ }
420
+
421
+ /**
422
+ * Validate Claude Code with simplified interface
423
+ * @returns {Promise<Object>} Validation result
424
+ */
425
+ async function validateClaudeCode() {
426
+ try {
427
+ const requiredFiles = [
428
+ 'aiwf_initialize.md',
429
+ 'aiwf_do_task.md',
430
+ 'aiwf_commit.md',
431
+ 'aiwf_code_review.md'
432
+ ];
433
+
434
+ for (const fileName of requiredFiles) {
435
+ const filePath = path.join(TOOL_DIRS.CLAUDE_COMMANDS, fileName);
436
+ const exists = await fs
437
+ .access(filePath)
438
+ .then(() => true)
439
+ .catch(() => false);
440
+ if (!exists) {
441
+ return { success: false, reason: `Missing file: ${filePath}` };
442
+ }
443
+ }
444
+
445
+ return { success: true };
446
+ } catch (error) {
447
+ return { success: false, reason: `Claude Code validation error: ${error.message}` };
448
+ }
449
+ }
450
+
451
+ /**
452
+ * Validate Gemini CLI with simplified interface
453
+ * @returns {Promise<Object>} Validation result
454
+ */
455
+ async function validateGeminiCLI() {
456
+ try {
457
+ const dirExists = await fs
458
+ .access(TOOL_DIRS.GEMINI_PROMPTS)
459
+ .then(() => true)
460
+ .catch(() => false);
461
+ if (!dirExists) {
462
+ return {
463
+ success: false,
464
+ reason: `Missing Gemini-CLI prompts directory: ${TOOL_DIRS.GEMINI_PROMPTS}`
465
+ };
466
+ }
467
+
468
+ return { success: true };
469
+ } catch (error) {
470
+ return { success: false, reason: `Gemini-CLI validation error: ${error.message}` };
471
+ }
472
+ }
473
+
474
+ /**
475
+ * Validate Cursor tool with simplified interface
476
+ * @returns {Promise<Object>} Validation result
477
+ */
478
+ async function validateCursorTool() {
479
+ try {
480
+ const dirExists = await fs
481
+ .access(TOOL_DIRS.CURSOR_RULES)
482
+ .then(() => true)
483
+ .catch(() => false);
484
+ if (!dirExists) {
485
+ return { success: false, reason: `Missing Cursor rules directory: ${TOOL_DIRS.CURSOR_RULES}` };
486
+ }
487
+
488
+ return { success: true };
489
+ } catch (error) {
490
+ return { success: false, reason: `Cursor validation error: ${error.message}` };
491
+ }
492
+ }
493
+
494
+ /**
495
+ * Validate Windsurf tool with simplified interface
496
+ * @returns {Promise<Object>} Validation result
497
+ */
498
+ async function validateWindsurfTool() {
499
+ try {
500
+ const dirExists = await fs
501
+ .access(TOOL_DIRS.WINDSURF_RULES)
502
+ .then(() => true)
503
+ .catch(() => false);
504
+ if (!dirExists) {
505
+ return { success: false, reason: `Missing Windsurf rules directory: ${TOOL_DIRS.WINDSURF_RULES}` };
506
+ }
507
+
508
+ return { success: true };
509
+ } catch (error) {
510
+ return { success: false, reason: `Windsurf validation error: ${error.message}` };
511
+ }
512
+ }
513
+
514
+ /**
515
+ * Display validation results in spec-compliant format
516
+ * @param {Object} validationResults - Validation results
517
+ * @param {string} language - Language code
518
+ */
519
+ export function displaySpecCompliantValidationResults(validationResults, language) {
520
+ console.log(chalk.blue('\n=== Installation Validation Results ==='));
521
+
522
+ // Success summary
523
+ if (validationResults.success.length > 0) {
524
+ console.log(
525
+ chalk.green(`\n✅ Successfully Validated Tools (${validationResults.success.length}):`)
526
+ );
527
+ validationResults.success.forEach(tool => {
528
+ console.log(chalk.green(` ✓ ${tool}`));
529
+ });
530
+ }
531
+
532
+ // Failed summary
533
+ if (validationResults.failed.length > 0) {
534
+ console.log(chalk.red(`\n❌ Failed Validations (${validationResults.failed.length}):`));
535
+ validationResults.failed.forEach(({ tool, reason }) => {
536
+ console.log(chalk.red(` ✗ ${tool}: ${reason}`));
537
+ });
538
+ }
539
+
540
+ // Warnings summary
541
+ if (validationResults.warnings.length > 0) {
542
+ console.log(chalk.yellow(`\n⚠️ Warnings (${validationResults.warnings.length}):`));
543
+ validationResults.warnings.forEach(warning => {
544
+ console.log(chalk.yellow(` ⚠ ${warning}`));
545
+ });
546
+ }
547
+
548
+ // Overall status
549
+ const isSuccess = validationResults.failed.length === 0;
550
+ const statusIcon = isSuccess ? '✅' : '❌';
551
+ const statusColor = isSuccess ? chalk.green : chalk.red;
552
+ const statusText = isSuccess ? 'PASSED' : 'FAILED';
553
+
554
+ console.log(statusColor(`\n${statusIcon} Overall Validation: ${statusText}`));
555
+
556
+ if (isSuccess) {
557
+ console.log(chalk.green('🎉 All selected tools are properly installed and validated!'));
558
+ } else {
559
+ console.log(chalk.yellow('⚠️ Some installations failed. See details above.'));
560
+ }
561
+ }