aiwf 0.3.19 โ†’ 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,15 +1,13 @@
1
1
  {
2
2
  "name": "aiwf",
3
- "version": "0.3.19",
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",
7
7
  "bin": {
8
8
  "aiwf": "./src/cli/index.js",
9
9
  "aiwf-lang": "./src/cli/language-cli.js",
10
- "aiwf-sprint": "./src/cli/sprint-cli.js",
11
- "aiwf-checkpoint": "./src/cli/checkpoint-cli.js",
12
- "aiwf-cache": "./src/cli/cache-cli.js"
10
+ "aiwf-sprint": "./src/cli/sprint-cli.js"
13
11
  },
14
12
  "scripts": {
15
13
  "test": "node --experimental-vm-modules node_modules/.bin/jest",
@@ -133,4 +131,4 @@
133
131
  "utils/engineering-guard.js"
134
132
  ]
135
133
  }
136
- }
134
+ }
package/src/cli/index.js CHANGED
@@ -4,16 +4,9 @@ import { program } from 'commander';
4
4
  import chalk from 'chalk';
5
5
  import { installAIWF } from '../lib/installer.js';
6
6
  import AIToolCommand from '../commands/ai-tool.js';
7
- import PersonaCommand from '../commands/persona.js';
8
- import { CacheCLI } from './cache-cli.js';
9
7
  import { addTaskToSprint } from '../commands/sprint-task.js';
10
- import CompressCommand from '../commands/compress.js';
11
- import TokenCommand from '../commands/token.js';
12
- import EvaluateCommand from '../commands/evaluate.js';
13
- import { createProject } from '../commands/create-project.js';
14
8
  import StateCommand from '../commands/state.js';
15
9
  import { createIndependentSprint } from '../commands/sprint-independent.js';
16
- import { CheckpointManager } from '../utils/checkpoint-manager.js';
17
10
  import { createYoloConfig, createInteractiveYoloConfig, showYoloConfig } from '../commands/yolo-config.js';
18
11
 
19
12
  // Parse version from package.json
@@ -50,94 +43,7 @@ program
50
43
  });
51
44
 
52
45
  // Cache management commands
53
- const cache = program.command('cache');
54
- cache.description('Manage offline template cache');
55
-
56
- cache
57
- .command('download')
58
- .description('Download templates for offline use')
59
- .option('--all', 'Download all templates')
60
- .option('--type <type>', 'Download specific type (ai-tools, projects)')
61
- .action(async (options) => {
62
- const cacheCLI = new CacheCLI();
63
- try {
64
- await cacheCLI.init();
65
- await cacheCLI.downloadCommand(options);
66
- } catch (error) {
67
- console.error(chalk.red('Cache download failed:', error.message));
68
- process.exit(1);
69
- } finally {
70
- await cacheCLI.cleanup();
71
- }
72
- });
73
-
74
- cache
75
- .command('list')
76
- .description('List cached templates')
77
- .option('--type <type>', 'Filter by type (ai-tools, projects)')
78
- .action(async (options) => {
79
- const cacheCLI = new CacheCLI();
80
- try {
81
- await cacheCLI.init();
82
- await cacheCLI.listCommand(options);
83
- } catch (error) {
84
- console.error(chalk.red('Cache list failed:', error.message));
85
- process.exit(1);
86
- } finally {
87
- await cacheCLI.cleanup();
88
- }
89
- });
90
-
91
- cache
92
- .command('clean')
93
- .description('Clean up cached templates')
94
- .option('--all', 'Clear all cached templates')
95
- .option('--max-age <days>', 'Maximum age in days (default: 7)', '7')
96
- .action(async (options) => {
97
- const cacheCLI = new CacheCLI();
98
- try {
99
- await cacheCLI.init();
100
- await cacheCLI.cleanCommand(options);
101
- } catch (error) {
102
- console.error(chalk.red('Cache clean failed:', error.message));
103
- process.exit(1);
104
- } finally {
105
- await cacheCLI.cleanup();
106
- }
107
- });
108
-
109
- cache
110
- .command('update')
111
- .description('Check for template updates')
112
- .option('--install', 'Install available updates')
113
- .action(async (options) => {
114
- const cacheCLI = new CacheCLI();
115
- try {
116
- await cacheCLI.init();
117
- await cacheCLI.updateCommand(options);
118
- } catch (error) {
119
- console.error(chalk.red('Cache update failed:', error.message));
120
- process.exit(1);
121
- } finally {
122
- await cacheCLI.cleanup();
123
- }
124
- });
125
-
126
- cache
127
- .command('status')
128
- .description('Show cache system status')
129
- .action(async () => {
130
- const cacheCLI = new CacheCLI();
131
- try {
132
- await cacheCLI.init();
133
- await cacheCLI.statusCommand();
134
- } catch (error) {
135
- console.error(chalk.red('Cache status failed:', error.message));
136
- process.exit(1);
137
- } finally {
138
- await cacheCLI.cleanup();
139
- }
140
- });
46
+ // (removed) cache command group
141
47
 
142
48
  // Language management commands
143
49
  const lang = program.command('lang');
@@ -171,45 +77,7 @@ lang
171
77
  await resetLanguage();
172
78
  });
173
79
 
174
- // Persona management commands
175
- const persona = program.command('persona');
176
- persona.description('Manage AI personas / AI ํŽ˜๋ฅด์†Œ๋‚˜ ๊ด€๋ฆฌ');
177
-
178
- persona
179
- .command('status')
180
- .alias('s')
181
- .description('Show current persona status / ํ˜„์žฌ ํŽ˜๋ฅด์†Œ๋‚˜ ์ƒํƒœ ํ‘œ์‹œ')
182
- .action(async () => {
183
- const personaCmd = new PersonaCommand();
184
- await personaCmd.showStatus();
185
- });
186
-
187
- persona
188
- .command('list')
189
- .alias('ls')
190
- .description('List available personas / ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํŽ˜๋ฅด์†Œ๋‚˜ ๋ชฉ๋ก')
191
- .action(async () => {
192
- const personaCmd = new PersonaCommand();
193
- await personaCmd.listPersonas();
194
- });
195
-
196
- persona
197
- .command('set <persona-name>')
198
- .alias('switch')
199
- .description('Switch to specific persona / ํŠน์ • ํŽ˜๋ฅด์†Œ๋‚˜๋กœ ์ „ํ™˜')
200
- .action(async (personaName) => {
201
- const personaCmd = new PersonaCommand();
202
- await personaCmd.setPersona(personaName);
203
- });
204
-
205
- persona
206
- .command('reset')
207
- .alias('r')
208
- .description('Reset to default persona / ๊ธฐ๋ณธ ํŽ˜๋ฅด์†Œ๋‚˜๋กœ ๋ฆฌ์…‹')
209
- .action(async () => {
210
- const personaCmd = new PersonaCommand();
211
- await personaCmd.resetPersona();
212
- });
80
+ // (removed) persona command group
213
81
 
214
82
  // Sprint task management command
215
83
  program
@@ -225,125 +93,14 @@ program
225
93
  }
226
94
  });
227
95
 
228
- // Create project command
229
- program
230
- .command('create-project')
231
- .alias('create')
232
- .description('Create a new AIWF project / ์ƒˆ AIWF ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ')
233
- .action(async () => {
234
- try {
235
- await createProject();
236
- } catch (error) {
237
- console.error(chalk.red(`์˜ค๋ฅ˜: ${error.message}`));
238
- process.exit(1);
239
- }
240
- });
241
-
242
- // Context compression command
243
- program
244
- .command('compress [mode] [path]')
245
- .description('Compress context for token optimization / ํ† ํฐ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•œ ์ปจํ…์ŠคํŠธ ์••์ถ•')
246
- .option('--persona, -p', 'Enable persona-aware compression / ํŽ˜๋ฅด์†Œ๋‚˜ ์ธ์‹ ์••์ถ• ํ™œ์„ฑํ™”')
247
- .action(async (mode, path, options) => {
248
- const compressCmd = new CompressCommand();
249
- const args = [];
250
- if (mode) args.push(mode);
251
- if (path) args.push(path);
252
- if (options.persona) args.push('--persona');
253
- await compressCmd.execute(args);
254
- });
255
-
256
-
257
- // Token tracking commands
258
- const token = program.command('token');
259
- token.description('Manage token usage tracking / ํ† ํฐ ์‚ฌ์šฉ๋Ÿ‰ ์ถ”์  ๊ด€๋ฆฌ');
260
-
261
- token
262
- .command('status')
263
- .alias('s')
264
- .description('Show token usage status / ํ† ํฐ ์‚ฌ์šฉ ํ˜„ํ™ฉ ํ‘œ์‹œ')
265
- .action(async () => {
266
- const tokenCmd = new TokenCommand();
267
- await tokenCmd.execute(['status']);
268
- });
269
-
270
- token
271
- .command('report [period]')
272
- .description('Generate usage report / ์‚ฌ์šฉ ๋ฆฌํฌํŠธ ์ƒ์„ฑ')
273
- .action(async (period) => {
274
- const tokenCmd = new TokenCommand();
275
- const args = ['report'];
276
- if (period) args.push(period);
277
- await tokenCmd.execute(args);
278
- });
279
-
280
- token
281
- .command('track <input> <output>')
282
- .description('Manually track token usage / ํ† ํฐ ์‚ฌ์šฉ๋Ÿ‰ ์ˆ˜๋™ ๊ธฐ๋ก')
283
- .action(async (input, output) => {
284
- const tokenCmd = new TokenCommand();
285
- await tokenCmd.execute(['track', input, output]);
286
- });
287
-
288
- token
289
- .command('limit <type> <value>')
290
- .description('Set usage limits / ์‚ฌ์šฉ ํ•œ๋„ ์„ค์ •')
291
- .action(async (type, value) => {
292
- const tokenCmd = new TokenCommand();
293
- await tokenCmd.execute(['limit', type, value]);
294
- });
295
-
296
- token
297
- .command('reset')
298
- .description('Reset tracking data / ์ถ”์  ๋ฐ์ดํ„ฐ ์ดˆ๊ธฐํ™”')
299
- .action(async () => {
300
- const tokenCmd = new TokenCommand();
301
- await tokenCmd.execute(['reset']);
302
- });
96
+ // (removed) create-project command
303
97
 
304
- // Evaluation commands
305
- const evaluate = program.command('evaluate');
306
- evaluate.description('Evaluate AI responses and code quality / AI ์‘๋‹ต ๋ฐ ์ฝ”๋“œ ํ’ˆ์งˆ ํ‰๊ฐ€');
98
+ // (removed) compress command
307
99
 
308
- evaluate
309
- .command('response <file>')
310
- .description('Evaluate AI response quality / AI ์‘๋‹ต ํ’ˆ์งˆ ํ‰๊ฐ€')
311
- .action(async (file) => {
312
- const evaluateCmd = new EvaluateCommand();
313
- await evaluateCmd.execute(['response', file]);
314
- });
315
100
 
316
- evaluate
317
- .command('code <file>')
318
- .description('Evaluate code quality / ์ฝ”๋“œ ํ’ˆ์งˆ ํ‰๊ฐ€')
319
- .action(async (file) => {
320
- const evaluateCmd = new EvaluateCommand();
321
- await evaluateCmd.execute(['code', file]);
322
- });
101
+ // (removed) token command group
323
102
 
324
- evaluate
325
- .command('persona <file> <persona>')
326
- .description('Evaluate persona appropriateness / ํŽ˜๋ฅด์†Œ๋‚˜ ์ ํ•ฉ์„ฑ ํ‰๊ฐ€')
327
- .action(async (file, persona) => {
328
- const evaluateCmd = new EvaluateCommand();
329
- await evaluateCmd.execute(['persona', file, persona]);
330
- });
331
-
332
- evaluate
333
- .command('report')
334
- .description('Generate evaluation report / ํ‰๊ฐ€ ๋ฆฌํฌํŠธ ์ƒ์„ฑ')
335
- .action(async () => {
336
- const evaluateCmd = new EvaluateCommand();
337
- await evaluateCmd.execute(['report']);
338
- });
339
-
340
- evaluate
341
- .command('criteria')
342
- .description('Show evaluation criteria / ํ‰๊ฐ€ ๊ธฐ์ค€ ํ‘œ์‹œ')
343
- .action(async () => {
344
- const evaluateCmd = new EvaluateCommand();
345
- await evaluateCmd.execute(['criteria']);
346
- });
103
+ // (removed) evaluate command group
347
104
 
348
105
  // State management commands
349
106
  const state = program.command('state');
@@ -503,303 +260,7 @@ yoloConfig
503
260
  }
504
261
  });
505
262
 
506
- // Checkpoint management commands (YOLO recovery)
507
- const checkpoint = program.command('checkpoint');
508
- checkpoint.description('YOLO checkpoint management / YOLO ์ฒดํฌํฌ์ธํŠธ ๊ด€๋ฆฌ');
509
-
510
- checkpoint
511
- .command('list')
512
- .alias('ls')
513
- .description('List available checkpoints / ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ฒดํฌํฌ์ธํŠธ ๋ชฉ๋ก')
514
- .option('--limit <n>', 'Limit number of checkpoints / ์ฒดํฌํฌ์ธํŠธ ์ˆ˜ ์ œํ•œ', '10')
515
- .action(async (options) => {
516
- try {
517
- // ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ ์ฐพ๊ธฐ
518
- const fs = await import('fs/promises');
519
- const path = await import('path');
520
- let currentDir = process.cwd();
521
-
522
- while (currentDir !== path.parse(currentDir).root) {
523
- try {
524
- await fs.access(path.join(currentDir, '.aiwf'));
525
- break;
526
- } catch {
527
- currentDir = path.dirname(currentDir);
528
- }
529
- }
530
-
531
- const manager = new CheckpointManager(currentDir);
532
- const checkpoints = await manager.listCheckpoints();
533
-
534
- console.log(chalk.bold('๐Ÿ“Š ์ฒดํฌํฌ์ธํŠธ ๋ชฉ๋ก:'));
535
- console.log('');
536
-
537
- if (checkpoints.length === 0) {
538
- console.log(chalk.yellow('๐Ÿ“ญ ์ฒดํฌํฌ์ธํŠธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.'));
539
- return;
540
- }
541
-
542
- const limit = parseInt(options.limit);
543
- const limitedCheckpoints = checkpoints.slice(0, limit);
544
-
545
- for (const cp of limitedCheckpoints) {
546
- const typeIcon = cp.type === 'session_start' ? '๐Ÿš€' :
547
- cp.type === 'task_complete' ? 'โœ…' : '๐Ÿ”„';
548
- console.log(`${typeIcon} ${chalk.cyan(cp.id)} - ${chalk.yellow(cp.type)}`);
549
- console.log(` ํƒœ์Šคํฌ: ${chalk.blue(cp.tasks_completed)}๊ฐœ ์™„๋ฃŒ`);
550
- console.log('');
551
- }
552
- } catch (error) {
553
- console.error(chalk.red('โŒ ์ฒดํฌํฌ์ธํŠธ ๋ชฉ๋ก ์กฐํšŒ ์‹คํŒจ:'), error.message);
554
- process.exit(1);
555
- }
556
- });
557
-
558
- checkpoint
559
- .command('add [type]')
560
- .alias('create')
561
- .description('Create a checkpoint / ์ฒดํฌํฌ์ธํŠธ ์ƒ์„ฑ')
562
- .option('-m, --message <text>', 'Description for the checkpoint / ์ฒดํฌํฌ์ธํŠธ ์„ค๋ช…')
563
- .option('--meta <json>', 'Additional metadata as JSON / ์ถ”๊ฐ€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ(JSON)')
564
- .option('--cleanup <n>', 'Keep only last N checkpoints after creating / ์ƒ์„ฑ ํ›„ ์ตœ๊ทผ N๊ฐœ๋งŒ ๋ณด์กด')
565
- .action(async (type, options) => {
566
- try {
567
- const fs = await import('fs/promises');
568
- const path = await import('path');
569
- let currentDir = process.cwd();
570
-
571
- // ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ ํƒ์ƒ‰ (.aiwf ๊ธฐ์ค€)
572
- while (currentDir !== path.parse(currentDir).root) {
573
- try {
574
- await fs.access(path.join(currentDir, '.aiwf'));
575
- break;
576
- } catch {
577
- currentDir = path.dirname(currentDir);
578
- }
579
- }
580
-
581
- const manager = new CheckpointManager(currentDir);
582
- await manager.initialize();
583
-
584
- // ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๊ตฌ์„ฑ
585
- const metadata = {};
586
- if (options.message) metadata.message = options.message;
587
- if (options.meta) {
588
- try {
589
- const parsed = JSON.parse(options.meta);
590
- Object.assign(metadata, parsed);
591
- } catch (e) {
592
- console.error(chalk.red('โŒ --meta ๊ฐ’์ด ์˜ฌ๋ฐ”๋ฅธ JSON ํ˜•์‹์ด ์•„๋‹™๋‹ˆ๋‹ค.'));
593
- process.exit(1);
594
- }
595
- }
596
-
597
- const cpType = type || 'manual';
598
- const checkpointId = await manager.createCheckpoint(cpType, metadata);
599
-
600
- console.log(chalk.green('โœ… ์ฒดํฌํฌ์ธํŠธ ์ƒ์„ฑ ์™„๋ฃŒ!'));
601
- console.log(` ID: ${chalk.cyan(checkpointId)} ์œ ํ˜•: ${chalk.yellow(cpType)}`);
602
- if (metadata.message) {
603
- console.log(` ๋ฉ”์‹œ์ง€: ${chalk.blue(metadata.message)}`);
604
- }
605
-
606
- if (options.cleanup) {
607
- const keep = parseInt(options.cleanup, 10);
608
- if (!Number.isNaN(keep) && keep > 0) {
609
- await manager.cleanup(keep);
610
- console.log(`๐Ÿงน ์ตœ๊ทผ ${chalk.cyan(keep)}๊ฐœ๋งŒ ๋ณด์กดํ•˜๋„๋ก ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.`);
611
- } else {
612
- console.log(chalk.yellow('โš ๏ธ --cleanup ๊ฐ’์ด ์œ ํšจํ•˜์ง€ ์•Š์•„ ์ •๋ฆฌ๋ฅผ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค. ์ •์ˆ˜๋กœ ์ž…๋ ฅํ•˜์„ธ์š”.'));
613
- }
614
- }
615
- } catch (error) {
616
- console.error(chalk.red('โŒ ์ฒดํฌํฌ์ธํŠธ ์ƒ์„ฑ ์‹คํŒจ:'), error.message);
617
- process.exit(1);
618
- }
619
- });
620
-
621
- checkpoint
622
- .command('restore <checkpointId>')
623
- .description('Restore from checkpoint / ์ฒดํฌํฌ์ธํŠธ์—์„œ ๋ณต๊ตฌ')
624
- .action(async (checkpointId) => {
625
- try {
626
- const fs = await import('fs/promises');
627
- const path = await import('path');
628
- let currentDir = process.cwd();
629
-
630
- while (currentDir !== path.parse(currentDir).root) {
631
- try {
632
- await fs.access(path.join(currentDir, '.aiwf'));
633
- break;
634
- } catch {
635
- currentDir = path.dirname(currentDir);
636
- }
637
- }
638
-
639
- const manager = new CheckpointManager(currentDir);
640
- await manager.initialize();
641
-
642
- console.log(chalk.blue(`๐Ÿ”„ ์ฒดํฌํฌ์ธํŠธ ${checkpointId}์—์„œ ๋ณต๊ตฌ ์ค‘...`));
643
-
644
- const result = await manager.restoreFromCheckpoint(checkpointId);
645
-
646
- if (result.success) {
647
- console.log(chalk.green('โœ… ์ฒดํฌํฌ์ธํŠธ ๋ณต๊ตฌ ์„ฑ๊ณต!'));
648
- console.log(` ์„ธ์…˜ ID: ${chalk.cyan(result.checkpoint.state_snapshot.session_id)}`);
649
- console.log(` ์Šคํ”„๋ฆฐํŠธ: ${chalk.blue(result.checkpoint.state_snapshot.sprint_id || 'N/A')}`);
650
- console.log('');
651
- console.log(chalk.green('๐Ÿš€ ๋ณต๊ตฌ ์™„๋ฃŒ! YOLO ๋ชจ๋“œ๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.'));
652
- }
653
- } catch (error) {
654
- console.error(chalk.red('โŒ ์ฒดํฌํฌ์ธํŠธ ๋ณต๊ตฌ ์‹คํŒจ:'), error.message);
655
- process.exit(1);
656
- }
657
- });
658
-
659
- checkpoint
660
- .command('status')
661
- .description('Show current YOLO session status / ํ˜„์žฌ YOLO ์„ธ์…˜ ์ƒํƒœ')
662
- .action(async () => {
663
- try {
664
- const fs = await import('fs/promises');
665
- const path = await import('path');
666
- let currentDir = process.cwd();
667
-
668
- while (currentDir !== path.parse(currentDir).root) {
669
- try {
670
- await fs.access(path.join(currentDir, '.aiwf'));
671
- break;
672
- } catch {
673
- currentDir = path.dirname(currentDir);
674
- }
675
- }
676
-
677
- const manager = new CheckpointManager(currentDir);
678
- await manager.loadState();
679
-
680
- console.log(chalk.bold('๐Ÿ“Š YOLO ์„ธ์…˜ ์ƒํƒœ:'));
681
- console.log('');
682
-
683
- if (!manager.currentState.session_id) {
684
- console.log(chalk.yellow('๐Ÿ“ญ ํ™œ์„ฑ YOLO ์„ธ์…˜์ด ์—†์Šต๋‹ˆ๋‹ค.'));
685
- return;
686
- }
687
-
688
- console.log(`์„ธ์…˜ ID: ${chalk.cyan(manager.currentState.session_id)}`);
689
- console.log(`์Šคํ”„๋ฆฐํŠธ: ${chalk.blue(manager.currentState.sprint_id || 'N/A')}`);
690
- console.log(`์™„๋ฃŒ๋œ ํƒœ์Šคํฌ: ${chalk.green(manager.currentState.completed_tasks.length)}๊ฐœ`);
691
- console.log(`์ฒดํฌํฌ์ธํŠธ: ${chalk.blue(manager.currentState.checkpoints.length)}๊ฐœ`);
692
- } catch (error) {
693
- console.error(chalk.red('โŒ ์ƒํƒœ ํ™•์ธ ์‹คํŒจ:'), error.message);
694
- process.exit(1);
695
- }
696
- });
697
-
698
- // ์ฒดํฌํฌ์ธํŠธ ๋ฆฌํฌํŠธ ์ƒ์„ฑ
699
- checkpoint
700
- .command('report')
701
- .description('Generate progress report / ์ง„ํ–‰ ์ƒํ™ฉ ๋ฆฌํฌํŠธ ์ƒ์„ฑ')
702
- .action(async () => {
703
- try {
704
- const fs = await import('fs/promises');
705
- const path = await import('path');
706
- let currentDir = process.cwd();
707
-
708
- while (currentDir !== path.parse(currentDir).root) {
709
- try {
710
- await fs.access(path.join(currentDir, '.aiwf'));
711
- break;
712
- } catch {
713
- currentDir = path.dirname(currentDir);
714
- }
715
- }
716
-
717
- const manager = new CheckpointManager(currentDir);
718
- await manager.loadState();
719
-
720
- console.log(chalk.blue('๐Ÿ“Š ์ง„ํ–‰ ์ƒํ™ฉ ๋ฆฌํฌํŠธ ์ƒ์„ฑ ์ค‘...'));
721
- console.log('');
722
-
723
- const report = await manager.generateProgressReport();
724
-
725
- console.log(chalk.bold('๐ŸŽฏ YOLO ์„ธ์…˜ ๋ฆฌํฌํŠธ'));
726
- console.log(''.padEnd(50, '='));
727
- console.log('');
728
-
729
- // ์„ธ์…˜ ์ •๋ณด
730
- console.log(chalk.bold('๐Ÿ“‹ ์„ธ์…˜ ์ •๋ณด:'));
731
- console.log(` ID: ${chalk.cyan(report.session.id)}`);
732
- console.log(` ์‹œ์ž‘: ${chalk.gray(new Date(report.session.started).toLocaleString())}`);
733
- console.log(` ์Šคํ”„๋ฆฐํŠธ: ${chalk.blue(report.session.sprint || 'N/A')}`);
734
- console.log('');
735
-
736
- // ์ง„ํ–‰ ์ƒํ™ฉ
737
- console.log(chalk.bold('๐Ÿ“ˆ ์ง„ํ–‰ ์ƒํ™ฉ:'));
738
- console.log(` ์™„๋ฃŒ: ${chalk.green(report.progress.completed)}๊ฐœ`);
739
- console.log(` ์‹คํŒจ: ${chalk.red(report.progress.failed)}๊ฐœ`);
740
- console.log(` ๊ฑด๋„ˆ๋œ€: ${chalk.yellow(report.progress.skipped)}๊ฐœ`);
741
- console.log('');
742
-
743
- // ์„ฑ๋Šฅ ์ง€ํ‘œ
744
- console.log(chalk.bold('โฑ๏ธ ์„ฑ๋Šฅ ์ง€ํ‘œ:'));
745
- console.log(` ์ด ์‹œ๊ฐ„: ${chalk.blue(report.performance.total_time)}`);
746
- console.log(` ํ‰๊ท  ํƒœ์Šคํฌ ์‹œ๊ฐ„: ${chalk.blue(report.performance.avg_task_time)}`);
747
- console.log(` ์„ฑ๊ณต๋ฅ : ${chalk.green(report.performance.success_rate)}`);
748
-
749
- } catch (error) {
750
- console.error(chalk.red('โŒ ๋ฆฌํฌํŠธ ์ƒ์„ฑ ์‹คํŒจ:'), error.message);
751
- process.exit(1);
752
- }
753
- });
754
-
755
- // ์ฒดํฌํฌ์ธํŠธ ์ •๋ฆฌ
756
- checkpoint
757
- .command('clean')
758
- .description('Clean old checkpoints / ์˜ค๋ž˜๋œ ์ฒดํฌํฌ์ธํŠธ ์ •๋ฆฌ')
759
- .option('--keep <n>', 'Number of checkpoints to keep / ์œ ์ง€ํ•  ์ฒดํฌํฌ์ธํŠธ ์ˆ˜', '10')
760
- .option('--dry-run', 'Preview without deletion / ์‹ค์ œ ์‚ญ์ œ ์—†์ด ๋ฏธ๋ฆฌ๋ณด๊ธฐ')
761
- .action(async (options) => {
762
- try {
763
- const fs = await import('fs/promises');
764
- const path = await import('path');
765
- let currentDir = process.cwd();
766
-
767
- while (currentDir !== path.parse(currentDir).root) {
768
- try {
769
- await fs.access(path.join(currentDir, '.aiwf'));
770
- break;
771
- } catch {
772
- currentDir = path.dirname(currentDir);
773
- }
774
- }
775
-
776
- const manager = new CheckpointManager(currentDir);
777
- const keepLast = parseInt(options.keep);
778
-
779
- console.log(chalk.blue(`๐Ÿงน ์ฒดํฌํฌ์ธํŠธ ์ •๋ฆฌ ์ค‘... (์ตœ๊ทผ ${keepLast}๊ฐœ ์œ ์ง€)`));
780
-
781
- if (options.dryRun) {
782
- console.log(chalk.yellow('๐Ÿ” ๋“œ๋ผ์ด๋Ÿฐ ๋ชจ๋“œ: ์‹ค์ œ ์‚ญ์ œ๋Š” ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.'));
783
- const checkpoints = await manager.listCheckpoints();
784
- if (checkpoints.length <= keepLast) {
785
- console.log(chalk.green('โœ… ์ •๋ฆฌํ•  ์ฒดํฌํฌ์ธํŠธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.'));
786
- } else {
787
- const toDelete = checkpoints.slice(keepLast);
788
- console.log(chalk.yellow(`์‚ญ์ œ ์˜ˆ์ • ์ฒดํฌํฌ์ธํŠธ (${toDelete.length}๊ฐœ):`));
789
- for (const cp of toDelete) {
790
- console.log(` ${chalk.red('๐Ÿ—‘๏ธ')} ${chalk.cyan(cp.id)}`);
791
- }
792
- }
793
- } else {
794
- await manager.cleanup(keepLast);
795
- console.log(chalk.green('โœ… ์ฒดํฌํฌ์ธํŠธ ์ •๋ฆฌ ์™„๋ฃŒ!'));
796
- }
797
-
798
- } catch (error) {
799
- console.error(chalk.red('โŒ ์ฒดํฌํฌ์ธํŠธ ์ •๋ฆฌ ์‹คํŒจ:'), error.message);
800
- process.exit(1);
801
- }
802
- });
263
+ // (removed) checkpoint command group
803
264
 
804
265
  // Engineering Guard commands (์˜ค๋ฒ„์—”์ง€๋‹ˆ์–ด๋ง ๋ฐฉ์ง€)
805
266
  const guard = program.command('guard');
@@ -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) {