aiwf 0.3.20 → 0.3.21

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aiwf",
3
- "version": "0.3.20",
3
+ "version": "0.3.21",
4
4
  "description": "AI Workflow Framework for Claude Code with multi-language support (Korean/English)",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -483,7 +483,7 @@ async function updateCommands(languagePath, spinner, msg, debugLog) {
483
483
  spinner,
484
484
  msg,
485
485
  languagePath,
486
- false // commands는 기존 방식 유지 (파일 리스트 사용)
486
+ true // commands도 동적 디렉터리 탐색 사용 (파일 리스트 의존 제거)
487
487
  );
488
488
  } catch (error) {
489
489
  logWithSpinner(spinner, msg.commandsNotFound, debugLog);
@@ -498,7 +498,7 @@ async function updateCommands(languagePath, spinner, msg, debugLog) {
498
498
  spinner,
499
499
  msg,
500
500
  languagePath,
501
- false // agents도 기존 방식 유지 (파일 리스트 사용)
501
+ true // agents도 동적 디렉터리 탐색 사용 (파일 리스트 의존 제거)
502
502
  );
503
503
  logWithSpinner(spinner, 'Successfully downloaded agents', debugLog);
504
504
  } catch (error) {
@@ -119,14 +119,37 @@ async function validateTool(tool) {
119
119
  */
120
120
  async function validateClaudeCode() {
121
121
  try {
122
- const requiredFiles = [
122
+ // 기본 필수 파일 (현재 리포지토리에 존재하는 핵심 명령어)
123
+ const baseRequired = [
123
124
  'aiwf_initialize.md',
124
125
  'aiwf_do_task.md',
125
- 'aiwf_commit.md',
126
- 'aiwf_code_review.md'
126
+ 'aiwf_commit.md'
127
+ ];
128
+
129
+ // 과거 필수였던 리뷰 명령어의 대체 후보들
130
+ const reviewPrimary = 'aiwf_code_review.md';
131
+ const reviewAlternatives = [
132
+ 'aiwf_yolo.md',
133
+ 'aiwf_prime.md',
134
+ 'aiwf_agent_workflow.md'
127
135
  ];
128
136
 
129
- for (const fileName of requiredFiles) {
137
+ // 디렉토리 존재 및 파일 개수 간단 점검
138
+ const dirExists = await fs
139
+ .access(TOOL_DIRS.CLAUDE_COMMANDS)
140
+ .then(() => true)
141
+ .catch(() => false);
142
+ if (!dirExists) {
143
+ return { success: false, reason: `Missing Claude commands directory: ${TOOL_DIRS.CLAUDE_COMMANDS}` };
144
+ }
145
+
146
+ const allFiles = await fs.readdir(TOOL_DIRS.CLAUDE_COMMANDS);
147
+ if (allFiles.length < VALIDATION_CONSTANTS.MIN_FILE_COUNT.CLAUDE_COMMANDS) {
148
+ return { success: false, reason: `Insufficient Claude commands files: expected at least ${VALIDATION_CONSTANTS.MIN_FILE_COUNT.CLAUDE_COMMANDS}, found ${allFiles.length}` };
149
+ }
150
+
151
+ // 기본 필수 파일 존재/크기 확인
152
+ for (const fileName of baseRequired) {
130
153
  const filePath = path.join(TOOL_DIRS.CLAUDE_COMMANDS, fileName);
131
154
  const exists = await fs
132
155
  .access(filePath)
@@ -135,8 +158,6 @@ async function validateClaudeCode() {
135
158
  if (!exists) {
136
159
  return { success: false, reason: `Missing file: ${filePath}` };
137
160
  }
138
-
139
- // Check file size
140
161
  try {
141
162
  const stats = await fs.stat(filePath);
142
163
  if (stats.size < VALIDATION_CONSTANTS.MIN_FILE_SIZE) {
@@ -147,6 +168,35 @@ async function validateClaudeCode() {
147
168
  }
148
169
  }
149
170
 
171
+ // 리뷰 명령어: 기본 파일 또는 대체 파일 중 하나라도 존재하면 통과
172
+ const reviewPrimaryPath = path.join(TOOL_DIRS.CLAUDE_COMMANDS, reviewPrimary);
173
+ const primaryExists = await fs.access(reviewPrimaryPath).then(() => true).catch(() => false);
174
+
175
+ let alternativeUsed = null;
176
+ if (!primaryExists) {
177
+ for (const alt of reviewAlternatives) {
178
+ const altPath = path.join(TOOL_DIRS.CLAUDE_COMMANDS, alt);
179
+ const altExists = await fs.access(altPath).then(() => true).catch(() => false);
180
+ if (altExists) {
181
+ alternativeUsed = alt;
182
+ // 크기 확인
183
+ try {
184
+ const stats = await fs.stat(altPath);
185
+ if (stats.size < VALIDATION_CONSTANTS.MIN_FILE_SIZE) {
186
+ return { success: false, reason: `File ${alt} is too small (${stats.size} bytes)` };
187
+ }
188
+ } catch (error) {
189
+ return { success: false, reason: `Cannot read file ${alt}: ${error.message}` };
190
+ }
191
+ break;
192
+ }
193
+ }
194
+ }
195
+
196
+ if (!primaryExists && !alternativeUsed) {
197
+ return { success: false, reason: `Missing file: ${reviewPrimary} (or one of alternatives: ${reviewAlternatives.join(', ')})` };
198
+ }
199
+
150
200
  return { success: true };
151
201
  } catch (error) {
152
202
  return { success: false, reason: `Claude Code validation error: ${error.message}` };