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.
- package/package.json +3 -2
- package/src/cli/index.js +39 -336
- package/src/lib/installer.js +310 -90
- package/src/utils/messages.js +24 -0
- package/src/DEPENDENCY_MAP.md +0 -90
- package/src/cli/cache-cli.js +0 -459
- package/src/cli/checkpoint-cli.js +0 -417
- package/src/cli/language-cli.js +0 -286
- package/src/cli/sprint-cli.js +0 -287
- package/src/commands/ai-tool.js +0 -383
- package/src/commands/compress.js +0 -60
- package/src/commands/create-project.js +0 -160
- package/src/commands/evaluate.js +0 -459
- package/src/commands/persona.js +0 -309
- package/src/commands/sprint-task.js +0 -262
- package/src/commands/token.js +0 -312
- package/src/lib/ai-persona-manager.js +0 -711
- package/src/lib/cache-system.js +0 -332
- package/src/lib/context-engine.js +0 -568
- package/src/lib/github-integration.js +0 -402
- package/src/lib/memory-profiler.js +0 -471
- package/src/lib/metrics-collector.js +0 -885
- package/src/lib/offline-detector.js +0 -386
- package/src/lib/resource-loader-enhanced.js +0 -399
- package/src/lib/resource-loader.js +0 -250
- package/src/lib/resources/commands/ai-persona.js +0 -602
- package/src/lib/resources/commands/compress-context.js +0 -389
- package/src/lib/resources/commands/evaluate.js +0 -246
- package/src/lib/resources/commands/persona-context-apply.js +0 -562
- package/src/lib/resources/commands/token-tracking.js +0 -443
- package/src/lib/resources/config/commit-patterns.js +0 -103
- package/src/lib/resources/config/language.json +0 -6
- package/src/lib/resources/personas/PERSONA_INDEX.md +0 -57
- package/src/lib/resources/personas/analyst.json +0 -44
- package/src/lib/resources/personas/architect/best_practices.md +0 -136
- package/src/lib/resources/personas/architect/knowledge_base.md +0 -377
- package/src/lib/resources/personas/architect.json +0 -44
- package/src/lib/resources/personas/backend/best_practices.md +0 -766
- package/src/lib/resources/personas/backend/knowledge_base.md +0 -1070
- package/src/lib/resources/personas/data_analyst/best_practices.md +0 -594
- package/src/lib/resources/personas/data_analyst/knowledge_base.md +0 -1057
- package/src/lib/resources/personas/developer.json +0 -44
- package/src/lib/resources/personas/developer.md +0 -37
- package/src/lib/resources/personas/evaluation_criteria.json +0 -137
- package/src/lib/resources/personas/frontend/best_practices.md +0 -445
- package/src/lib/resources/personas/frontend/knowledge_base.md +0 -729
- package/src/lib/resources/personas/persona-index.json +0 -31
- package/src/lib/resources/personas/reviewer.json +0 -44
- package/src/lib/resources/personas/security/best_practices.md +0 -307
- package/src/lib/resources/personas/security/knowledge_base.md +0 -498
- package/src/lib/resources/personas/tester.json +0 -44
- package/src/lib/resources/templates/README.md +0 -78
- package/src/lib/resources/templates/api-server/config.json +0 -64
- package/src/lib/resources/templates/api-server/template/.aiwf/config.json +0 -56
- package/src/lib/resources/templates/api-server/template/.aiwf/feature-ledger.json +0 -42
- package/src/lib/resources/templates/api-server/template/.aiwf/personas/backend-engineer.json +0 -40
- package/src/lib/resources/templates/api-server/template/.aiwf/scripts/cli.js +0 -111
- package/src/lib/resources/templates/api-server/template/.env.example +0 -29
- package/src/lib/resources/templates/api-server/template/.eslintrc.json +0 -23
- package/src/lib/resources/templates/api-server/template/README.md +0 -171
- package/src/lib/resources/templates/api-server/template/jest.config.js +0 -26
- package/src/lib/resources/templates/api-server/template/nodemon.json +0 -9
- package/src/lib/resources/templates/api-server/template/package.json +0 -61
- package/src/lib/resources/templates/api-server/template/src/app.ts +0 -60
- package/src/lib/resources/templates/api-server/template/src/config/swagger.ts +0 -38
- package/src/lib/resources/templates/api-server/template/src/controllers/aiwfController.ts +0 -54
- package/src/lib/resources/templates/api-server/template/src/controllers/authController.ts +0 -128
- package/src/lib/resources/templates/api-server/template/src/controllers/statusController.ts +0 -28
- package/src/lib/resources/templates/api-server/template/src/index.ts +0 -28
- package/src/lib/resources/templates/api-server/template/src/middleware/aiwfMiddleware.ts +0 -50
- package/src/lib/resources/templates/api-server/template/src/middleware/authMiddleware.ts +0 -41
- package/src/lib/resources/templates/api-server/template/src/middleware/errorHandler.ts +0 -42
- package/src/lib/resources/templates/api-server/template/src/middleware/notFoundHandler.ts +0 -14
- package/src/lib/resources/templates/api-server/template/src/middleware/requestLogger.ts +0 -20
- package/src/lib/resources/templates/api-server/template/src/routes/aiwf.ts +0 -31
- package/src/lib/resources/templates/api-server/template/src/routes/index.ts +0 -13
- package/src/lib/resources/templates/api-server/template/src/routes/v1/index.ts +0 -67
- package/src/lib/resources/templates/api-server/template/src/utils/logger.ts +0 -37
- package/src/lib/resources/templates/api-server/template/tests/app.test.ts +0 -40
- package/src/lib/resources/templates/api-server/template/tsconfig.json +0 -43
- package/src/lib/resources/templates/npm-library/config.json +0 -61
- package/src/lib/resources/templates/npm-library/template/LICENSE +0 -21
- package/src/lib/resources/templates/npm-library/template/README.md +0 -201
- package/src/lib/resources/templates/npm-library/template/package.json +0 -78
- package/src/lib/resources/templates/web-app/config.json +0 -53
- package/src/lib/resources/templates/web-app/template/.aiwf/config.json +0 -54
- package/src/lib/resources/templates/web-app/template/.aiwf/feature-ledger.json +0 -37
- package/src/lib/resources/templates/web-app/template/.aiwf/personas/fullstack-developer.json +0 -40
- package/src/lib/resources/templates/web-app/template/.aiwf/scripts/cli.js +0 -110
- package/src/lib/resources/templates/web-app/template/.eslintrc.cjs +0 -20
- package/src/lib/resources/templates/web-app/template/README.md +0 -151
- package/src/lib/resources/templates/web-app/template/index.html +0 -14
- package/src/lib/resources/templates/web-app/template/package.json +0 -44
- package/src/lib/resources/templates/web-app/template/postcss.config.js +0 -6
- package/src/lib/resources/templates/web-app/template/public/vite.svg +0 -1
- package/src/lib/resources/templates/web-app/template/src/App.tsx +0 -21
- package/src/lib/resources/templates/web-app/template/src/components/Layout.tsx +0 -57
- package/src/lib/resources/templates/web-app/template/src/components/aiwf/ContextStatus.tsx +0 -107
- package/src/lib/resources/templates/web-app/template/src/components/aiwf/TokenUsage.tsx +0 -71
- package/src/lib/resources/templates/web-app/template/src/index.css +0 -60
- package/src/lib/resources/templates/web-app/template/src/main.tsx +0 -10
- package/src/lib/resources/templates/web-app/template/src/pages/AiwfDashboard.tsx +0 -57
- package/src/lib/resources/templates/web-app/template/src/pages/HomePage.tsx +0 -89
- package/src/lib/resources/templates/web-app/template/src/pages/NotFound.tsx +0 -25
- package/src/lib/resources/templates/web-app/template/src/stores/aiwfStore.ts +0 -126
- package/src/lib/resources/templates/web-app/template/src/types/global.d.ts +0 -9
- package/src/lib/resources/templates/web-app/template/src/vite-env.d.ts +0 -1
- package/src/lib/resources/templates/web-app/template/tailwind.config.js +0 -30
- package/src/lib/resources/templates/web-app/template/tsconfig.json +0 -37
- package/src/lib/resources/templates/web-app/template/tsconfig.node.json +0 -10
- package/src/lib/resources/templates/web-app/template/vite.config.ts +0 -23
- package/src/lib/resources/utils/background-monitor.js +0 -223
- package/src/lib/resources/utils/compression-metrics.js +0 -1031
- package/src/lib/resources/utils/compression-strategies.js +0 -557
- package/src/lib/resources/utils/content-normalizer.js +0 -455
- package/src/lib/resources/utils/context-compressor.js +0 -583
- package/src/lib/resources/utils/context-rule-parser.js +0 -180
- package/src/lib/resources/utils/context-token-monitor.js +0 -463
- package/src/lib/resources/utils/context-update-manager.js +0 -502
- package/src/lib/resources/utils/git-utils.js +0 -220
- package/src/lib/resources/utils/importance-classifier.js +0 -645
- package/src/lib/resources/utils/information-filter.js +0 -710
- package/src/lib/resources/utils/persona-aware-compressor.js +0 -598
- package/src/lib/resources/utils/prompt-injector.js +0 -242
- package/src/lib/resources/utils/simplified-evaluator.js +0 -119
- package/src/lib/resources/utils/text-summarizer.js +0 -492
- package/src/lib/resources/utils/token-counter.js +0 -177
- package/src/lib/resources/utils/token-monitor.js +0 -484
- package/src/lib/resources/utils/token-reporter.js +0 -452
- package/src/lib/resources/utils/token-storage.js +0 -433
- package/src/lib/resources/utils/token-tracker.js +0 -283
- package/src/lib/state/priority-calculator.js +0 -217
- package/src/lib/state/state-index.js +0 -155
- package/src/lib/state/task-scanner.js +0 -328
- package/src/lib/task-analyzer.js +0 -599
- package/src/lib/template-cache-system.js +0 -559
- package/src/lib/template-downloader.js +0 -467
- package/src/lib/template-version-manager.js +0 -491
- package/src/lib/token-optimizer.js +0 -517
- package/src/utils/engineering-guard.js +0 -399
package/src/cli/cache-cli.js
DELETED
|
@@ -1,459 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { Command } from 'commander';
|
|
4
|
-
import chalk from 'chalk';
|
|
5
|
-
import ora from 'ora';
|
|
6
|
-
import prompts from 'prompts';
|
|
7
|
-
import { TemplateCache } from '../lib/template-cache-system.js';
|
|
8
|
-
import { OfflineDetector } from '../lib/offline-detector.js';
|
|
9
|
-
import { TemplateDownloader } from '../lib/template-downloader.js';
|
|
10
|
-
import { TemplateVersionManager } from '../lib/template-version-manager.js';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* 캐시 관리 CLI 명령어
|
|
14
|
-
* - aiwf cache download: 선택적 템플릿 다운로드
|
|
15
|
-
* - aiwf cache list: 캐시 목록 조회
|
|
16
|
-
* - aiwf cache clean: 캐시 정리
|
|
17
|
-
* - aiwf cache update: 업데이트 확인
|
|
18
|
-
* - aiwf cache status: 캐시 상태 확인
|
|
19
|
-
*/
|
|
20
|
-
class CacheCLI {
|
|
21
|
-
constructor() {
|
|
22
|
-
this.cache = new TemplateCache();
|
|
23
|
-
this.offlineDetector = new OfflineDetector();
|
|
24
|
-
this.downloader = new TemplateDownloader();
|
|
25
|
-
this.versionManager = new TemplateVersionManager();
|
|
26
|
-
|
|
27
|
-
// 의존성 주입
|
|
28
|
-
this.offlineDetector.setCache(this.cache);
|
|
29
|
-
this.downloader.setCache(this.cache);
|
|
30
|
-
this.downloader.setOfflineDetector(this.offlineDetector);
|
|
31
|
-
this.versionManager.setCache(this.cache);
|
|
32
|
-
this.versionManager.setDownloader(this.downloader);
|
|
33
|
-
this.versionManager.setOfflineDetector(this.offlineDetector);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* CLI 초기화
|
|
38
|
-
*/
|
|
39
|
-
async init() {
|
|
40
|
-
await this.cache.init();
|
|
41
|
-
await this.offlineDetector.start();
|
|
42
|
-
await this.versionManager.init();
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* 템플릿 다운로드 명령어
|
|
47
|
-
*/
|
|
48
|
-
async downloadCommand(options = {}) {
|
|
49
|
-
const spinner = ora('Scanning available templates...').start();
|
|
50
|
-
|
|
51
|
-
try {
|
|
52
|
-
const templates = await this.downloader.scanAvailableTemplates();
|
|
53
|
-
spinner.stop();
|
|
54
|
-
|
|
55
|
-
if (options.all) {
|
|
56
|
-
return await this.downloadAllTemplates();
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (options.type) {
|
|
60
|
-
return await this.downloadTemplatesByType(options.type);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// 대화형 선택
|
|
64
|
-
return await this.interactiveDownload(templates);
|
|
65
|
-
|
|
66
|
-
} catch (error) {
|
|
67
|
-
spinner.fail(chalk.red(`Failed to scan templates: ${error.message}`));
|
|
68
|
-
process.exit(1);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* 모든 템플릿 다운로드
|
|
74
|
-
*/
|
|
75
|
-
async downloadAllTemplates() {
|
|
76
|
-
const spinner = ora('Downloading all templates...').start();
|
|
77
|
-
|
|
78
|
-
try {
|
|
79
|
-
const result = await this.downloader.downloadAllTemplates();
|
|
80
|
-
spinner.stop();
|
|
81
|
-
|
|
82
|
-
this.displayDownloadResults(result);
|
|
83
|
-
return result;
|
|
84
|
-
|
|
85
|
-
} catch (error) {
|
|
86
|
-
spinner.fail(chalk.red(`Download failed: ${error.message}`));
|
|
87
|
-
process.exit(1);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* 타입별 템플릿 다운로드
|
|
93
|
-
*/
|
|
94
|
-
async downloadTemplatesByType(type) {
|
|
95
|
-
const spinner = ora(`Downloading ${type} templates...`).start();
|
|
96
|
-
|
|
97
|
-
try {
|
|
98
|
-
const result = await this.downloader.downloadTemplatesByType(type);
|
|
99
|
-
spinner.stop();
|
|
100
|
-
|
|
101
|
-
this.displayDownloadResults(result);
|
|
102
|
-
return result;
|
|
103
|
-
|
|
104
|
-
} catch (error) {
|
|
105
|
-
spinner.fail(chalk.red(`Download failed: ${error.message}`));
|
|
106
|
-
process.exit(1);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* 대화형 다운로드
|
|
112
|
-
*/
|
|
113
|
-
async interactiveDownload(templates) {
|
|
114
|
-
const choices = [];
|
|
115
|
-
|
|
116
|
-
// AI 도구 선택지
|
|
117
|
-
if (Object.keys(templates['ai-tools']).length > 0) {
|
|
118
|
-
choices.push({
|
|
119
|
-
title: chalk.cyan('AI Tools'),
|
|
120
|
-
value: 'ai-tools-all',
|
|
121
|
-
description: 'All AI development tools'
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
for (const [name, info] of Object.entries(templates['ai-tools'])) {
|
|
125
|
-
choices.push({
|
|
126
|
-
title: ` ${name}`,
|
|
127
|
-
value: `ai-tools:${name}`,
|
|
128
|
-
description: info.description || 'AI development tool'
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// 프로젝트 템플릿 선택지
|
|
134
|
-
if (Object.keys(templates['projects']).length > 0) {
|
|
135
|
-
choices.push({
|
|
136
|
-
title: chalk.green('Project Templates'),
|
|
137
|
-
value: 'projects-all',
|
|
138
|
-
description: 'All project templates'
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
for (const [name, info] of Object.entries(templates['projects'])) {
|
|
142
|
-
choices.push({
|
|
143
|
-
title: ` ${name}`,
|
|
144
|
-
value: `projects:${name}`,
|
|
145
|
-
description: info.description || 'Project template'
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const response = await prompts({
|
|
151
|
-
type: 'multiselect',
|
|
152
|
-
name: 'templates',
|
|
153
|
-
message: 'Select templates to download:',
|
|
154
|
-
choices,
|
|
155
|
-
hint: 'Space to select, Enter to confirm'
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
if (!response.templates || response.templates.length === 0) {
|
|
159
|
-
console.log(chalk.yellow('No templates selected.'));
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const selections = this.parseSelections(response.templates, templates);
|
|
164
|
-
|
|
165
|
-
const spinner = ora('Downloading selected templates...').start();
|
|
166
|
-
|
|
167
|
-
// 다운로드 진행률 표시
|
|
168
|
-
let currentTemplate = '';
|
|
169
|
-
this.downloader.on('templateStart', ({ type, name }) => {
|
|
170
|
-
currentTemplate = `${type}/${name}`;
|
|
171
|
-
spinner.text = `Downloading ${currentTemplate}...`;
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
this.downloader.on('progress', ({ completed, total, percentage }) => {
|
|
175
|
-
spinner.text = `Downloaded ${completed}/${total} templates (${percentage.toFixed(1)}%)`;
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
try {
|
|
179
|
-
const result = await this.downloader.downloadSelectedTemplates(selections);
|
|
180
|
-
spinner.stop();
|
|
181
|
-
|
|
182
|
-
this.displayDownloadResults(result);
|
|
183
|
-
return result;
|
|
184
|
-
|
|
185
|
-
} catch (error) {
|
|
186
|
-
spinner.fail(chalk.red(`Download failed: ${error.message}`));
|
|
187
|
-
process.exit(1);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* 선택사항 파싱
|
|
193
|
-
*/
|
|
194
|
-
parseSelections(selections, templates) {
|
|
195
|
-
const parsed = [];
|
|
196
|
-
|
|
197
|
-
for (const selection of selections) {
|
|
198
|
-
if (selection === 'ai-tools-all') {
|
|
199
|
-
for (const [name, info] of Object.entries(templates['ai-tools'])) {
|
|
200
|
-
parsed.push({
|
|
201
|
-
type: 'ai-tools',
|
|
202
|
-
name,
|
|
203
|
-
version: info.version
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
} else if (selection === 'projects-all') {
|
|
207
|
-
for (const [name, info] of Object.entries(templates['projects'])) {
|
|
208
|
-
parsed.push({
|
|
209
|
-
type: 'projects',
|
|
210
|
-
name,
|
|
211
|
-
version: info.version
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
} else if (selection.includes(':')) {
|
|
215
|
-
const [type, name] = selection.split(':');
|
|
216
|
-
const info = templates[type][name];
|
|
217
|
-
parsed.push({
|
|
218
|
-
type,
|
|
219
|
-
name,
|
|
220
|
-
version: info.version
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
return parsed;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* 다운로드 결과 표시
|
|
230
|
-
*/
|
|
231
|
-
displayDownloadResults(result) {
|
|
232
|
-
console.log('\\n' + chalk.bold('Download Results:'));
|
|
233
|
-
console.log(chalk.green(`✅ Completed: ${result.completed}/${result.total}`));
|
|
234
|
-
|
|
235
|
-
if (result.failed > 0) {
|
|
236
|
-
console.log(chalk.red(`❌ Failed: ${result.failed}`));
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// 성공한 다운로드 표시
|
|
240
|
-
const successful = result.results.filter(r => r.success);
|
|
241
|
-
if (successful.length > 0) {
|
|
242
|
-
console.log('\\n' + chalk.green('Successfully downloaded:'));
|
|
243
|
-
for (const item of successful) {
|
|
244
|
-
console.log(` ${chalk.cyan(item.type)}/${chalk.white(item.name)} ${chalk.gray(`v${item.version}`)}`);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// 실패한 다운로드 표시
|
|
249
|
-
const failed = result.results.filter(r => !r.success);
|
|
250
|
-
if (failed.length > 0) {
|
|
251
|
-
console.log('\\n' + chalk.red('Failed downloads:'));
|
|
252
|
-
for (const item of failed) {
|
|
253
|
-
console.log(` ${chalk.cyan(item.type)}/${chalk.white(item.name)} ${chalk.gray(`v${item.version}`)} - ${chalk.red(item.error)}`);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* 캐시 목록 조회
|
|
260
|
-
*/
|
|
261
|
-
async listCommand(options = {}) {
|
|
262
|
-
try {
|
|
263
|
-
const templates = await this.cache.listTemplates(options.type);
|
|
264
|
-
const stats = this.cache.getStats();
|
|
265
|
-
|
|
266
|
-
console.log(chalk.bold('Template Cache Status:'));
|
|
267
|
-
console.log(`📦 Total templates: ${chalk.cyan(stats.templatesCount)}`);
|
|
268
|
-
console.log(`💾 Total size: ${chalk.cyan(this.formatBytes(stats.totalSize))}`);
|
|
269
|
-
console.log(`📈 Cache usage: ${chalk.cyan(stats.usagePercentage)}`);
|
|
270
|
-
console.log(`🎯 Hit rate: ${chalk.cyan(stats.hitRate)}`);
|
|
271
|
-
|
|
272
|
-
if (stats.lastUpdate) {
|
|
273
|
-
console.log(`🕒 Last update: ${chalk.gray(new Date(stats.lastUpdate).toLocaleString())}`);
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
// AI 도구 목록
|
|
277
|
-
if (templates['ai-tools'] && Object.keys(templates['ai-tools']).length > 0) {
|
|
278
|
-
console.log('\\n' + chalk.cyan.bold('AI Tools:'));
|
|
279
|
-
for (const [name, info] of Object.entries(templates['ai-tools'])) {
|
|
280
|
-
console.log(` ${chalk.white(name)} ${chalk.gray(`v${info.version}`)} ${chalk.dim(`(${this.formatBytes(info.size)})`)}`);
|
|
281
|
-
console.log(` ${chalk.gray(`Cached: ${new Date(info.cached_at).toLocaleString()}`)}`);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// 프로젝트 템플릿 목록
|
|
286
|
-
if (templates['projects'] && Object.keys(templates['projects']).length > 0) {
|
|
287
|
-
console.log('\\n' + chalk.green.bold('Project Templates:'));
|
|
288
|
-
for (const [name, info] of Object.entries(templates['projects'])) {
|
|
289
|
-
console.log(` ${chalk.white(name)} ${chalk.gray(`v${info.version}`)} ${chalk.dim(`(${this.formatBytes(info.size)})`)}`);
|
|
290
|
-
console.log(` ${chalk.gray(`Cached: ${new Date(info.cached_at).toLocaleString()}`)}`);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
if (stats.templatesCount === 0) {
|
|
295
|
-
console.log('\\n' + chalk.yellow('No templates cached. Use `aiwf cache download` to cache templates.'));
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
} catch (error) {
|
|
299
|
-
console.error(chalk.red(`Failed to list cache: ${error.message}`));
|
|
300
|
-
process.exit(1);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/**
|
|
305
|
-
* 캐시 정리
|
|
306
|
-
*/
|
|
307
|
-
async cleanCommand(options = {}) {
|
|
308
|
-
try {
|
|
309
|
-
if (options.all) {
|
|
310
|
-
const response = await prompts({
|
|
311
|
-
type: 'confirm',
|
|
312
|
-
name: 'confirm',
|
|
313
|
-
message: 'Are you sure you want to clear all cached templates?',
|
|
314
|
-
initial: false
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
if (!response.confirm) {
|
|
318
|
-
console.log(chalk.yellow('Cache clear cancelled.'));
|
|
319
|
-
return;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
const spinner = ora('Clearing cache...').start();
|
|
323
|
-
await this.cache.clear();
|
|
324
|
-
spinner.succeed(chalk.green('Cache cleared successfully.'));
|
|
325
|
-
|
|
326
|
-
} else {
|
|
327
|
-
const spinner = ora('Cleaning up expired cache...').start();
|
|
328
|
-
const result = await this.cache.cleanup({
|
|
329
|
-
maxAge: options.maxAge || 7 * 24 * 60 * 60 * 1000 // 7일
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
spinner.succeed(
|
|
333
|
-
chalk.green(`Cleaned up ${result.removedCount} expired templates. `) +
|
|
334
|
-
chalk.gray(`Freed ${this.formatBytes(result.freedSpace)}.`)
|
|
335
|
-
);
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
} catch (error) {
|
|
339
|
-
console.error(chalk.red(`Failed to clean cache: ${error.message}`));
|
|
340
|
-
process.exit(1);
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
/**
|
|
345
|
-
* 업데이트 확인
|
|
346
|
-
*/
|
|
347
|
-
async updateCommand(options = {}) {
|
|
348
|
-
const spinner = ora('Checking for updates...').start();
|
|
349
|
-
|
|
350
|
-
try {
|
|
351
|
-
const updateInfo = await this.versionManager.checkForUpdates();
|
|
352
|
-
const availableUpdates = updateInfo.updates.filter(u => u.needsUpdate);
|
|
353
|
-
|
|
354
|
-
spinner.stop();
|
|
355
|
-
|
|
356
|
-
if (availableUpdates.length === 0) {
|
|
357
|
-
console.log(chalk.green('✅ All templates are up to date.'));
|
|
358
|
-
return;
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
console.log(chalk.yellow(`📦 ${availableUpdates.length} updates available:`));
|
|
362
|
-
|
|
363
|
-
for (const update of availableUpdates) {
|
|
364
|
-
console.log(` ${chalk.cyan(update.type)}/${chalk.white(update.name)}: ` +
|
|
365
|
-
`${chalk.gray(update.currentVersion || 'not cached')} → ${chalk.green(update.availableVersion)}`);
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
if (options.install) {
|
|
369
|
-
const response = await prompts({
|
|
370
|
-
type: 'confirm',
|
|
371
|
-
name: 'confirm',
|
|
372
|
-
message: 'Install all available updates?',
|
|
373
|
-
initial: true
|
|
374
|
-
});
|
|
375
|
-
|
|
376
|
-
if (response.confirm) {
|
|
377
|
-
const updateSpinner = ora('Installing updates...').start();
|
|
378
|
-
const results = await this.versionManager.updateAllTemplates();
|
|
379
|
-
updateSpinner.stop();
|
|
380
|
-
|
|
381
|
-
const successCount = results.filter(r => r.success).length;
|
|
382
|
-
const failCount = results.filter(r => !r.success).length;
|
|
383
|
-
|
|
384
|
-
console.log(chalk.green(`✅ ${successCount} templates updated successfully`));
|
|
385
|
-
if (failCount > 0) {
|
|
386
|
-
console.log(chalk.red(`❌ ${failCount} templates failed to update`));
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
} catch (error) {
|
|
392
|
-
spinner.fail(chalk.red(`Failed to check updates: ${error.message}`));
|
|
393
|
-
process.exit(1);
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
/**
|
|
398
|
-
* 캐시 상태 확인
|
|
399
|
-
*/
|
|
400
|
-
async statusCommand() {
|
|
401
|
-
try {
|
|
402
|
-
const cacheStats = this.cache.getStats();
|
|
403
|
-
const networkInfo = this.offlineDetector.getNetworkStats();
|
|
404
|
-
const versionStats = this.versionManager.getStats();
|
|
405
|
-
|
|
406
|
-
console.log(chalk.bold('AIWF Cache System Status\\n'));
|
|
407
|
-
|
|
408
|
-
// 네트워크 상태
|
|
409
|
-
console.log(chalk.bold('Network Status:'));
|
|
410
|
-
const statusColor = networkInfo.status === 'online' ? chalk.green : chalk.red;
|
|
411
|
-
console.log(` Status: ${statusColor(networkInfo.status.toUpperCase())}`);
|
|
412
|
-
console.log(` Uptime: ${chalk.cyan(networkInfo.uptime)}`);
|
|
413
|
-
console.log(` Downtime: ${chalk.cyan(networkInfo.downtime)}`);
|
|
414
|
-
console.log(` Offline mode: ${networkInfo.offlineMode ? chalk.yellow('enabled') : chalk.green('disabled')}`);
|
|
415
|
-
|
|
416
|
-
// 캐시 통계
|
|
417
|
-
console.log('\\n' + chalk.bold('Cache Statistics:'));
|
|
418
|
-
console.log(` Templates: ${chalk.cyan(cacheStats.templatesCount)}`);
|
|
419
|
-
console.log(` Total size: ${chalk.cyan(this.formatBytes(cacheStats.totalSize))}`);
|
|
420
|
-
console.log(` Usage: ${chalk.cyan(cacheStats.usagePercentage)} of ${this.formatBytes(cacheStats.maxCacheSize)}`);
|
|
421
|
-
console.log(` Hit rate: ${chalk.cyan(cacheStats.hitRate)}`);
|
|
422
|
-
|
|
423
|
-
// 버전 관리
|
|
424
|
-
console.log('\\n' + chalk.bold('Version Management:'));
|
|
425
|
-
console.log(` Total templates: ${chalk.cyan(versionStats.totalTemplates)}`);
|
|
426
|
-
console.log(` Total versions: ${chalk.cyan(versionStats.totalVersions)}`);
|
|
427
|
-
console.log(` Cached versions: ${chalk.cyan(versionStats.cachedVersions)}`);
|
|
428
|
-
if (versionStats.lastCheck) {
|
|
429
|
-
console.log(` Last check: ${chalk.gray(new Date(versionStats.lastCheck).toLocaleString())}`);
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
} catch (error) {
|
|
433
|
-
console.error(chalk.red(`Failed to get status: ${error.message}`));
|
|
434
|
-
process.exit(1);
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
/**
|
|
439
|
-
* 바이트 포맷팅
|
|
440
|
-
*/
|
|
441
|
-
formatBytes(bytes) {
|
|
442
|
-
if (bytes === 0) return '0 Bytes';
|
|
443
|
-
|
|
444
|
-
const k = 1024;
|
|
445
|
-
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
446
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
447
|
-
|
|
448
|
-
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
/**
|
|
452
|
-
* CLI 종료
|
|
453
|
-
*/
|
|
454
|
-
async cleanup() {
|
|
455
|
-
this.offlineDetector.stop();
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
export { CacheCLI };
|