aiwf 0.3.14 → 0.3.16

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 (54) hide show
  1. package/README.ko.md +19 -10
  2. package/README.md +54 -9
  3. package/docs/AI-WORKFLOW.ko.md +1 -1
  4. package/docs/AI-WORKFLOW.md +1 -1
  5. package/docs/API_REFERENCE_FULL.ko.md +979 -0
  6. package/docs/API_REFERENCE_FULL.md +979 -0
  7. package/docs/ARCHITECTURE.ko.md +314 -0
  8. package/docs/ARCHITECTURE.md +314 -0
  9. package/docs/GETTING_STARTED.ko.md +219 -0
  10. package/docs/GETTING_STARTED.md +1 -2
  11. package/docs/PERFORMANCE_GUIDELINES.ko.md +388 -0
  12. package/docs/ROADMAP_v0.4.0.md +286 -0
  13. package/docs/TROUBLESHOOTING.ko.md +366 -0
  14. package/package.json +50 -2
  15. package/src/DEPENDENCY_MAP.md +90 -0
  16. package/src/cli/index.js +1 -1
  17. package/src/lib/installer.js +204 -15
  18. package/src/lib/resources/templates/api-server/template/src/controllers/aiwfController.ts +0 -14
  19. package/src/lib/resources/templates/api-server/template/src/routes/aiwf.ts +0 -11
  20. package/src/lib/resources/templates/web-app/template/src/pages/AiwfDashboard.tsx +2 -5
  21. package/src/lib/resources/utils/token-reporter.js +2 -3
  22. package/src/utils/checkpoint-manager.js +11 -1
  23. package/src/utils/engineering-guard.js +11 -1
  24. package/src/utils/messages.js +16 -0
  25. package/src/utils/paths.js +2 -2
  26. package/templates/api-server/template/src/controllers/aiwfController.ts +0 -14
  27. package/templates/api-server/template/src/routes/aiwf.ts +0 -11
  28. package/templates/web-app/template/src/pages/AiwfDashboard.tsx +2 -5
  29. package/docs/CLEANUP_RECOMMENDATIONS.md +0 -86
  30. package/docs/git-feature-integration-guide.md +0 -253
  31. package/docs/guides/feature-git-integration-guide-ko.md +0 -481
  32. package/docs/guides/feature-git-integration-guide.md +0 -481
  33. package/docs/lightweight-evaluation.md +0 -198
  34. package/docs/performance-benchmark-report.md +0 -159
  35. package/docs/reports/S02-sprint-report.md +0 -190
  36. package/docs/usability-test-report.md +0 -170
  37. package/src/commands/cache-templates.js +0 -209
  38. package/src/commands/create-offline.js +0 -86
  39. package/src/commands/state-refactored.js +0 -419
  40. package/src/lib/resources/commands/feature-ledger.js +0 -565
  41. package/src/lib/resources/commands/feature_commit_report.js +0 -370
  42. package/src/lib/resources/commands/scan_git_history.js +0 -234
  43. package/src/lib/resources/commands/sync_feature_commits.js +0 -154
  44. package/src/lib/resources/templates/web-app/template/src/components/aiwf/FeatureLedger.tsx +0 -93
  45. package/src/lib/resources/utils/feature-updater.js +0 -271
  46. package/src/utils/git-integration.js +0 -173
  47. package/templates/web-app/template/src/components/aiwf/FeatureLedger.tsx +0 -93
  48. /package/docs/{AI_PERSONA_SYSTEM_DESIGN.md → designs/AI_PERSONA_SYSTEM_DESIGN.md} +0 -0
  49. /package/docs/{API_DOCUMENTATION.md → designs/API_DOCUMENTATION.md} +0 -0
  50. /package/docs/{API_REFERENCE.md → designs/API_REFERENCE.md} +0 -0
  51. /package/docs/{Enhanced_Installation_Flow_Design.md → designs/Enhanced_Installation_Flow_Design.md} +0 -0
  52. /package/docs/{moonklabs-metadata-system-prd.md → designs/aiwf-metadata-system-prd.md} +0 -0
  53. /package/docs/{offline-template-cache.md → designs/offline-template-cache.md} +0 -0
  54. /package/docs/{persona-aware-compression.md → designs/persona-aware-compression.md} +0 -0
@@ -0,0 +1,90 @@
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/` 으로 사용처 확인
package/src/cli/index.js CHANGED
@@ -35,7 +35,7 @@ program
35
35
  program
36
36
  .command('install')
37
37
  .description('Install AIWF framework')
38
- .option('-f, --force', 'Force install without prompts')
38
+ .option('-f, --force', 'Force complete reinstall without prompts')
39
39
  .action((options) => installAIWF({ ...options, debugLog: true }));
40
40
 
41
41
  // AI Tool command
@@ -36,6 +36,7 @@ import {
36
36
  TOOL_DIRS,
37
37
  TEMP_DIRS,
38
38
  AIWF_DIRS,
39
+ BASE_DIRS,
39
40
  getAllAiwfDirectories,
40
41
  getAllClaudeMdFiles
41
42
  } from '../utils/paths.js';
@@ -52,6 +53,61 @@ async function checkExistingInstallation() {
52
53
  return flagExists;
53
54
  }
54
55
 
56
+ /**
57
+ * Check if existing project files exist
58
+ * @returns {Promise<{hasProject: boolean, projectFiles: string[]}>} Project status
59
+ */
60
+ async function checkExistingProject() {
61
+ const projectFiles = [];
62
+ let hasProject = false;
63
+
64
+ // Check for key project files
65
+ const keyFiles = [
66
+ FILES.PROJECT_MANIFEST,
67
+ path.join(AIWF_DIRS.PROJECT_DOCS, 'README.md'),
68
+ path.join(AIWF_DIRS.REQUIREMENTS, 'requirements.md'),
69
+ path.join(AIWF_DIRS.SPRINTS, 'sprint-01.md'),
70
+ path.join(AIWF_DIRS.GENERAL_TASKS, 'tasks.md'),
71
+ path.join(AIWF_DIRS.ARCHITECTURAL_DECISIONS, 'decisions.md'),
72
+ path.join(AIWF_DIRS.STATE_OF_PROJECT, 'current-state.md')
73
+ ];
74
+
75
+ for (const file of keyFiles) {
76
+ try {
77
+ await fs.access(file);
78
+ projectFiles.push(file);
79
+ hasProject = true;
80
+ } catch (error) {
81
+ // File doesn't exist, continue
82
+ }
83
+ }
84
+
85
+ // Check for any .md files in project directories
86
+ const projectDirs = [
87
+ AIWF_DIRS.PROJECT_DOCS,
88
+ AIWF_DIRS.REQUIREMENTS,
89
+ AIWF_DIRS.SPRINTS,
90
+ AIWF_DIRS.GENERAL_TASKS,
91
+ AIWF_DIRS.ARCHITECTURAL_DECISIONS,
92
+ AIWF_DIRS.STATE_OF_PROJECT
93
+ ];
94
+
95
+ for (const dir of projectDirs) {
96
+ try {
97
+ const files = await fs.readdir(dir);
98
+ const mdFiles = files.filter(file => file.endsWith('.md'));
99
+ if (mdFiles.length > 0) {
100
+ hasProject = true;
101
+ projectFiles.push(...mdFiles.map(file => path.join(dir, file)));
102
+ }
103
+ } catch (error) {
104
+ // Directory doesn't exist, continue
105
+ }
106
+ }
107
+
108
+ return { hasProject, projectFiles };
109
+ }
110
+
55
111
  /**
56
112
  * Log with spinner for debug mode
57
113
  * @param {Object} spinner - Ora spinner instance
@@ -146,34 +202,145 @@ async function selectLanguage(options) {
146
202
  * Handle existing installation
147
203
  * @param {Object} msg - Localized messages
148
204
  * @param {Object} options - Installation options
149
- * @returns {Promise<boolean>} Continue with installation
205
+ * @returns {Promise<{continue: boolean, installType: string, preserveProject: boolean}>} Installation decision
150
206
  */
151
207
  async function handleExistingInstallation(msg, options) {
208
+
152
209
  if (options.force) {
153
- return true;
210
+ return { continue: true, installType: 'reinstall', preserveProject: false };
154
211
  }
155
212
 
156
- const response = await prompts({
213
+ // First, ask about installation type
214
+ const installResponse = await prompts({
157
215
  type: 'select',
158
216
  name: 'action',
159
217
  message: msg.existingDetected,
160
218
  choices: [
161
219
  { title: msg.updateOption, value: 'update' },
220
+ { title: msg.reinstallOption, value: 'reinstall' },
162
221
  { title: msg.skipOption, value: 'skip' },
163
222
  { title: msg.cancelOption, value: 'cancel' }
164
223
  ]
165
224
  });
166
225
 
167
- if (response.action === 'skip' || response.action === 'cancel') {
226
+
227
+
228
+ if (installResponse.action === 'skip' || installResponse.action === 'cancel') {
168
229
  console.log(chalk.yellow(msg.installCancelled));
169
230
  process.exit(0);
170
231
  }
171
232
 
172
- if (response.action === 'update') {
233
+ let preserveProject = true; // Default to preserve
234
+
235
+ // If reinstalling, don't preserve project (complete fresh install)
236
+ if (installResponse.action === 'reinstall') {
237
+ preserveProject = false;
238
+ }
239
+
240
+ // Backup if updating
241
+ if (installResponse.action === 'update') {
173
242
  await backupCommandsAndDocs(msg);
174
243
  }
175
244
 
176
- return true;
245
+ return {
246
+ continue: true,
247
+ installType: installResponse.action,
248
+ preserveProject
249
+ };
250
+ }
251
+
252
+ /**
253
+ * Backup project files
254
+ * @param {string[]} projectFiles - List of project files to backup
255
+ * @param {Object} msg - Localized messages
256
+ * @returns {Promise<string>} Backup directory path
257
+ */
258
+ async function backupProjectFiles(projectFiles, msg) {
259
+ if (projectFiles.length === 0) {
260
+ return null;
261
+ }
262
+
263
+ const backupDir = path.join(os.tmpdir(), `aiwf-project-backup-${Date.now()}`);
264
+ await fs.mkdir(backupDir, { recursive: true });
265
+
266
+ console.log(chalk.cyan('💾 Backing up project files...'));
267
+
268
+ for (const file of projectFiles) {
269
+ try {
270
+ const relativePath = path.relative(process.cwd(), file);
271
+ const backupPath = path.join(backupDir, relativePath);
272
+ const backupDirPath = path.dirname(backupPath);
273
+
274
+ await fs.mkdir(backupDirPath, { recursive: true });
275
+ await fs.copyFile(file, backupPath);
276
+ } catch (error) {
277
+ console.log(chalk.yellow(`Warning: Could not backup ${file}: ${error.message}`));
278
+ }
279
+ }
280
+
281
+ console.log(chalk.green(`✅ Project files backed up to: ${backupDir}`));
282
+ return backupDir;
283
+ }
284
+
285
+ /**
286
+ * Restore project files from backup
287
+ * @param {string} backupDir - Backup directory path
288
+ * @param {Object} msg - Localized messages
289
+ */
290
+ async function restoreProjectFiles(backupDir, msg) {
291
+ if (!backupDir) {
292
+ return;
293
+ }
294
+
295
+ console.log(chalk.cyan('🔄 Restoring project files...'));
296
+
297
+ try {
298
+ const backupFiles = await fs.readdir(backupDir, { recursive: true });
299
+
300
+ for (const file of backupFiles) {
301
+ const backupFilePath = path.join(backupDir, file);
302
+ const stat = await fs.stat(backupFilePath);
303
+
304
+ if (stat.isFile()) {
305
+ const targetPath = path.join(process.cwd(), file);
306
+ const targetDir = path.dirname(targetPath);
307
+
308
+ await fs.mkdir(targetDir, { recursive: true });
309
+ await fs.copyFile(backupFilePath, targetPath);
310
+ }
311
+ }
312
+
313
+ console.log(chalk.green(msg.projectPreserved));
314
+
315
+ // Clean up backup directory
316
+ await fs.rm(backupDir, { recursive: true, force: true });
317
+ } catch (error) {
318
+ console.log(chalk.yellow(`Warning: Could not restore some project files: ${error.message}`));
319
+ console.log(chalk.yellow(`Backup preserved at: ${backupDir}`));
320
+ }
321
+ }
322
+
323
+ /**
324
+ * Remove project files
325
+ * @param {string[]} projectFiles - List of project files to remove
326
+ * @param {Object} msg - Localized messages
327
+ */
328
+ async function removeProjectFiles(projectFiles, msg) {
329
+ if (projectFiles.length === 0) {
330
+ return;
331
+ }
332
+
333
+ console.log(chalk.cyan('🗑️ Removing existing project files...'));
334
+
335
+ for (const file of projectFiles) {
336
+ try {
337
+ await fs.unlink(file);
338
+ } catch (error) {
339
+ // File might already be deleted, continue
340
+ }
341
+ }
342
+
343
+ console.log(chalk.green(msg.projectOverwritten));
177
344
  }
178
345
 
179
346
  /**
@@ -609,9 +776,22 @@ export async function installAIWF(options = {}) {
609
776
  // Check existing installation
610
777
  const hasExisting = await checkExistingInstallation();
611
778
 
779
+ let installDecision = { continue: true, installType: 'fresh', preserveProject: false };
780
+ let projectBackupDir = null;
781
+
612
782
  if (hasExisting) {
613
- const shouldContinue = await handleExistingInstallation(msg, options);
614
- if (!shouldContinue) return;
783
+
784
+ installDecision = await handleExistingInstallation(msg, options);
785
+
786
+ if (!installDecision.continue) return;
787
+
788
+ // If reinstalling and preserving project, backup project files
789
+ if (installDecision.installType === 'reinstall' && installDecision.preserveProject) {
790
+ const { hasProject, projectFiles } = await checkExistingProject();
791
+ if (hasProject) {
792
+ projectBackupDir = await backupProjectFiles(projectFiles, msg);
793
+ }
794
+ }
615
795
  }
616
796
 
617
797
  const spinner = ora(msg.fetching).start();
@@ -620,16 +800,20 @@ export async function installAIWF(options = {}) {
620
800
  // Create directory structure
621
801
  await createDirectoryStructure();
622
802
 
623
- // Download manifest (fresh installs only)
624
- if (!hasExisting) {
803
+ // Download manifest (fresh installs only or complete reinstall)
804
+ if (!hasExisting || installDecision.installType === 'reinstall') {
625
805
  await downloadManifest(languagePath, spinner, msg, debugLog);
626
806
  }
627
807
 
628
- // Download templates
629
- await downloadTemplates(languagePath, spinner, msg, debugLog);
808
+ // Download templates (fresh installs and complete reinstall only)
809
+ if (!hasExisting || installDecision.installType === 'reinstall') {
810
+ await downloadTemplates(languagePath, spinner, msg, debugLog);
811
+ }
630
812
 
631
- // Update documentation
632
- await updateDocumentation(languagePath, spinner, msg, debugLog);
813
+ // Update documentation (fresh installs and complete reinstall only)
814
+ if (!hasExisting || installDecision.installType === 'reinstall') {
815
+ await updateDocumentation(languagePath, spinner, msg, debugLog);
816
+ }
633
817
 
634
818
  // Update commands
635
819
  await updateCommands(languagePath, spinner, msg, debugLog);
@@ -637,8 +821,13 @@ export async function installAIWF(options = {}) {
637
821
  // Download and process rules
638
822
  await downloadAndProcessRules(spinner, msg, debugLog);
639
823
 
824
+ // Restore project files if needed
825
+ if (projectBackupDir) {
826
+ await restoreProjectFiles(projectBackupDir, msg);
827
+ }
828
+
640
829
  // Success
641
- if (hasExisting) {
830
+ if (hasExisting && installDecision.installType === 'update') {
642
831
  spinner.succeed(chalk.green(msg.updateSuccess));
643
832
  } else {
644
833
  spinner.succeed(chalk.green(msg.installSuccess));
@@ -3,20 +3,6 @@ import fs from 'fs/promises';
3
3
  import path from 'path';
4
4
 
5
5
  export const aiwfController = {
6
- getFeatures: async (req: Request, res: Response, next: NextFunction) => {
7
- try {
8
- const ledgerPath = path.join(process.cwd(), '.aiwf', 'feature-ledger.json');
9
- const ledgerData = await fs.readFile(ledgerPath, 'utf-8');
10
- const ledger = JSON.parse(ledgerData);
11
-
12
- res.json({
13
- success: true,
14
- data: ledger,
15
- });
16
- } catch (error) {
17
- next(error);
18
- }
19
- },
20
6
 
21
7
  getTokenUsage: async (req: Request, res: Response, next: NextFunction) => {
22
8
  try {
@@ -3,17 +3,6 @@ import { aiwfController } from '@controllers/aiwfController';
3
3
 
4
4
  const router = Router();
5
5
 
6
- /**
7
- * @swagger
8
- * /api/aiwf/features:
9
- * get:
10
- * summary: Feature Ledger 조회
11
- * tags: [AIWF]
12
- * responses:
13
- * 200:
14
- * description: Feature 목록
15
- */
16
- router.get('/features', aiwfController.getFeatures);
17
6
 
18
7
  /**
19
8
  * @swagger
@@ -1,19 +1,17 @@
1
1
  import { useState, useEffect } from 'react'
2
2
  import { useAiwfStore } from '@/stores/aiwfStore'
3
- import FeatureLedger from '@/components/aiwf/FeatureLedger'
4
3
  import TokenUsage from '@/components/aiwf/TokenUsage'
5
4
  import ContextStatus from '@/components/aiwf/ContextStatus'
6
5
 
7
6
  export default function AiwfDashboard() {
8
- const { features, tokenUsage, contextStatus, loadDashboardData } = useAiwfStore()
9
- const [activeTab, setActiveTab] = useState('features')
7
+ const { tokenUsage, contextStatus, loadDashboardData } = useAiwfStore()
8
+ const [activeTab, setActiveTab] = useState('tokens')
10
9
 
11
10
  useEffect(() => {
12
11
  loadDashboardData()
13
12
  }, [loadDashboardData])
14
13
 
15
14
  const tabs = [
16
- { id: 'features', name: 'Feature Ledger', icon: '📋' },
17
15
  { id: 'tokens', name: '토큰 사용량', icon: '🪙' },
18
16
  { id: 'context', name: 'Context 상태', icon: '📊' },
19
17
  ]
@@ -51,7 +49,6 @@ export default function AiwfDashboard() {
51
49
  </div>
52
50
 
53
51
  <div className="mt-8">
54
- {activeTab === 'features' && <FeatureLedger features={features} />}
55
52
  {activeTab === 'tokens' && <TokenUsage usage={tokenUsage} />}
56
53
  {activeTab === 'context' && <ContextStatus status={contextStatus} />}
57
54
  </div>
@@ -37,9 +37,8 @@ export class TokenReporter {
37
37
  '.aiwf/02_REQUIREMENTS',
38
38
  '.aiwf/03_SPRINTS',
39
39
  '.aiwf/04_GENERAL_TASKS',
40
- '.aiwf/05_COMPLETED_TASKS',
41
- '.aiwf/06_FEATURE_LEDGERS',
42
- '.aiwf/07_AI_PERSONAS'
40
+ '.aiwf/05_ARCHITECTURAL_DECISIONS',
41
+ '.aiwf/10_STATE_OF_PROJECT'
43
42
  ];
44
43
 
45
44
  // 각 디렉토리별 토큰 수 분석
@@ -1,6 +1,16 @@
1
1
  /**
2
- * YOLO 모드 체크포인트 매니저
2
+ * Checkpoint Manager - YOLO 모드 체크포인트 매니저
3
+ *
4
+ * @usage YOLO 모드 및 CLI 명령어에서 사용
5
+ * @used_by src/cli/index.js, src/cli/checkpoint-cli.js
6
+ * @commands aiwf checkpoint, aiwf-checkpoint
7
+ * @warning 삭제 금지 - YOLO 시스템 핵심 구성 요소
8
+ *
3
9
  * 진행 상황을 저장하고 복구할 수 있는 시스템
10
+ * - 세션 상태 관리
11
+ * - 체크포인트 생성/복구
12
+ * - 진행률 추적
13
+ * - 복구 가능한 상태 유지
4
14
  */
5
15
 
6
16
  import fs from 'fs/promises';
@@ -1,6 +1,16 @@
1
1
  /**
2
- * 오버엔지니어링 방지 가드
2
+ * Engineering Guard - 오버엔지니어링 방지 가드
3
+ *
4
+ * @usage YOLO 모드 전용 - 동적 import로 사용됨
5
+ * @used_by /claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_yolo.md
6
+ * @phase 프로젝트 복잡도 모니터링 (5단계)
7
+ * @warning 삭제 금지 - YOLO 시스템 핵심 구성 요소
8
+ *
3
9
  * YOLO 모드에서 과도한 복잡성을 방지하는 유틸리티
10
+ * - 초기 복잡도 측정
11
+ * - 사전 체크 및 실시간 모니터링
12
+ * - 태스크 완료 후 검증
13
+ * - 최종 보고서 생성
4
14
  */
5
15
 
6
16
  import fs from 'fs/promises';
@@ -11,8 +11,16 @@ export const messages = {
11
11
  english: 'English',
12
12
  existingDetected: '기존 AIWF 설치가 감지되었습니다. 무엇을 하시겠습니까?',
13
13
  updateOption: '업데이트 (명령어와 문서만 업데이트하고 작업 내용은 보존)',
14
+ reinstallOption: '완전 재설치 (모든 내용을 새로 설치, 기존 프로젝트 덮어쓰기)',
14
15
  skipOption: '설치 건너뛰기',
15
16
  cancelOption: '취소',
17
+ projectDetected: '기존 프로젝트가 감지되었습니다. 프로젝트 파일을 어떻게 처리하시겠습니까?',
18
+ preserveProject: '프로젝트 보존 (기존 프로젝트 파일 유지)',
19
+ overwriteProject: '덮어쓰기 (새로 설치하고 기존 프로젝트 삭제)',
20
+ checkingProject: '기존 프로젝트 확인 중...',
21
+ projectFound: '기존 프로젝트가 발견되었습니다:',
22
+ projectPreserved: '💾 프로젝트가 보존되었습니다.',
23
+ projectOverwritten: '🔄 프로젝트가 새로 설치되었습니다.',
16
24
  installCancelled: '\n설치가 취소되었습니다.',
17
25
  backingUp: '기존 명령어 및 문서 백업 중...',
18
26
  fetching: 'GitHub에서 AIWF 프레임워크를 가져오는 중...',
@@ -72,8 +80,16 @@ export const messages = {
72
80
  english: 'English',
73
81
  existingDetected: 'Existing AIWF installation detected. What would you like to do?',
74
82
  updateOption: 'Update (Update commands and docs only, preserve work content)',
83
+ reinstallOption: 'Complete reinstall (Install everything fresh, overwrite existing project)',
75
84
  skipOption: 'Skip installation',
76
85
  cancelOption: 'Cancel',
86
+ projectDetected: 'Existing project detected. How would you like to handle project files?',
87
+ preserveProject: 'Preserve project (Keep existing project files)',
88
+ overwriteProject: 'Overwrite (Fresh install and remove existing project)',
89
+ checkingProject: 'Checking for existing project...',
90
+ projectFound: 'Existing project found:',
91
+ projectPreserved: '💾 Project has been preserved.',
92
+ projectOverwritten: '🔄 Project has been freshly installed.',
77
93
  installCancelled: '\nInstallation cancelled.',
78
94
  backingUp: 'Backing up existing commands and documents...',
79
95
  fetching: 'Fetching AIWF framework from GitHub...',
@@ -22,7 +22,7 @@ export const AIWF_DIRS = {
22
22
  REQUIREMENTS: path.join(BASE_DIRS.AIWF, '02_REQUIREMENTS'),
23
23
  SPRINTS: path.join(BASE_DIRS.AIWF, '03_SPRINTS'),
24
24
  GENERAL_TASKS: path.join(BASE_DIRS.AIWF, '04_GENERAL_TASKS'),
25
- ARCHITECTURE_DECISIONS: path.join(BASE_DIRS.AIWF, '05_ARCHITECTURE_DECISIONS'),
25
+ ARCHITECTURAL_DECISIONS: path.join(BASE_DIRS.AIWF, '05_ARCHITECTURAL_DECISIONS'),
26
26
  STATE_OF_PROJECT: path.join(BASE_DIRS.AIWF, '10_STATE_OF_PROJECT'),
27
27
  PROMPTS: path.join(BASE_DIRS.AIWF, '98_PROMPTS'),
28
28
  TEMPLATES: path.join(BASE_DIRS.AIWF, '99_TEMPLATES'),
@@ -77,7 +77,7 @@ export function getAllAiwfDirectories() {
77
77
  AIWF_DIRS.REQUIREMENTS,
78
78
  AIWF_DIRS.SPRINTS,
79
79
  AIWF_DIRS.GENERAL_TASKS,
80
- AIWF_DIRS.ARCHITECTURE_DECISIONS,
80
+ AIWF_DIRS.ARCHITECTURAL_DECISIONS,
81
81
  AIWF_DIRS.STATE_OF_PROJECT,
82
82
  AIWF_DIRS.PROMPTS,
83
83
  AIWF_DIRS.TEMPLATES
@@ -3,20 +3,6 @@ import fs from 'fs/promises';
3
3
  import path from 'path';
4
4
 
5
5
  export const aiwfController = {
6
- getFeatures: async (req: Request, res: Response, next: NextFunction) => {
7
- try {
8
- const ledgerPath = path.join(process.cwd(), '.aiwf', 'feature-ledger.json');
9
- const ledgerData = await fs.readFile(ledgerPath, 'utf-8');
10
- const ledger = JSON.parse(ledgerData);
11
-
12
- res.json({
13
- success: true,
14
- data: ledger,
15
- });
16
- } catch (error) {
17
- next(error);
18
- }
19
- },
20
6
 
21
7
  getTokenUsage: async (req: Request, res: Response, next: NextFunction) => {
22
8
  try {
@@ -3,17 +3,6 @@ import { aiwfController } from '@controllers/aiwfController';
3
3
 
4
4
  const router = Router();
5
5
 
6
- /**
7
- * @swagger
8
- * /api/aiwf/features:
9
- * get:
10
- * summary: Feature Ledger 조회
11
- * tags: [AIWF]
12
- * responses:
13
- * 200:
14
- * description: Feature 목록
15
- */
16
- router.get('/features', aiwfController.getFeatures);
17
6
 
18
7
  /**
19
8
  * @swagger
@@ -1,19 +1,17 @@
1
1
  import { useState, useEffect } from 'react'
2
2
  import { useAiwfStore } from '@/stores/aiwfStore'
3
- import FeatureLedger from '@/components/aiwf/FeatureLedger'
4
3
  import TokenUsage from '@/components/aiwf/TokenUsage'
5
4
  import ContextStatus from '@/components/aiwf/ContextStatus'
6
5
 
7
6
  export default function AiwfDashboard() {
8
- const { features, tokenUsage, contextStatus, loadDashboardData } = useAiwfStore()
9
- const [activeTab, setActiveTab] = useState('features')
7
+ const { tokenUsage, contextStatus, loadDashboardData } = useAiwfStore()
8
+ const [activeTab, setActiveTab] = useState('tokens')
10
9
 
11
10
  useEffect(() => {
12
11
  loadDashboardData()
13
12
  }, [loadDashboardData])
14
13
 
15
14
  const tabs = [
16
- { id: 'features', name: 'Feature Ledger', icon: '📋' },
17
15
  { id: 'tokens', name: '토큰 사용량', icon: '🪙' },
18
16
  { id: 'context', name: 'Context 상태', icon: '📊' },
19
17
  ]
@@ -51,7 +49,6 @@ export default function AiwfDashboard() {
51
49
  </div>
52
50
 
53
51
  <div className="mt-8">
54
- {activeTab === 'features' && <FeatureLedger features={features} />}
55
52
  {activeTab === 'tokens' && <TokenUsage usage={tokenUsage} />}
56
53
  {activeTab === 'context' && <ContextStatus status={contextStatus} />}
57
54
  </div>