mulby-cli 1.1.5
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/PLUGIN_DEVELOP_PROMPT.md +1164 -0
- package/README.md +852 -0
- package/assets/default-icon.png +0 -0
- package/dist/commands/ai-session.js +44 -0
- package/dist/commands/build.js +111 -0
- package/dist/commands/config-ai.js +291 -0
- package/dist/commands/config.js +53 -0
- package/dist/commands/create/ai-create.js +183 -0
- package/dist/commands/create/assets.js +53 -0
- package/dist/commands/create/basic.js +72 -0
- package/dist/commands/create/index.js +73 -0
- package/dist/commands/create/react.js +136 -0
- package/dist/commands/create/templates/basic.js +383 -0
- package/dist/commands/create/templates/react/backend.js +72 -0
- package/dist/commands/create/templates/react/config.js +166 -0
- package/dist/commands/create/templates/react/docs.js +78 -0
- package/dist/commands/create/templates/react/hooks.js +469 -0
- package/dist/commands/create/templates/react/index.js +41 -0
- package/dist/commands/create/templates/react/types.js +1228 -0
- package/dist/commands/create/templates/react/ui.js +528 -0
- package/dist/commands/create/templates/react.js +1888 -0
- package/dist/commands/dev.js +141 -0
- package/dist/commands/pack.js +160 -0
- package/dist/commands/resume.js +97 -0
- package/dist/commands/test-ui.js +50 -0
- package/dist/index.js +71 -0
- package/dist/services/ai/PLUGIN_API.md +1102 -0
- package/dist/services/ai/PLUGIN_DEVELOP_PROMPT.md +1164 -0
- package/dist/services/ai/context-manager.js +639 -0
- package/dist/services/ai/index.js +88 -0
- package/dist/services/ai/knowledge.js +52 -0
- package/dist/services/ai/prompts.js +114 -0
- package/dist/services/ai/providers/base.js +38 -0
- package/dist/services/ai/providers/claude.js +284 -0
- package/dist/services/ai/providers/deepseek.js +28 -0
- package/dist/services/ai/providers/gemini.js +191 -0
- package/dist/services/ai/providers/glm.js +31 -0
- package/dist/services/ai/providers/minimax.js +27 -0
- package/dist/services/ai/providers/openai.js +177 -0
- package/dist/services/ai/tools.js +204 -0
- package/dist/services/ai-generator.js +968 -0
- package/dist/services/config-manager.js +117 -0
- package/dist/services/dependency-manager.js +236 -0
- package/dist/services/file-writer.js +66 -0
- package/dist/services/plan-adapter.js +244 -0
- package/dist/services/plan-command-handler.js +172 -0
- package/dist/services/plan-manager.js +502 -0
- package/dist/services/session-manager.js +113 -0
- package/dist/services/task-analyzer.js +136 -0
- package/dist/services/tui/index.js +57 -0
- package/dist/services/tui/store.js +123 -0
- package/dist/types/ai.js +172 -0
- package/dist/types/plan.js +2 -0
- package/dist/ui/Terminal.js +56 -0
- package/dist/ui/components/InputArea.js +176 -0
- package/dist/ui/components/LogArea.js +19 -0
- package/dist/ui/components/PlanPanel.js +69 -0
- package/dist/ui/components/SelectArea.js +13 -0
- package/package.json +45 -0
|
Binary file
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.sessionCommand = sessionCommand;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const session_manager_1 = require("../services/session-manager");
|
|
9
|
+
const ai_create_1 = require("./create/ai-create");
|
|
10
|
+
async function sessionCommand(action, id) {
|
|
11
|
+
const sessionManager = session_manager_1.SessionManager.getInstance();
|
|
12
|
+
switch (action) {
|
|
13
|
+
case 'list':
|
|
14
|
+
const sessions = sessionManager.listSessions();
|
|
15
|
+
if (sessions.length === 0) {
|
|
16
|
+
console.log('没有找到历史会话');
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
console.log(chalk_1.default.blue('📜 AI 生成会话历史:'));
|
|
20
|
+
sessions.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime())
|
|
21
|
+
.forEach(s => {
|
|
22
|
+
const date = new Date(s.updatedAt).toLocaleString();
|
|
23
|
+
const statusColor = s.status === 'completed' ? chalk_1.default.green : (s.status === 'failed' ? chalk_1.default.red : chalk_1.default.yellow);
|
|
24
|
+
console.log(`${s.id.slice(0, 8)} | ${date} | ${statusColor(s.status)} | ${s.pluginName || '未命名'} | ${s.description.slice(0, 30)}...`);
|
|
25
|
+
});
|
|
26
|
+
break;
|
|
27
|
+
case 'clean':
|
|
28
|
+
// Logic to clean old sessions? For now maybe manually delete.
|
|
29
|
+
// Or delete specific id?
|
|
30
|
+
// "clean" usually implies removing finished/old ones.
|
|
31
|
+
console.log('清理功能暂未实现');
|
|
32
|
+
break;
|
|
33
|
+
case 'resume':
|
|
34
|
+
if (id) {
|
|
35
|
+
await (0, ai_create_1.aiCreate)('resuming', { resume: id });
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
await (0, ai_create_1.aiCreate)('resuming', { resume: true });
|
|
39
|
+
}
|
|
40
|
+
break;
|
|
41
|
+
default:
|
|
42
|
+
console.log(chalk_1.default.red(`未知操作: ${action}`));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.build = build;
|
|
40
|
+
const fs = __importStar(require("fs-extra"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const esbuild = __importStar(require("esbuild"));
|
|
43
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
44
|
+
const child_process_1 = require("child_process");
|
|
45
|
+
async function build() {
|
|
46
|
+
const cwd = process.cwd();
|
|
47
|
+
const manifestPath = path.join(cwd, 'manifest.json');
|
|
48
|
+
if (!fs.existsSync(manifestPath)) {
|
|
49
|
+
console.log(chalk_1.default.red('错误: 未找到 manifest.json'));
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
const manifest = fs.readJsonSync(manifestPath);
|
|
53
|
+
const hasUI = !!manifest.ui;
|
|
54
|
+
console.log(chalk_1.default.blue('构建插件...'));
|
|
55
|
+
console.log();
|
|
56
|
+
// 1. 构建后端
|
|
57
|
+
await buildBackend(cwd);
|
|
58
|
+
// 2. 构建 UI(如果有)
|
|
59
|
+
if (hasUI) {
|
|
60
|
+
await buildUI(cwd);
|
|
61
|
+
}
|
|
62
|
+
console.log();
|
|
63
|
+
console.log(chalk_1.default.green('✓ 构建完成'));
|
|
64
|
+
}
|
|
65
|
+
async function buildBackend(cwd) {
|
|
66
|
+
const entryPoint = path.join(cwd, 'src/main.ts');
|
|
67
|
+
if (!fs.existsSync(entryPoint)) {
|
|
68
|
+
console.log(chalk_1.default.yellow('跳过后端构建: 未找到 src/main.ts'));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
fs.ensureDirSync(path.join(cwd, 'dist'));
|
|
72
|
+
try {
|
|
73
|
+
await esbuild.build({
|
|
74
|
+
entryPoints: [entryPoint],
|
|
75
|
+
bundle: true,
|
|
76
|
+
platform: 'node',
|
|
77
|
+
outfile: path.join(cwd, 'dist/main.js'),
|
|
78
|
+
minify: true
|
|
79
|
+
});
|
|
80
|
+
console.log(chalk_1.default.green(' ✓ 后端构建: dist/main.js'));
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
console.log(chalk_1.default.red('后端构建失败:'), err);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async function buildUI(cwd) {
|
|
88
|
+
const viteConfig = path.join(cwd, 'vite.config.ts');
|
|
89
|
+
if (!fs.existsSync(viteConfig)) {
|
|
90
|
+
console.log(chalk_1.default.yellow('跳过 UI 构建: 未找到 vite.config.ts'));
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
console.log(chalk_1.default.blue(' 构建 UI...'));
|
|
94
|
+
return new Promise((resolve, reject) => {
|
|
95
|
+
const vite = (0, child_process_1.spawn)('npx', ['vite', 'build'], {
|
|
96
|
+
cwd,
|
|
97
|
+
stdio: 'inherit',
|
|
98
|
+
shell: true
|
|
99
|
+
});
|
|
100
|
+
vite.on('close', (code) => {
|
|
101
|
+
if (code === 0) {
|
|
102
|
+
console.log(chalk_1.default.green(' ✓ UI 构建: ui/'));
|
|
103
|
+
resolve();
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
reject(new Error(`Vite 构建失败,退出码: ${code}`));
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
vite.on('error', reject);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createAIConfigCommand = createAIConfigCommand;
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const config_manager_1 = require("../services/config-manager");
|
|
11
|
+
const ai_1 = require("../types/ai");
|
|
12
|
+
function createAIConfigCommand() {
|
|
13
|
+
const command = new commander_1.Command('ai')
|
|
14
|
+
.description('管理 AI 供应商配置');
|
|
15
|
+
// 添加供应商配置
|
|
16
|
+
command
|
|
17
|
+
.command('add <name>')
|
|
18
|
+
.description('添加新的 AI 供应商配置')
|
|
19
|
+
.option('-p, --provider <provider>', '供应商类型 (openai/claude/deepseek/gemini/glm/custom)')
|
|
20
|
+
.option('-k, --api-key <key>', 'API Key')
|
|
21
|
+
.option('-m, --model <model>', '模型名称')
|
|
22
|
+
.option('-e, --endpoint <url>', 'API 端点 (可选)')
|
|
23
|
+
.action(async (name, options) => {
|
|
24
|
+
try {
|
|
25
|
+
const configManager = config_manager_1.ConfigManager.getInstance();
|
|
26
|
+
let aiConfig = configManager.get('ai') || { providers: {} };
|
|
27
|
+
// 如果配置已存在,询问是否覆盖
|
|
28
|
+
if (aiConfig.providers[name]) {
|
|
29
|
+
const { confirm } = await inquirer_1.default.prompt([{
|
|
30
|
+
type: 'confirm',
|
|
31
|
+
name: 'confirm',
|
|
32
|
+
message: `配置 "${name}" 已存在,是否覆盖?`,
|
|
33
|
+
default: false
|
|
34
|
+
}]);
|
|
35
|
+
if (!confirm) {
|
|
36
|
+
console.log(chalk_1.default.yellow('已取消'));
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// 交互式收集配置
|
|
41
|
+
let provider = options.provider;
|
|
42
|
+
let apiKey = options.apiKey;
|
|
43
|
+
let model = options.model;
|
|
44
|
+
let endpoint = options.endpoint;
|
|
45
|
+
if (!provider) {
|
|
46
|
+
const { selectedProvider } = await inquirer_1.default.prompt([{
|
|
47
|
+
type: 'list',
|
|
48
|
+
name: 'selectedProvider',
|
|
49
|
+
message: '选择 AI 供应商:',
|
|
50
|
+
choices: [
|
|
51
|
+
{ name: 'OpenAI', value: 'openai' },
|
|
52
|
+
{ name: 'Claude (Anthropic)', value: 'claude' },
|
|
53
|
+
{ name: 'DeepSeek', value: 'deepseek' },
|
|
54
|
+
{ name: 'Gemini (Google)', value: 'gemini' },
|
|
55
|
+
{ name: 'GLM (智谱AI)', value: 'glm' },
|
|
56
|
+
{ name: 'Custom (自定义)', value: 'custom' }
|
|
57
|
+
]
|
|
58
|
+
}]);
|
|
59
|
+
provider = selectedProvider;
|
|
60
|
+
}
|
|
61
|
+
if (!apiKey) {
|
|
62
|
+
const { inputKey } = await inquirer_1.default.prompt([{
|
|
63
|
+
type: 'password',
|
|
64
|
+
name: 'inputKey',
|
|
65
|
+
message: '输入 API Key:',
|
|
66
|
+
validate: (input) => input.length > 0 || 'API Key 不能为空'
|
|
67
|
+
}]);
|
|
68
|
+
apiKey = inputKey;
|
|
69
|
+
}
|
|
70
|
+
// 选择模型
|
|
71
|
+
if (!model && ai_1.PROVIDER_MODELS[provider].length > 0) {
|
|
72
|
+
const { selectedModel } = await inquirer_1.default.prompt([{
|
|
73
|
+
type: 'list',
|
|
74
|
+
name: 'selectedModel',
|
|
75
|
+
message: '选择模型:',
|
|
76
|
+
choices: ai_1.PROVIDER_MODELS[provider],
|
|
77
|
+
default: ai_1.PROVIDER_MODELS[provider][0]
|
|
78
|
+
}]);
|
|
79
|
+
model = selectedModel;
|
|
80
|
+
}
|
|
81
|
+
// 自定义端点
|
|
82
|
+
if (!endpoint && provider === 'custom') {
|
|
83
|
+
const { inputEndpoint } = await inquirer_1.default.prompt([{
|
|
84
|
+
type: 'input',
|
|
85
|
+
name: 'inputEndpoint',
|
|
86
|
+
message: '输入 API 端点:',
|
|
87
|
+
validate: (input) => input.length > 0 || 'API 端点不能为空'
|
|
88
|
+
}]);
|
|
89
|
+
endpoint = inputEndpoint;
|
|
90
|
+
}
|
|
91
|
+
else if (!endpoint) {
|
|
92
|
+
endpoint = ai_1.PROVIDER_ENDPOINTS[provider];
|
|
93
|
+
}
|
|
94
|
+
// 保存配置
|
|
95
|
+
const providerConfig = {
|
|
96
|
+
provider,
|
|
97
|
+
apiKey,
|
|
98
|
+
model,
|
|
99
|
+
apiEndpoint: endpoint
|
|
100
|
+
};
|
|
101
|
+
aiConfig.providers[name] = providerConfig;
|
|
102
|
+
// 如果是第一个配置,设为默认
|
|
103
|
+
if (!aiConfig.default) {
|
|
104
|
+
aiConfig.default = name;
|
|
105
|
+
}
|
|
106
|
+
configManager.set('ai', aiConfig);
|
|
107
|
+
console.log(chalk_1.default.green(`✓ 已添加配置 "${name}"`));
|
|
108
|
+
if (aiConfig.default === name) {
|
|
109
|
+
console.log(chalk_1.default.blue(` 已设为默认配置`));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
console.error(chalk_1.default.red('添加配置失败:'), error.message);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
// 列出所有配置
|
|
117
|
+
command
|
|
118
|
+
.command('list')
|
|
119
|
+
.alias('ls')
|
|
120
|
+
.description('列出所有 AI 供应商配置')
|
|
121
|
+
.action(() => {
|
|
122
|
+
try {
|
|
123
|
+
const configManager = config_manager_1.ConfigManager.getInstance();
|
|
124
|
+
const aiConfig = configManager.get('ai');
|
|
125
|
+
if (!aiConfig || !aiConfig.providers || Object.keys(aiConfig.providers).length === 0) {
|
|
126
|
+
console.log(chalk_1.default.yellow('未配置任何 AI 供应商'));
|
|
127
|
+
console.log(chalk_1.default.gray('使用 `mulby ai add <name>` 添加配置'));
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
console.log(chalk_1.default.bold('\nAI 供应商配置:\n'));
|
|
131
|
+
for (const [name, config] of Object.entries(aiConfig.providers)) {
|
|
132
|
+
const isDefault = aiConfig.default === name;
|
|
133
|
+
const prefix = isDefault ? chalk_1.default.green('● ') : ' ';
|
|
134
|
+
const suffix = isDefault ? chalk_1.default.gray(' (默认)') : '';
|
|
135
|
+
console.log(`${prefix}${chalk_1.default.bold(name)}${suffix}`);
|
|
136
|
+
console.log(` ${chalk_1.default.gray('供应商:')} ${config.provider}`);
|
|
137
|
+
console.log(` ${chalk_1.default.gray('模型:')} ${config.model || '未指定'}`);
|
|
138
|
+
console.log(` ${chalk_1.default.gray('API Key:')} ${maskApiKey(config.apiKey)}`);
|
|
139
|
+
if (config.apiEndpoint) {
|
|
140
|
+
console.log(` ${chalk_1.default.gray('端点:')} ${config.apiEndpoint}`);
|
|
141
|
+
}
|
|
142
|
+
console.log();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
console.error(chalk_1.default.red('列出配置失败:'), error.message);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
// 删除配置
|
|
150
|
+
command
|
|
151
|
+
.command('remove <name>')
|
|
152
|
+
.alias('rm')
|
|
153
|
+
.description('删除 AI 供应商配置')
|
|
154
|
+
.action(async (name) => {
|
|
155
|
+
try {
|
|
156
|
+
const configManager = config_manager_1.ConfigManager.getInstance();
|
|
157
|
+
const aiConfig = configManager.get('ai');
|
|
158
|
+
if (!aiConfig || !aiConfig.providers || !aiConfig.providers[name]) {
|
|
159
|
+
console.log(chalk_1.default.yellow(`配置 "${name}" 不存在`));
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const { confirm } = await inquirer_1.default.prompt([{
|
|
163
|
+
type: 'confirm',
|
|
164
|
+
name: 'confirm',
|
|
165
|
+
message: `确定要删除配置 "${name}"?`,
|
|
166
|
+
default: false
|
|
167
|
+
}]);
|
|
168
|
+
if (!confirm) {
|
|
169
|
+
console.log(chalk_1.default.yellow('已取消'));
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
delete aiConfig.providers[name];
|
|
173
|
+
// 如果删除的是默认配置,重新设置默认
|
|
174
|
+
if (aiConfig.default === name) {
|
|
175
|
+
const remainingProviders = Object.keys(aiConfig.providers);
|
|
176
|
+
aiConfig.default = remainingProviders.length > 0 ? remainingProviders[0] : undefined;
|
|
177
|
+
}
|
|
178
|
+
configManager.set('ai', aiConfig);
|
|
179
|
+
console.log(chalk_1.default.green(`✓ 已删除配置 "${name}"`));
|
|
180
|
+
if (aiConfig.default) {
|
|
181
|
+
console.log(chalk_1.default.blue(` 默认配置已切换为 "${aiConfig.default}"`));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
console.error(chalk_1.default.red('删除配置失败:'), error.message);
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
// 设置默认配置
|
|
189
|
+
command
|
|
190
|
+
.command('use <name>')
|
|
191
|
+
.description('设置默认使用的 AI 供应商配置')
|
|
192
|
+
.action((name) => {
|
|
193
|
+
try {
|
|
194
|
+
const configManager = config_manager_1.ConfigManager.getInstance();
|
|
195
|
+
const aiConfig = configManager.get('ai');
|
|
196
|
+
if (!aiConfig || !aiConfig.providers || !aiConfig.providers[name]) {
|
|
197
|
+
console.log(chalk_1.default.yellow(`配置 "${name}" 不存在`));
|
|
198
|
+
console.log(chalk_1.default.gray('使用 `mulby ai list` 查看所有配置'));
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
aiConfig.default = name;
|
|
202
|
+
configManager.set('ai', aiConfig);
|
|
203
|
+
console.log(chalk_1.default.green(`✓ 已将 "${name}" 设为默认配置`));
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
console.error(chalk_1.default.red('设置默认配置失败:'), error.message);
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
// 查看配置详情
|
|
210
|
+
command
|
|
211
|
+
.command('show <name>')
|
|
212
|
+
.description('查看指定 AI 供应商配置的详细信息')
|
|
213
|
+
.action((name) => {
|
|
214
|
+
try {
|
|
215
|
+
const configManager = config_manager_1.ConfigManager.getInstance();
|
|
216
|
+
const aiConfig = configManager.get('ai');
|
|
217
|
+
if (!aiConfig || !aiConfig.providers || !aiConfig.providers[name]) {
|
|
218
|
+
console.log(chalk_1.default.yellow(`配置 "${name}" 不存在`));
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
const config = aiConfig.providers[name];
|
|
222
|
+
const isDefault = aiConfig.default === name;
|
|
223
|
+
console.log(chalk_1.default.bold(`\n配置: ${name}`) + (isDefault ? chalk_1.default.gray(' (默认)') : ''));
|
|
224
|
+
console.log(chalk_1.default.gray('─'.repeat(50)));
|
|
225
|
+
console.log(`${chalk_1.default.gray('供应商:')} ${config.provider}`);
|
|
226
|
+
console.log(`${chalk_1.default.gray('模型:')} ${config.model || '未指定'}`);
|
|
227
|
+
console.log(`${chalk_1.default.gray('API Key:')} ${maskApiKey(config.apiKey)}`);
|
|
228
|
+
if (config.apiEndpoint) {
|
|
229
|
+
console.log(`${chalk_1.default.gray('端点:')} ${config.apiEndpoint}`);
|
|
230
|
+
}
|
|
231
|
+
console.log(`${chalk_1.default.gray('最大重试:')} ${config.maxRetries || 3}`);
|
|
232
|
+
console.log(`${chalk_1.default.gray('超时时间:')} ${config.timeout || 60}s`);
|
|
233
|
+
console.log(`${chalk_1.default.gray('流式输出:')} ${config.streaming !== false ? '是' : '否'}`);
|
|
234
|
+
if (config.maxTokens) {
|
|
235
|
+
console.log(`${chalk_1.default.gray('最大 Token:')} ${config.maxTokens}`);
|
|
236
|
+
}
|
|
237
|
+
console.log();
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
console.error(chalk_1.default.red('查看配置失败:'), error.message);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
// 更新配置
|
|
244
|
+
command
|
|
245
|
+
.command('update <name>')
|
|
246
|
+
.description('更新 AI 供应商配置')
|
|
247
|
+
.option('-k, --api-key <key>', '更新 API Key')
|
|
248
|
+
.option('-m, --model <model>', '更新模型名称')
|
|
249
|
+
.option('-e, --endpoint <url>', '更新 API 端点')
|
|
250
|
+
.action(async (name, options) => {
|
|
251
|
+
try {
|
|
252
|
+
const configManager = config_manager_1.ConfigManager.getInstance();
|
|
253
|
+
const aiConfig = configManager.get('ai');
|
|
254
|
+
if (!aiConfig || !aiConfig.providers || !aiConfig.providers[name]) {
|
|
255
|
+
console.log(chalk_1.default.yellow(`配置 "${name}" 不存在`));
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
const config = aiConfig.providers[name];
|
|
259
|
+
let updated = false;
|
|
260
|
+
if (options.apiKey) {
|
|
261
|
+
config.apiKey = options.apiKey;
|
|
262
|
+
updated = true;
|
|
263
|
+
}
|
|
264
|
+
if (options.model) {
|
|
265
|
+
config.model = options.model;
|
|
266
|
+
updated = true;
|
|
267
|
+
}
|
|
268
|
+
if (options.endpoint) {
|
|
269
|
+
config.apiEndpoint = options.endpoint;
|
|
270
|
+
updated = true;
|
|
271
|
+
}
|
|
272
|
+
if (!updated) {
|
|
273
|
+
console.log(chalk_1.default.yellow('未指定要更新的字段'));
|
|
274
|
+
console.log(chalk_1.default.gray('使用 --api-key, --model 或 --endpoint 选项'));
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
configManager.set('ai', aiConfig);
|
|
278
|
+
console.log(chalk_1.default.green(`✓ 已更新配置 "${name}"`));
|
|
279
|
+
}
|
|
280
|
+
catch (error) {
|
|
281
|
+
console.error(chalk_1.default.red('更新配置失败:'), error.message);
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
return command;
|
|
285
|
+
}
|
|
286
|
+
function maskApiKey(key) {
|
|
287
|
+
if (key.length <= 8) {
|
|
288
|
+
return '***';
|
|
289
|
+
}
|
|
290
|
+
return key.substring(0, 4) + '***' + key.substring(key.length - 4);
|
|
291
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.configCommand = configCommand;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const config_manager_1 = require("../services/config-manager");
|
|
9
|
+
function configCommand(action, key, value) {
|
|
10
|
+
const configManager = config_manager_1.ConfigManager.getInstance();
|
|
11
|
+
try {
|
|
12
|
+
switch (action) {
|
|
13
|
+
case 'get':
|
|
14
|
+
if (!key) {
|
|
15
|
+
console.log(chalk_1.default.red('错误: 请指定要查询的配置键,例如: mulby config get ai.provider'));
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const val = configManager.get(key);
|
|
19
|
+
if (val === undefined) {
|
|
20
|
+
console.log(chalk_1.default.gray('(未设置)'));
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
console.log(val);
|
|
24
|
+
}
|
|
25
|
+
break;
|
|
26
|
+
case 'set':
|
|
27
|
+
if (!key || !value) {
|
|
28
|
+
console.log(chalk_1.default.red('错误: 请指定键和值,例如: mulby config set ai.apiKey sk-xxx'));
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
configManager.set(key, value);
|
|
32
|
+
console.log(chalk_1.default.green(`✓ 已设置 ${key} = ${value}`));
|
|
33
|
+
break;
|
|
34
|
+
case 'delete':
|
|
35
|
+
if (!key) {
|
|
36
|
+
console.log(chalk_1.default.red('错误: 请指定要删除的配置键'));
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
configManager.delete(key);
|
|
40
|
+
console.log(chalk_1.default.green(`✓ 已删除 ${key}`));
|
|
41
|
+
break;
|
|
42
|
+
case 'list':
|
|
43
|
+
const allConfig = configManager.getAll();
|
|
44
|
+
console.log(JSON.stringify(allConfig, null, 2));
|
|
45
|
+
break;
|
|
46
|
+
default:
|
|
47
|
+
console.log(chalk_1.default.red(`错误: 未知操作 '${action}'。支持: get, set, delete, list`));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
console.error(chalk_1.default.red(`配置操作失败: ${error.message}`));
|
|
52
|
+
}
|
|
53
|
+
}
|