aiwf 0.3.21 β†’ 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 +310 -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
@@ -1,417 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * AIWF 체크포인트 CLI
5
- * YOLO λͺ¨λ“œ 체크포인트 관리λ₯Ό μœ„ν•œ λͺ…λ Ήμ–΄ μΈν„°νŽ˜μ΄μŠ€
6
- */
7
-
8
- import { Command } from 'commander';
9
- import chalk from 'chalk';
10
- import { CheckpointManager } from '../utils/checkpoint-manager.js';
11
- import fs from 'fs/promises';
12
- import path from 'path';
13
-
14
- const program = new Command();
15
-
16
- program
17
- .name('aiwf-checkpoint')
18
- .description('AIWF 체크포인트 관리 도ꡬ')
19
- .version('0.3.12');
20
-
21
- // ν”„λ‘œμ νŠΈ 루트 μ°ΎκΈ° 헬퍼
22
- async function findProjectRoot(startDir = process.cwd()) {
23
- let currentDir = startDir;
24
-
25
- while (currentDir !== path.parse(currentDir).root) {
26
- try {
27
- await fs.access(path.join(currentDir, '.aiwf'));
28
- return currentDir;
29
- } catch {
30
- currentDir = path.dirname(currentDir);
31
- }
32
- }
33
-
34
- throw new Error('.aiwf 디렉토리λ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€. AIWF ν”„λ‘œμ νŠΈ λ‚΄μ—μ„œ μ‹€ν–‰ν•΄μ£Όμ„Έμš”.');
35
- }
36
-
37
- // 체크포인트 λͺ©λ‘ 보기
38
- program
39
- .command('list')
40
- .alias('ls')
41
- .description('μ‚¬μš© κ°€λŠ₯ν•œ 체크포인트 λͺ©λ‘')
42
- .option('--limit <n>', 'ν‘œμ‹œν•  체크포인트 수 μ œν•œ', '10')
43
- .action(async (options) => {
44
- try {
45
- const projectRoot = await findProjectRoot();
46
- const manager = new CheckpointManager(projectRoot);
47
-
48
- console.log(chalk.bold('πŸ“Š 체크포인트 λͺ©λ‘:'));
49
- console.log('');
50
-
51
- const checkpoints = await manager.listCheckpoints();
52
-
53
- if (checkpoints.length === 0) {
54
- console.log(chalk.yellow('πŸ“­ μ²΄ν¬ν¬μΈνŠΈκ°€ μ—†μŠ΅λ‹ˆλ‹€.'));
55
- console.log('');
56
- console.log(chalk.gray('YOLO λͺ¨λ“œλ₯Ό μ‹€ν–‰ν•˜λ©΄ μžλ™μœΌλ‘œ μ²΄ν¬ν¬μΈνŠΈκ°€ μƒμ„±λ©λ‹ˆλ‹€.'));
57
- return;
58
- }
59
-
60
- const limit = parseInt(options.limit);
61
- const limitedCheckpoints = checkpoints.slice(0, limit);
62
-
63
- for (const cp of limitedCheckpoints) {
64
- const typeIcon = cp.type === 'session_start' ? 'πŸš€' :
65
- cp.type === 'task_complete' ? 'βœ…' :
66
- cp.type === 'sprint_complete' ? '🎯' :
67
- cp.type === 'session_end' ? '🏁' :
68
- cp.type === 'manual' ? 'πŸ“' : 'πŸ”„';
69
-
70
- const timeAgo = getTimeAgo(new Date(cp.created));
71
-
72
- console.log(`${typeIcon} ${chalk.cyan(cp.id)} - ${chalk.yellow(cp.type)}`);
73
- console.log(` 생성: ${chalk.gray(timeAgo)}`);
74
- console.log(` νƒœμŠ€ν¬: ${chalk.blue(cp.tasks_completed)}개 μ™„λ£Œ`);
75
-
76
- if (cp.metadata && Object.keys(cp.metadata).length > 0) {
77
- console.log(` 메타: ${chalk.gray(JSON.stringify(cp.metadata))}`);
78
- }
79
- console.log('');
80
- }
81
-
82
- if (checkpoints.length > limit) {
83
- console.log(chalk.gray(`... 더 λ§Žμ€ μ²΄ν¬ν¬μΈνŠΈκ°€ μžˆμŠ΅λ‹ˆλ‹€ (총 ${checkpoints.length}개)`));
84
- console.log(chalk.blue(`λͺ¨λ“  체크포인트λ₯Ό 보렀면: aiwf-checkpoint list --limit ${checkpoints.length}`));
85
- }
86
-
87
- } catch (error) {
88
- console.error(chalk.red('❌ 체크포인트 λͺ©λ‘ 쑰회 μ‹€νŒ¨:'), error.message);
89
- process.exit(1);
90
- }
91
- });
92
-
93
- // μ²΄ν¬ν¬μΈνŠΈμ—μ„œ 볡ꡬ
94
- program
95
- .command('restore <checkpointId>')
96
- .description('μ²΄ν¬ν¬μΈνŠΈμ—μ„œ 볡ꡬ')
97
- .option('--dry-run', 'μ‹€μ œ 볡ꡬ 없이 미리보기만')
98
- .action(async (checkpointId, options) => {
99
- try {
100
- const projectRoot = await findProjectRoot();
101
- const manager = new CheckpointManager(projectRoot);
102
- await manager.initialize();
103
-
104
- console.log(chalk.blue(`πŸ”„ 체크포인트 ${checkpointId}μ—μ„œ 볡ꡬ 쀑...`));
105
- console.log('');
106
-
107
- if (options.dryRun) {
108
- console.log(chalk.yellow('πŸ” λ“œλΌμ΄λŸ° λͺ¨λ“œ: μ‹€μ œ λ³΅κ΅¬λŠ” μˆ˜ν–‰ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.'));
109
- console.log('');
110
- }
111
-
112
- const result = await manager.restoreFromCheckpoint(checkpointId);
113
-
114
- if (result.success) {
115
- console.log(chalk.green('βœ… 체크포인트 볡ꡬ 성곡!'));
116
- console.log('');
117
- console.log(chalk.bold('πŸ“Š 볡ꡬ된 μ„Έμ…˜ 정보:'));
118
- console.log(` μ„Έμ…˜ ID: ${chalk.cyan(result.checkpoint.state_snapshot.session_id)}`);
119
- console.log(` μŠ€ν”„λ¦°νŠΈ: ${chalk.blue(result.checkpoint.state_snapshot.sprint_id || 'N/A')}`);
120
- console.log(` λͺ¨λ“œ: ${chalk.yellow(result.checkpoint.state_snapshot.mode || 'N/A')}`);
121
- console.log('');
122
-
123
- console.log(chalk.bold('πŸ”„ 재개 κ°€λŠ₯ν•œ μž‘μ—…:'));
124
- if (result.tasks_to_resume.current) {
125
- console.log(` ν˜„μž¬ νƒœμŠ€ν¬: ${chalk.cyan(result.tasks_to_resume.current)}`);
126
- }
127
- console.log(` μ™„λ£Œλœ νƒœμŠ€ν¬: ${chalk.blue(result.tasks_to_resume.completed.length)}개`);
128
- console.log(` λ‹€μŒ μž‘μ—…: ${chalk.gray(result.tasks_to_resume.next_task_hint)}`);
129
- console.log('');
130
-
131
- if (result.checkpoint.git_info) {
132
- console.log(chalk.bold('πŸ“‹ Git 정보:'));
133
- console.log(` 브랜치: ${chalk.cyan(result.checkpoint.git_info.branch)}`);
134
- console.log(` 컀밋: ${chalk.gray(result.checkpoint.git_info.commit.substring(0, 8))}`);
135
- console.log('');
136
- }
137
-
138
- console.log(chalk.green('πŸš€ 볡ꡬ μ™„λ£Œ! YOLO λͺ¨λ“œλ₯Ό λ‹€μ‹œ μ‹€ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.'));
139
-
140
- } else {
141
- console.error(chalk.red('❌ 체크포인트 볡ꡬ μ‹€νŒ¨'));
142
- }
143
-
144
- } catch (error) {
145
- console.error(chalk.red('❌ 체크포인트 볡ꡬ μ‹€νŒ¨:'), error.message);
146
- process.exit(1);
147
- }
148
- });
149
-
150
- // 체크포인트 생성
151
- program
152
- .command('create [message]')
153
- .description('μˆ˜λ™ 체크포인트 생성')
154
- .action(async (message) => {
155
- try {
156
- const projectRoot = await findProjectRoot();
157
- const manager = new CheckpointManager(projectRoot);
158
- await manager.initialize();
159
-
160
- const checkpointMessage = message || 'μˆ˜λ™ 체크포인트';
161
-
162
- console.log(chalk.blue('πŸ“ μˆ˜λ™ 체크포인트 생성 쀑...'));
163
-
164
- const checkpointId = await manager.createCheckpoint('manual', {
165
- message: checkpointMessage,
166
- created_by: 'user'
167
- });
168
-
169
- console.log(chalk.green('βœ… 체크포인트 생성 μ™„λ£Œ!'));
170
- console.log('');
171
- console.log(`체크포인트 ID: ${chalk.cyan(checkpointId)}`);
172
- console.log(`λ©”μ‹œμ§€: ${chalk.yellow(checkpointMessage)}`);
173
- console.log('');
174
- console.log(chalk.gray('이 μ²΄ν¬ν¬μΈνŠΈμ—μ„œ λ³΅κ΅¬ν•˜λ €λ©΄:'));
175
- console.log(chalk.blue(`aiwf-checkpoint restore ${checkpointId}`));
176
-
177
- } catch (error) {
178
- console.error(chalk.red('❌ 체크포인트 생성 μ‹€νŒ¨:'), error.message);
179
- process.exit(1);
180
- }
181
- });
182
-
183
- // ν˜„μž¬ μƒνƒœ 보기
184
- program
185
- .command('status')
186
- .description('ν˜„μž¬ YOLO μ„Έμ…˜ μƒνƒœ')
187
- .action(async () => {
188
- try {
189
- const projectRoot = await findProjectRoot();
190
- const manager = new CheckpointManager(projectRoot);
191
- await manager.loadState();
192
-
193
- console.log(chalk.bold('πŸ“Š YOLO μ„Έμ…˜ μƒνƒœ:'));
194
- console.log('');
195
-
196
- if (!manager.currentState.session_id) {
197
- console.log(chalk.yellow('πŸ“­ ν™œμ„± YOLO μ„Έμ…˜μ΄ μ—†μŠ΅λ‹ˆλ‹€.'));
198
- console.log('');
199
- console.log(chalk.gray('YOLO λͺ¨λ“œλ₯Ό μ‹œμž‘ν•˜λ €λ©΄:'));
200
- console.log(chalk.blue('/project:aiwf:yolo'));
201
- return;
202
- }
203
-
204
- console.log(`μ„Έμ…˜ ID: ${chalk.cyan(manager.currentState.session_id)}`);
205
- console.log(`μ‹œμž‘ μ‹œκ°„: ${chalk.gray(new Date(manager.currentState.started_at).toLocaleString())}`);
206
- console.log(`μŠ€ν”„λ¦°νŠΈ: ${chalk.blue(manager.currentState.sprint_id || 'N/A')}`);
207
- console.log(`λͺ¨λ“œ: ${chalk.yellow(manager.currentState.mode || 'N/A')}`);
208
- console.log('');
209
-
210
- console.log(chalk.bold('πŸ“ˆ μ§„ν–‰ 상황:'));
211
- console.log(` μ™„λ£Œλœ νƒœμŠ€ν¬: ${chalk.green(manager.currentState.completed_tasks.length)}개`);
212
- console.log(` μ‹€νŒ¨ν•œ νƒœμŠ€ν¬: ${chalk.red(manager.currentState.metrics.failed_tasks)}개`);
213
- console.log(` κ±΄λ„ˆλ›΄ νƒœμŠ€ν¬: ${chalk.yellow(manager.currentState.metrics.skipped_tasks)}개`);
214
-
215
- if (manager.currentState.current_task) {
216
- console.log(` ν˜„μž¬ νƒœμŠ€ν¬: ${chalk.cyan(manager.currentState.current_task.id)}`);
217
- console.log(` μ‹œλ„ 횟수: ${chalk.blue(manager.currentState.current_task.attempts)}회`);
218
- }
219
- console.log('');
220
-
221
- if (manager.currentState.metrics.total_time > 0) {
222
- console.log(chalk.bold('⏱️ μ„±λŠ₯ μ§€ν‘œ:'));
223
- console.log(` 총 μ‹€ν–‰ μ‹œκ°„: ${chalk.blue(manager.formatDuration(manager.currentState.metrics.total_time))}`);
224
- console.log(` 평균 νƒœμŠ€ν¬ μ‹œκ°„: ${chalk.blue(manager.formatDuration(manager.currentState.metrics.avg_task_time))}`);
225
- console.log('');
226
- }
227
-
228
- console.log(chalk.bold('πŸ“Š 체크포인트:'));
229
- console.log(` μƒμ„±λœ 체크포인트: ${chalk.blue(manager.currentState.checkpoints.length)}개`);
230
-
231
- if (manager.currentState.checkpoints.length > 0) {
232
- const latest = manager.currentState.checkpoints[manager.currentState.checkpoints.length - 1];
233
- console.log(` 졜근 체크포인트: ${chalk.cyan(latest.id)} (${chalk.gray(latest.type)})`);
234
- }
235
-
236
- } catch (error) {
237
- console.error(chalk.red('❌ μƒνƒœ 확인 μ‹€νŒ¨:'), error.message);
238
- process.exit(1);
239
- }
240
- });
241
-
242
- // 체크포인트 정리
243
- program
244
- .command('clean')
245
- .description('였래된 체크포인트 정리')
246
- .option('--keep <n>', 'μœ μ§€ν•  체크포인트 수', '10')
247
- .option('--dry-run', 'μ‹€μ œ μ‚­μ œ 없이 미리보기만')
248
- .action(async (options) => {
249
- try {
250
- const projectRoot = await findProjectRoot();
251
- const manager = new CheckpointManager(projectRoot);
252
-
253
- const keepLast = parseInt(options.keep);
254
-
255
- console.log(chalk.blue(`🧹 체크포인트 정리 쀑... (졜근 ${keepLast}개 μœ μ§€)`));
256
- console.log('');
257
-
258
- if (options.dryRun) {
259
- console.log(chalk.yellow('πŸ” λ“œλΌμ΄λŸ° λͺ¨λ“œ: μ‹€μ œ μ‚­μ œλŠ” μˆ˜ν–‰ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.'));
260
- console.log('');
261
-
262
- const checkpoints = await manager.listCheckpoints();
263
- if (checkpoints.length <= keepLast) {
264
- console.log(chalk.green('βœ… 정리할 μ²΄ν¬ν¬μΈνŠΈκ°€ μ—†μŠ΅λ‹ˆλ‹€.'));
265
- } else {
266
- const toDelete = checkpoints.slice(keepLast);
267
- console.log(chalk.yellow(`μ‚­μ œ μ˜ˆμ • 체크포인트 (${toDelete.length}개):`));
268
- for (const cp of toDelete) {
269
- console.log(` ${chalk.red('πŸ—‘οΈ')} ${chalk.cyan(cp.id)} - ${chalk.gray(cp.type)}`);
270
- }
271
- }
272
- } else {
273
- await manager.cleanup(keepLast);
274
- console.log(chalk.green('βœ… 체크포인트 정리 μ™„λ£Œ!'));
275
- }
276
-
277
- } catch (error) {
278
- console.error(chalk.red('❌ 체크포인트 정리 μ‹€νŒ¨:'), error.message);
279
- process.exit(1);
280
- }
281
- });
282
-
283
- // 체크포인트 리포트 생성
284
- program
285
- .command('report')
286
- .description('ν˜„μž¬ μ„Έμ…˜μ˜ μ§„ν–‰ 상황 리포트 생성')
287
- .action(async () => {
288
- try {
289
- const projectRoot = await findProjectRoot();
290
- const manager = new CheckpointManager(projectRoot);
291
- await manager.loadState();
292
-
293
- console.log(chalk.blue('πŸ“Š μ§„ν–‰ 상황 리포트 생성 쀑...'));
294
- console.log('');
295
-
296
- const report = await manager.generateProgressReport();
297
-
298
- console.log(chalk.bold('🎯 YOLO μ„Έμ…˜ 리포트'));
299
- console.log(''.padEnd(50, '='));
300
- console.log('');
301
-
302
- // μ„Έμ…˜ 정보
303
- console.log(chalk.bold('πŸ“‹ μ„Έμ…˜ 정보:'));
304
- console.log(` ID: ${chalk.cyan(report.session.id)}`);
305
- console.log(` μ‹œμž‘: ${chalk.gray(new Date(report.session.started).toLocaleString())}`);
306
- console.log(` μŠ€ν”„λ¦°νŠΈ: ${chalk.blue(report.session.sprint || 'N/A')}`);
307
- console.log(` λͺ¨λ“œ: ${chalk.yellow(report.session.mode || 'N/A')}`);
308
- console.log('');
309
-
310
- // μ§„ν–‰ 상황
311
- console.log(chalk.bold('πŸ“ˆ μ§„ν–‰ 상황:'));
312
- console.log(` μ™„λ£Œ: ${chalk.green(report.progress.completed)}개`);
313
- console.log(` μ‹€νŒ¨: ${chalk.red(report.progress.failed)}개`);
314
- console.log(` κ±΄λ„ˆλœ€: ${chalk.yellow(report.progress.skipped)}개`);
315
- console.log(` ν˜„μž¬: ${chalk.cyan(report.progress.current)}`);
316
- console.log('');
317
-
318
- // μ„±λŠ₯ μ§€ν‘œ
319
- console.log(chalk.bold('⏱️ μ„±λŠ₯ μ§€ν‘œ:'));
320
- console.log(` 총 μ‹œκ°„: ${chalk.blue(report.performance.total_time)}`);
321
- console.log(` 평균 νƒœμŠ€ν¬ μ‹œκ°„: ${chalk.blue(report.performance.avg_task_time)}`);
322
- console.log(` 성곡λ₯ : ${chalk.green(report.performance.success_rate)}`);
323
- console.log('');
324
-
325
- // 체크포인트
326
- if (report.checkpoints.length > 0) {
327
- console.log(chalk.bold('πŸ“Š 체크포인트:'));
328
- for (const cp of report.checkpoints.slice(-5)) { // 졜근 5개만
329
- const typeIcon = cp.type === 'session_start' ? 'πŸš€' :
330
- cp.type === 'task_complete' ? 'βœ…' :
331
- cp.type === 'auto' ? 'πŸ”„' : 'πŸ“';
332
- console.log(` ${typeIcon} ${chalk.cyan(cp.id)} - ${chalk.gray(cp.type)}`);
333
- }
334
- console.log('');
335
- }
336
-
337
- // ꢌμž₯사항
338
- if (report.recommendations.length > 0) {
339
- console.log(chalk.bold('πŸ’‘ ꢌμž₯사항:'));
340
- for (const rec of report.recommendations) {
341
- console.log(` β€’ ${chalk.yellow(rec)}`);
342
- }
343
- console.log('');
344
- }
345
-
346
- } catch (error) {
347
- console.error(chalk.red('❌ 리포트 생성 μ‹€νŒ¨:'), error.message);
348
- process.exit(1);
349
- }
350
- });
351
-
352
- // 도움말 λͺ…λ Ήμ–΄
353
- program
354
- .command('help')
355
- .description('AIWF 체크포인트 λͺ…λ Ήμ–΄ 도움말')
356
- .action(() => {
357
- console.log(chalk.bold('πŸ“Š AIWF 체크포인트 CLI 도움말'));
358
- console.log('');
359
- console.log(chalk.yellow('πŸ“‹ μ£Όμš” λͺ…λ Ήμ–΄:'));
360
- console.log('');
361
- console.log(` ${chalk.cyan('aiwf-checkpoint list')} - 체크포인트 λͺ©λ‘ 보기`);
362
- console.log(` ${chalk.cyan('aiwf-checkpoint status')} - ν˜„μž¬ μ„Έμ…˜ μƒνƒœ`);
363
- console.log(` ${chalk.cyan('aiwf-checkpoint restore <id>')} - μ²΄ν¬ν¬μΈνŠΈμ—μ„œ 볡ꡬ`);
364
- console.log(` ${chalk.cyan('aiwf-checkpoint create [message]')} - μˆ˜λ™ 체크포인트 생성`);
365
- console.log(` ${chalk.cyan('aiwf-checkpoint clean')} - 였래된 체크포인트 정리`);
366
- console.log(` ${chalk.cyan('aiwf-checkpoint report')} - μ§„ν–‰ 상황 리포트`);
367
- console.log('');
368
- console.log(chalk.yellow('πŸ”§ μœ μš©ν•œ μ˜΅μ…˜:'));
369
- console.log('');
370
- console.log(` ${chalk.blue('--dry-run')} - μ‹€μ œ μ‹€ν–‰ 없이 미리보기`);
371
- console.log(` ${chalk.blue('--limit <n>')} - λͺ©λ‘ ν‘œμ‹œ μ œν•œ`);
372
- console.log(` ${chalk.blue('--keep <n>')} - 정리 μ‹œ μœ μ§€ν•  개수`);
373
- console.log('');
374
- console.log(chalk.yellow('πŸ’‘ μ‚¬μš© μ˜ˆμ‹œ:'));
375
- console.log('');
376
- console.log(` ${chalk.gray('# 졜근 μ²΄ν¬ν¬μΈνŠΈμ—μ„œ 볡ꡬ')}`);
377
- console.log(` ${chalk.blue('aiwf-checkpoint list')}`);
378
- console.log(` ${chalk.blue('aiwf-checkpoint restore cp_1234567890')}`);
379
- console.log('');
380
- console.log(` ${chalk.gray('# μ€‘μš”ν•œ μž‘μ—… μ „ μˆ˜λ™ 체크포인트 생성')}`);
381
- console.log(` ${chalk.blue('aiwf-checkpoint create "μ£Όμš” λ¦¬νŒ©ν† λ§ μ „"')}`);
382
- console.log('');
383
- console.log(` ${chalk.gray('# 였래된 체크포인트 정리')}`);
384
- console.log(` ${chalk.blue('aiwf-checkpoint clean --keep 5')}`);
385
- console.log('');
386
- console.log(chalk.green('πŸ›‘οΈ μ²΄ν¬ν¬μΈνŠΈλŠ” YOLO λͺ¨λ“œ μ‹€ν–‰ 쀑 μžλ™μœΌλ‘œ μƒμ„±λ©λ‹ˆλ‹€!'));
387
- });
388
-
389
- // μ‹œκ°„ κ²½κ³Ό 계산 헬퍼
390
- function getTimeAgo(date) {
391
- const now = new Date();
392
- const diffMs = now - date;
393
- const diffMins = Math.floor(diffMs / 60000);
394
- const diffHours = Math.floor(diffMins / 60);
395
- const diffDays = Math.floor(diffHours / 24);
396
-
397
- if (diffDays > 0) return `${diffDays}일 μ „`;
398
- if (diffHours > 0) return `${diffHours}μ‹œκ°„ μ „`;
399
- if (diffMins > 0) return `${diffMins}λΆ„ μ „`;
400
- return '방금 μ „';
401
- }
402
-
403
- // μ—λŸ¬ 핸듀링
404
- program.on('command:*', () => {
405
- console.error(chalk.red('❌ μ•Œ 수 μ—†λŠ” λͺ…λ Ήμ–΄μž…λ‹ˆλ‹€.'));
406
- console.log('');
407
- console.log(chalk.blue('도움말을 보렀면: aiwf-checkpoint help'));
408
- process.exit(1);
409
- });
410
-
411
- // CLI μ‹€ν–‰
412
- program.parse(process.argv);
413
-
414
- // μΈμˆ˜κ°€ μ—†μœΌλ©΄ 도움말 ν‘œμ‹œ
415
- if (!process.argv.slice(2).length) {
416
- program.outputHelp();
417
- }