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/commands/ai-tool.js
DELETED
|
@@ -1,383 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import fs from 'fs-extra';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
6
|
-
import chalk from 'chalk';
|
|
7
|
-
import ora from 'ora';
|
|
8
|
-
// import { table } from 'table'; // 임시로 비활성화
|
|
9
|
-
|
|
10
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* AI Tool integration command for AIWF
|
|
14
|
-
* Manages AI tool templates and configurations
|
|
15
|
-
*/
|
|
16
|
-
export class AIToolCommand {
|
|
17
|
-
constructor() {
|
|
18
|
-
this.toolsPath = path.join(process.cwd(), '.aiwf', 'ai-tools');
|
|
19
|
-
this.availableTools = ['claude-code', 'github-copilot', 'cursor', 'windsurf', 'augment'];
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Main command handler
|
|
24
|
-
*/
|
|
25
|
-
async execute(args) {
|
|
26
|
-
const subcommand = args[0];
|
|
27
|
-
const toolName = args[1];
|
|
28
|
-
|
|
29
|
-
switch (subcommand) {
|
|
30
|
-
case 'install':
|
|
31
|
-
return await this.install(toolName);
|
|
32
|
-
case 'list':
|
|
33
|
-
return await this.list();
|
|
34
|
-
case 'update':
|
|
35
|
-
return await this.update(toolName);
|
|
36
|
-
case 'verify':
|
|
37
|
-
return await this.verify(toolName);
|
|
38
|
-
case 'check':
|
|
39
|
-
return await this.check(toolName);
|
|
40
|
-
case 'version':
|
|
41
|
-
return await this.version(toolName);
|
|
42
|
-
default:
|
|
43
|
-
return this.showHelp();
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Install an AI tool template
|
|
49
|
-
*/
|
|
50
|
-
async install(toolName) {
|
|
51
|
-
if (!toolName) {
|
|
52
|
-
console.error(chalk.red('Error: Tool name is required'));
|
|
53
|
-
console.log('Usage: aiwf ai-tool install <tool-name>');
|
|
54
|
-
console.log(`Available tools: ${this.availableTools.join(', ')}`);
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (!this.availableTools.includes(toolName)) {
|
|
59
|
-
console.error(chalk.red(`Error: Unknown tool '${toolName}'`));
|
|
60
|
-
console.log(`Available tools: ${this.availableTools.join(', ')}`);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const spinner = ora(`Installing ${toolName} template...`).start();
|
|
65
|
-
|
|
66
|
-
try {
|
|
67
|
-
const toolPath = path.join(this.toolsPath, toolName);
|
|
68
|
-
const configPath = path.join(toolPath, 'config.json');
|
|
69
|
-
|
|
70
|
-
// Check if tool template exists
|
|
71
|
-
if (!await fs.pathExists(configPath)) {
|
|
72
|
-
spinner.fail(`Template for ${toolName} not found`);
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Read configuration
|
|
77
|
-
const config = await fs.readJson(configPath);
|
|
78
|
-
|
|
79
|
-
// Copy template files
|
|
80
|
-
for (const fileToCopy of config.files_to_copy) {
|
|
81
|
-
const sourcePath = path.join(toolPath, fileToCopy.source);
|
|
82
|
-
const destPath = path.join(process.cwd(), fileToCopy.destination);
|
|
83
|
-
|
|
84
|
-
if (await fs.pathExists(sourcePath)) {
|
|
85
|
-
await fs.copy(sourcePath, destPath, { overwrite: true });
|
|
86
|
-
spinner.text = `Copying ${fileToCopy.destination}...`;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Run setup commands if any
|
|
91
|
-
if (config.setup_commands && config.setup_commands.length > 0) {
|
|
92
|
-
spinner.text = 'Running setup commands...';
|
|
93
|
-
const { exec } = await import('child_process');
|
|
94
|
-
const { promisify } = await import('util');
|
|
95
|
-
const execAsync = promisify(exec);
|
|
96
|
-
|
|
97
|
-
for (const command of config.setup_commands) {
|
|
98
|
-
await execAsync(command);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Create installation record
|
|
103
|
-
const installRecord = {
|
|
104
|
-
tool: toolName,
|
|
105
|
-
version: config.version,
|
|
106
|
-
installedAt: new Date().toISOString(),
|
|
107
|
-
features: config.features
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
const recordPath = path.join(process.cwd(), '.aiwf', 'ai-tools-installed.json');
|
|
111
|
-
let installedTools = {};
|
|
112
|
-
|
|
113
|
-
if (await fs.pathExists(recordPath)) {
|
|
114
|
-
installedTools = await fs.readJson(recordPath);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
installedTools[toolName] = installRecord;
|
|
118
|
-
await fs.writeJson(recordPath, installedTools, { spaces: 2 });
|
|
119
|
-
|
|
120
|
-
spinner.succeed(chalk.green(`Successfully installed ${toolName} template`));
|
|
121
|
-
|
|
122
|
-
// Show post-installation message
|
|
123
|
-
console.log('\n' + chalk.cyan('Next steps:'));
|
|
124
|
-
console.log(`1. Review the installed files`);
|
|
125
|
-
console.log(`2. Customize settings as needed`);
|
|
126
|
-
console.log(`3. Read the documentation in .aiwf/ai-tools/${toolName}/README.md`);
|
|
127
|
-
|
|
128
|
-
// Show feature status
|
|
129
|
-
if (config.features) {
|
|
130
|
-
console.log('\n' + chalk.cyan('Enabled features:'));
|
|
131
|
-
Object.entries(config.features).forEach(([feature, enabled]) => {
|
|
132
|
-
if (enabled) {
|
|
133
|
-
console.log(` ✓ ${feature}`);
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
} catch (error) {
|
|
139
|
-
spinner.fail(`Failed to install ${toolName}: ${error.message}`);
|
|
140
|
-
console.error(chalk.red(error.stack));
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* List available and installed AI tools
|
|
146
|
-
*/
|
|
147
|
-
async list() {
|
|
148
|
-
console.log(chalk.cyan('\n🤖 AI Tool Templates\n'));
|
|
149
|
-
|
|
150
|
-
const installedPath = path.join(process.cwd(), '.aiwf', 'ai-tools-installed.json');
|
|
151
|
-
let installedTools = {};
|
|
152
|
-
|
|
153
|
-
if (await fs.pathExists(installedPath)) {
|
|
154
|
-
installedTools = await fs.readJson(installedPath);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
const tableData = [
|
|
158
|
-
['Tool', 'Status', 'Version', 'Features']
|
|
159
|
-
];
|
|
160
|
-
|
|
161
|
-
for (const toolName of this.availableTools) {
|
|
162
|
-
const toolPath = path.join(this.toolsPath, toolName);
|
|
163
|
-
const configPath = path.join(toolPath, 'config.json');
|
|
164
|
-
|
|
165
|
-
if (await fs.pathExists(configPath)) {
|
|
166
|
-
const config = await fs.readJson(configPath);
|
|
167
|
-
const isInstalled = installedTools[toolName] ? '✓ Installed' : 'Available';
|
|
168
|
-
const status = isInstalled === '✓ Installed' ? chalk.green(isInstalled) : chalk.gray(isInstalled);
|
|
169
|
-
const version = installedTools[toolName]?.version || config.version;
|
|
170
|
-
const features = Object.entries(config.features)
|
|
171
|
-
.filter(([_, enabled]) => enabled)
|
|
172
|
-
.map(([feature]) => feature)
|
|
173
|
-
.slice(0, 3)
|
|
174
|
-
.join(', ') + (Object.keys(config.features).length > 3 ? '...' : '');
|
|
175
|
-
|
|
176
|
-
tableData.push([
|
|
177
|
-
chalk.bold(toolName),
|
|
178
|
-
status,
|
|
179
|
-
version,
|
|
180
|
-
features
|
|
181
|
-
]);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
console.log(table(tableData, {
|
|
186
|
-
border: {
|
|
187
|
-
topBody: '─',
|
|
188
|
-
topJoin: '┬',
|
|
189
|
-
topLeft: '┌',
|
|
190
|
-
topRight: '┐',
|
|
191
|
-
bottomBody: '─',
|
|
192
|
-
bottomJoin: '┴',
|
|
193
|
-
bottomLeft: '└',
|
|
194
|
-
bottomRight: '┘',
|
|
195
|
-
bodyLeft: '│',
|
|
196
|
-
bodyRight: '│',
|
|
197
|
-
bodyJoin: '│',
|
|
198
|
-
joinBody: '─',
|
|
199
|
-
joinLeft: '├',
|
|
200
|
-
joinRight: '┤',
|
|
201
|
-
joinJoin: '┼'
|
|
202
|
-
}
|
|
203
|
-
}));
|
|
204
|
-
|
|
205
|
-
console.log('\n' + chalk.cyan('Commands:'));
|
|
206
|
-
console.log(' Install a tool: aiwf ai-tool install <tool-name>');
|
|
207
|
-
console.log(' Update a tool: aiwf ai-tool update <tool-name>');
|
|
208
|
-
console.log(' Verify a tool: aiwf ai-tool verify <tool-name>');
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Update an installed AI tool template
|
|
213
|
-
*/
|
|
214
|
-
async update(toolName) {
|
|
215
|
-
if (!toolName) {
|
|
216
|
-
console.error(chalk.red('Error: Tool name is required'));
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
const installedPath = path.join(process.cwd(), '.aiwf', 'ai-tools-installed.json');
|
|
221
|
-
|
|
222
|
-
if (!await fs.pathExists(installedPath)) {
|
|
223
|
-
console.error(chalk.red('No AI tools installed'));
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
const installedTools = await fs.readJson(installedPath);
|
|
228
|
-
|
|
229
|
-
if (!installedTools[toolName]) {
|
|
230
|
-
console.error(chalk.red(`${toolName} is not installed`));
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
console.log(chalk.cyan(`Updating ${toolName}...`));
|
|
235
|
-
|
|
236
|
-
// Reinstall with latest template
|
|
237
|
-
await this.install(toolName);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* Verify an installed AI tool
|
|
242
|
-
*/
|
|
243
|
-
async verify(toolName) {
|
|
244
|
-
if (!toolName) {
|
|
245
|
-
console.error(chalk.red('Error: Tool name is required'));
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
const spinner = ora(`Verifying ${toolName} installation...`).start();
|
|
250
|
-
|
|
251
|
-
try {
|
|
252
|
-
const toolPath = path.join(this.toolsPath, toolName);
|
|
253
|
-
const configPath = path.join(toolPath, 'config.json');
|
|
254
|
-
const config = await fs.readJson(configPath);
|
|
255
|
-
|
|
256
|
-
let allFilesExist = true;
|
|
257
|
-
const missingFiles = [];
|
|
258
|
-
|
|
259
|
-
// Check if all required files exist
|
|
260
|
-
for (const fileToCopy of config.files_to_copy) {
|
|
261
|
-
const destPath = path.join(process.cwd(), fileToCopy.destination);
|
|
262
|
-
if (!await fs.pathExists(destPath)) {
|
|
263
|
-
allFilesExist = false;
|
|
264
|
-
missingFiles.push(fileToCopy.destination);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
if (allFilesExist) {
|
|
269
|
-
spinner.succeed(chalk.green(`${toolName} installation verified successfully`));
|
|
270
|
-
} else {
|
|
271
|
-
spinner.fail(chalk.red(`${toolName} installation incomplete`));
|
|
272
|
-
console.log(chalk.yellow('\nMissing files:'));
|
|
273
|
-
missingFiles.forEach(file => console.log(` - ${file}`));
|
|
274
|
-
console.log(chalk.cyan(`\nRun 'aiwf ai-tool install ${toolName}' to fix`));
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
} catch (error) {
|
|
278
|
-
spinner.fail(`Failed to verify ${toolName}: ${error.message}`);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* Check for updates for a tool
|
|
284
|
-
*/
|
|
285
|
-
async check(toolName) {
|
|
286
|
-
if (!toolName) {
|
|
287
|
-
// Check all installed tools
|
|
288
|
-
const installedPath = path.join(process.cwd(), '.aiwf', 'ai-tools-installed.json');
|
|
289
|
-
|
|
290
|
-
if (!await fs.pathExists(installedPath)) {
|
|
291
|
-
console.log(chalk.yellow('No AI tools installed'));
|
|
292
|
-
return;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
const installedTools = await fs.readJson(installedPath);
|
|
296
|
-
console.log(chalk.cyan('\nChecking for updates...\n'));
|
|
297
|
-
|
|
298
|
-
for (const [tool, info] of Object.entries(installedTools)) {
|
|
299
|
-
await this.checkSingleTool(tool, info.version);
|
|
300
|
-
}
|
|
301
|
-
} else {
|
|
302
|
-
await this.checkSingleTool(toolName);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* Check a single tool for updates
|
|
308
|
-
*/
|
|
309
|
-
async checkSingleTool(toolName, installedVersion) {
|
|
310
|
-
const toolPath = path.join(this.toolsPath, toolName);
|
|
311
|
-
const configPath = path.join(toolPath, 'config.json');
|
|
312
|
-
|
|
313
|
-
if (await fs.pathExists(configPath)) {
|
|
314
|
-
const config = await fs.readJson(configPath);
|
|
315
|
-
const latestVersion = config.version;
|
|
316
|
-
|
|
317
|
-
if (!installedVersion) {
|
|
318
|
-
// Get installed version
|
|
319
|
-
const installedPath = path.join(process.cwd(), '.aiwf', 'ai-tools-installed.json');
|
|
320
|
-
if (await fs.pathExists(installedPath)) {
|
|
321
|
-
const installedTools = await fs.readJson(installedPath);
|
|
322
|
-
installedVersion = installedTools[toolName]?.version;
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
if (installedVersion && installedVersion !== latestVersion) {
|
|
327
|
-
console.log(chalk.yellow(`${toolName}: Update available (${installedVersion} → ${latestVersion})`));
|
|
328
|
-
} else if (installedVersion) {
|
|
329
|
-
console.log(chalk.green(`${toolName}: Up to date (${latestVersion})`));
|
|
330
|
-
} else {
|
|
331
|
-
console.log(chalk.gray(`${toolName}: Not installed`));
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
* Show version of a tool
|
|
338
|
-
*/
|
|
339
|
-
async version(toolName) {
|
|
340
|
-
if (!toolName) {
|
|
341
|
-
console.error(chalk.red('Error: Tool name is required'));
|
|
342
|
-
return;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
const installedPath = path.join(process.cwd(), '.aiwf', 'ai-tools-installed.json');
|
|
346
|
-
|
|
347
|
-
if (await fs.pathExists(installedPath)) {
|
|
348
|
-
const installedTools = await fs.readJson(installedPath);
|
|
349
|
-
if (installedTools[toolName]) {
|
|
350
|
-
console.log(`${toolName}: ${installedTools[toolName].version}`);
|
|
351
|
-
return;
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
console.log(chalk.yellow(`${toolName} is not installed`));
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
* Show help message
|
|
360
|
-
*/
|
|
361
|
-
showHelp() {
|
|
362
|
-
console.log(chalk.cyan('\n🤖 AIWF AI Tool Integration\n'));
|
|
363
|
-
console.log('Usage: aiwf ai-tool <command> [tool-name]');
|
|
364
|
-
console.log('\nCommands:');
|
|
365
|
-
console.log(' install <tool> Install an AI tool template');
|
|
366
|
-
console.log(' list List available and installed tools');
|
|
367
|
-
console.log(' update <tool> Update an installed tool');
|
|
368
|
-
console.log(' verify <tool> Verify tool installation');
|
|
369
|
-
console.log(' check [tool] Check for updates');
|
|
370
|
-
console.log(' version <tool> Show installed version');
|
|
371
|
-
console.log('\nAvailable tools:');
|
|
372
|
-
this.availableTools.forEach(tool => {
|
|
373
|
-
console.log(` - ${tool}`);
|
|
374
|
-
});
|
|
375
|
-
console.log('\nExamples:');
|
|
376
|
-
console.log(' aiwf ai-tool install claude-code');
|
|
377
|
-
console.log(' aiwf ai-tool list');
|
|
378
|
-
console.log(' aiwf ai-tool update cursor');
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
// Export for use in main CLI
|
|
383
|
-
export default AIToolCommand;
|
package/src/commands/compress.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* AIWF 컨텍스트 압축 명령어
|
|
5
|
-
* 대용량 컨텍스트를 효율적으로 압축하여 토큰 사용량 감소
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { ResourceLoader } from '../lib/resource-loader.js';
|
|
9
|
-
import chalk from 'chalk';
|
|
10
|
-
|
|
11
|
-
class CompressCommand {
|
|
12
|
-
constructor() {
|
|
13
|
-
this.resourceLoader = new ResourceLoader();
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* 압축 명령어 실행
|
|
18
|
-
*/
|
|
19
|
-
async execute(args) {
|
|
20
|
-
try {
|
|
21
|
-
// compress-context 모듈 동적 로드
|
|
22
|
-
const compressModule = await this.resourceLoader.loadUtil('compress-context.js');
|
|
23
|
-
const executeCompressContext = compressModule.executeCompressContext || compressModule.default;
|
|
24
|
-
|
|
25
|
-
if (typeof executeCompressContext !== 'function') {
|
|
26
|
-
throw new Error('compress-context 모듈을 로드할 수 없습니다.');
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// 실행
|
|
30
|
-
await executeCompressContext(args);
|
|
31
|
-
|
|
32
|
-
} catch (error) {
|
|
33
|
-
console.error(chalk.red('❌ 압축 실행 중 오류가 발생했습니다:'), error.message);
|
|
34
|
-
this.showHelp();
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* 도움말 표시
|
|
40
|
-
*/
|
|
41
|
-
showHelp() {
|
|
42
|
-
console.log(chalk.cyan('\n🗜️ AIWF 컨텍스트 압축'));
|
|
43
|
-
console.log(chalk.gray('-'.repeat(50)));
|
|
44
|
-
console.log('사용법: aiwf compress [옵션] [경로]');
|
|
45
|
-
console.log('');
|
|
46
|
-
console.log('옵션:');
|
|
47
|
-
console.log(' aggressive 공격적 압축 (50-70% 토큰 감소)');
|
|
48
|
-
console.log(' balanced 균형잡힌 압축 (30-50% 토큰 감소) [기본값]');
|
|
49
|
-
console.log(' minimal 최소 압축 (10-30% 토큰 감소)');
|
|
50
|
-
console.log(' --persona 페르소나 인식 압축 활성화');
|
|
51
|
-
console.log('');
|
|
52
|
-
console.log('예시:');
|
|
53
|
-
console.log(' aiwf compress # 기본 압축');
|
|
54
|
-
console.log(' aiwf compress aggressive # 공격적 압축');
|
|
55
|
-
console.log(' aiwf compress --persona balanced # 페르소나 인식 압축');
|
|
56
|
-
console.log(' aiwf compress .aiwf # 특정 경로 압축');
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export default CompressCommand;
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import fs from 'fs-extra';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
6
|
-
import prompts from 'prompts';
|
|
7
|
-
import chalk from 'chalk';
|
|
8
|
-
import ora from 'ora';
|
|
9
|
-
import { ResourceLoader } from '../lib/resource-loader.js';
|
|
10
|
-
|
|
11
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
-
const __dirname = path.dirname(__filename);
|
|
13
|
-
|
|
14
|
-
// ResourceLoader를 사용하여 템플릿 관리
|
|
15
|
-
const resourceLoader = new ResourceLoader();
|
|
16
|
-
|
|
17
|
-
async function createProject() {
|
|
18
|
-
console.log(chalk.cyan('\n🚀 AIWF 프로젝트 생성기\n'));
|
|
19
|
-
|
|
20
|
-
// ResourceLoader를 사용하여 템플릿 찾기
|
|
21
|
-
const templates = await resourceLoader.listTemplates();
|
|
22
|
-
|
|
23
|
-
const templateConfigs = [];
|
|
24
|
-
for (const template of templates) {
|
|
25
|
-
try {
|
|
26
|
-
const config = await resourceLoader.loadTemplateConfig(template);
|
|
27
|
-
templateConfigs.push({
|
|
28
|
-
value: template,
|
|
29
|
-
title: config.displayName,
|
|
30
|
-
description: config.description
|
|
31
|
-
});
|
|
32
|
-
} catch (error) {
|
|
33
|
-
console.error(`템플릿 ${template} 로드 실패:`, error.message);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const questions = [
|
|
38
|
-
{
|
|
39
|
-
type: 'select',
|
|
40
|
-
name: 'template',
|
|
41
|
-
message: '템플릿을 선택하세요',
|
|
42
|
-
choices: templateConfigs,
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
type: 'text',
|
|
46
|
-
name: 'projectName',
|
|
47
|
-
message: '프로젝트 이름',
|
|
48
|
-
validate: value => {
|
|
49
|
-
if (!value) return '프로젝트 이름을 입력하세요';
|
|
50
|
-
if (!/^[a-z0-9-]+$/.test(value)) {
|
|
51
|
-
return '소문자, 숫자, 하이픈만 사용 가능합니다';
|
|
52
|
-
}
|
|
53
|
-
return true;
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
type: prev => prev === 'npm-library' ? 'text' : null,
|
|
58
|
-
name: 'description',
|
|
59
|
-
message: '프로젝트 설명',
|
|
60
|
-
initial: 'A new AIWF project'
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
type: prev => prev === 'npm-library' ? 'text' : null,
|
|
64
|
-
name: 'author',
|
|
65
|
-
message: '작성자',
|
|
66
|
-
initial: ''
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
type: 'text',
|
|
70
|
-
name: 'directory',
|
|
71
|
-
message: '프로젝트 디렉토리',
|
|
72
|
-
initial: prev => prev.projectName,
|
|
73
|
-
validate: value => {
|
|
74
|
-
if (!value) return '디렉토리를 입력하세요';
|
|
75
|
-
if (fs.existsSync(value)) {
|
|
76
|
-
return '이미 존재하는 디렉토리입니다';
|
|
77
|
-
}
|
|
78
|
-
return true;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
];
|
|
82
|
-
|
|
83
|
-
const answers = await prompts(questions);
|
|
84
|
-
|
|
85
|
-
if (!answers.template || !answers.projectName) {
|
|
86
|
-
console.log(chalk.red('\n❌ 프로젝트 생성이 취소되었습니다.'));
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const spinner = ora('프로젝트 생성 중...').start();
|
|
91
|
-
|
|
92
|
-
try {
|
|
93
|
-
// ResourceLoader를 사용하여 템플릿 경로 가져오기
|
|
94
|
-
const templatePath = await resourceLoader.getTemplatePath(answers.template);
|
|
95
|
-
const targetPath = path.resolve(answers.directory);
|
|
96
|
-
|
|
97
|
-
// 템플릿 복사
|
|
98
|
-
await fs.copy(templatePath, targetPath);
|
|
99
|
-
|
|
100
|
-
// 플레이스홀더 교체
|
|
101
|
-
const replacements = {
|
|
102
|
-
'{{projectName}}': answers.projectName,
|
|
103
|
-
'{{description}}': answers.description || '',
|
|
104
|
-
'{{author}}': answers.author || '',
|
|
105
|
-
'{{year}}': new Date().getFullYear().toString(),
|
|
106
|
-
'{{createdAt}}': new Date().toISOString(),
|
|
107
|
-
'{{username}}': answers.author?.toLowerCase().replace(/\s+/g, '') || 'username'
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
// 모든 파일에서 플레이스홀더 교체
|
|
111
|
-
await replacePlaceholders(targetPath, replacements);
|
|
112
|
-
|
|
113
|
-
spinner.succeed('프로젝트가 성공적으로 생성되었습니다!');
|
|
114
|
-
|
|
115
|
-
console.log(chalk.green(`\n✅ ${answers.projectName} 프로젝트가 생성되었습니다!\n`));
|
|
116
|
-
console.log('다음 명령어로 시작하세요:\n');
|
|
117
|
-
console.log(chalk.cyan(` cd ${answers.directory}`));
|
|
118
|
-
console.log(chalk.cyan(' npm install'));
|
|
119
|
-
console.log(chalk.cyan(' npm run dev\n'));
|
|
120
|
-
console.log('AIWF 명령어:');
|
|
121
|
-
console.log(chalk.gray(' npm run aiwf status # 프로젝트 상태 확인'));
|
|
122
|
-
console.log(chalk.gray(' npm run aiwf feature # Feature Ledger 관리\n'));
|
|
123
|
-
|
|
124
|
-
} catch (error) {
|
|
125
|
-
spinner.fail('프로젝트 생성 중 오류가 발생했습니다.');
|
|
126
|
-
console.error(chalk.red(error.message));
|
|
127
|
-
process.exit(1);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
async function replacePlaceholders(dir, replacements) {
|
|
132
|
-
const files = await fs.readdir(dir);
|
|
133
|
-
|
|
134
|
-
for (const file of files) {
|
|
135
|
-
const filePath = path.join(dir, file);
|
|
136
|
-
const stat = await fs.stat(filePath);
|
|
137
|
-
|
|
138
|
-
if (stat.isDirectory()) {
|
|
139
|
-
await replacePlaceholders(filePath, replacements);
|
|
140
|
-
} else if (stat.isFile()) {
|
|
141
|
-
let content = await fs.readFile(filePath, 'utf8');
|
|
142
|
-
|
|
143
|
-
for (const [placeholder, value] of Object.entries(replacements)) {
|
|
144
|
-
content = content.replace(new RegExp(placeholder, 'g'), value);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
await fs.writeFile(filePath, content, 'utf8');
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// CLI 실행
|
|
153
|
-
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
154
|
-
createProject().catch(error => {
|
|
155
|
-
console.error(chalk.red('오류:', error.message));
|
|
156
|
-
process.exit(1);
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
export { createProject };
|