@seandong/seno 0.1.7 → 0.2.0
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/dist/agent/conversation.d.ts +19 -3
- package/dist/agent/conversation.js +40 -9
- package/dist/agent/conversation.js.map +1 -1
- package/dist/agent/loop.d.ts +3 -0
- package/dist/agent/loop.js +27 -15
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/session.js +1 -7
- package/dist/agent/session.js.map +1 -1
- package/dist/cli/commands.d.ts +2 -0
- package/dist/cli/commands.js +33 -353
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/logger.d.ts +55 -7
- package/dist/cli/logger.js +152 -16
- package/dist/cli/logger.js.map +1 -1
- package/dist/cli/output.d.ts +1 -5
- package/dist/cli/output.js +29 -59
- package/dist/cli/output.js.map +1 -1
- package/dist/cli/prompt.js +7 -5
- package/dist/cli/prompt.js.map +1 -1
- package/dist/cli/readline-wrapper.d.ts +44 -0
- package/dist/cli/readline-wrapper.js +80 -0
- package/dist/cli/readline-wrapper.js.map +1 -0
- package/dist/cli/repl.js +23 -47
- package/dist/cli/repl.js.map +1 -1
- package/dist/commands/init.js +8 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/model.js +8 -2
- package/dist/commands/model.js.map +1 -1
- package/dist/commands/plugin-init.d.ts +24 -0
- package/dist/commands/plugin-init.js +313 -0
- package/dist/commands/plugin-init.js.map +1 -0
- package/dist/commands/server.d.ts +39 -0
- package/dist/commands/server.js +102 -0
- package/dist/commands/server.js.map +1 -0
- package/dist/config/manager.d.ts +14 -0
- package/dist/config/manager.js +151 -13
- package/dist/config/manager.js.map +1 -1
- package/dist/config/types.d.ts +15 -0
- package/dist/errors.d.ts +20 -3
- package/dist/errors.js +20 -5
- package/dist/errors.js.map +1 -1
- package/dist/i18n/strings.d.ts +44 -0
- package/dist/i18n/strings.js +46 -0
- package/dist/i18n/strings.js.map +1 -0
- package/dist/index.js +52 -18
- package/dist/index.js.map +1 -1
- package/dist/llm/anthropic.d.ts +0 -9
- package/dist/llm/anthropic.js +9 -62
- package/dist/llm/anthropic.js.map +1 -1
- package/dist/llm/error-handler.d.ts +28 -0
- package/dist/llm/error-handler.js +93 -0
- package/dist/llm/error-handler.js.map +1 -0
- package/dist/llm/openai-codex.js +15 -61
- package/dist/llm/openai-codex.js.map +1 -1
- package/dist/llm/openai.js +10 -57
- package/dist/llm/openai.js.map +1 -1
- package/dist/mcp/bridge.js.map +1 -1
- package/dist/mcp/manager.d.ts +4 -2
- package/dist/mcp/manager.js +36 -12
- package/dist/mcp/manager.js.map +1 -1
- package/dist/prompts/system.js +2 -1
- package/dist/prompts/system.js.map +1 -1
- package/dist/skills/registry.js.map +1 -1
- package/dist/skills/sync.js +3 -1
- package/dist/skills/sync.js.map +1 -1
- package/dist/tools/plugin-init.d.ts +6 -0
- package/dist/tools/plugin-init.js +46 -0
- package/dist/tools/plugin-init.js.map +1 -0
- package/dist/tools/registry.js +11 -2
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/server.d.ts +13 -0
- package/dist/tools/server.js +151 -0
- package/dist/tools/server.js.map +1 -0
- package/dist/tools/shell.js +1 -3
- package/dist/tools/shell.js.map +1 -1
- package/dist/tools/skills-sync.d.ts +6 -0
- package/dist/tools/skills-sync.js +39 -0
- package/dist/tools/skills-sync.js.map +1 -0
- package/dist/tools/ssh.js.map +1 -1
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/text.d.ts +45 -0
- package/dist/utils/text.js +95 -0
- package/dist/utils/text.js.map +1 -0
- package/package.json +23 -5
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import * as crypto from 'crypto';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import { execSync } from 'child_process';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import ora from 'ora';
|
|
7
|
+
// ─── Helpers ─────────────────────────────────────────────────
|
|
8
|
+
/** 安全执行 shell 命令,返回 stdout 或 null(失败时) */
|
|
9
|
+
function runCommand(cmd, timeout = 15000) {
|
|
10
|
+
try {
|
|
11
|
+
return execSync(cmd, {
|
|
12
|
+
encoding: 'utf-8',
|
|
13
|
+
timeout,
|
|
14
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
15
|
+
}).trim();
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/** 获取 nvm 目录路径 */
|
|
22
|
+
function getNvmDir() {
|
|
23
|
+
return process.env.NVM_DIR || path.join(process.env.HOME || '~', '.nvm');
|
|
24
|
+
}
|
|
25
|
+
/** 检查 nvm 是否已安装 */
|
|
26
|
+
function isNvmInstalled() {
|
|
27
|
+
const nvmScript = path.join(getNvmDir(), 'nvm.sh');
|
|
28
|
+
try {
|
|
29
|
+
fs.accessSync(nvmScript);
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** 通过 nvm 执行命令(先 source nvm.sh) */
|
|
37
|
+
function runWithNvm(cmd) {
|
|
38
|
+
const nvmDir = getNvmDir();
|
|
39
|
+
const script = `source "${nvmDir}/nvm.sh"\n${cmd}`;
|
|
40
|
+
try {
|
|
41
|
+
return execSync('bash', {
|
|
42
|
+
input: script,
|
|
43
|
+
encoding: 'utf-8',
|
|
44
|
+
timeout: 300000,
|
|
45
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
46
|
+
}).trim();
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** 检查 nvm 中是否已安装 Node.js 18,返回版本号或 null */
|
|
53
|
+
function getNode18Version() {
|
|
54
|
+
const result = runWithNvm('nvm ls 18');
|
|
55
|
+
if (!result)
|
|
56
|
+
return null;
|
|
57
|
+
const match = result.match(/v(18\.\d+\.\d+)/);
|
|
58
|
+
return match ? match[1] : null;
|
|
59
|
+
}
|
|
60
|
+
/** 确保 nvm 已安装 */
|
|
61
|
+
async function ensureNvm() {
|
|
62
|
+
if (isNvmInstalled())
|
|
63
|
+
return true;
|
|
64
|
+
const spinner = ora({ text: '安装 nvm...', indent: 2, discardStdin: false });
|
|
65
|
+
spinner.start();
|
|
66
|
+
try {
|
|
67
|
+
execSync('curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash', {
|
|
68
|
+
encoding: 'utf-8',
|
|
69
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
70
|
+
timeout: 120000,
|
|
71
|
+
});
|
|
72
|
+
if (!isNvmInstalled()) {
|
|
73
|
+
spinner.fail('nvm 安装失败');
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
spinner.succeed('nvm 安装成功');
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
spinner.fail('nvm 安装失败');
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/** 确保 nvm 中存在 Node.js 18 */
|
|
85
|
+
async function ensureNode18() {
|
|
86
|
+
if (!(await ensureNvm()))
|
|
87
|
+
return false;
|
|
88
|
+
const existing = getNode18Version();
|
|
89
|
+
if (existing) {
|
|
90
|
+
console.log(chalk.green(' ✓ ') + `${'Node.js 18'.padEnd(12)}${chalk.gray(`v${existing}`)}`);
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
const spinner = ora({ text: '通过 nvm 安装 Node.js 18...', indent: 2, discardStdin: false });
|
|
94
|
+
spinner.start();
|
|
95
|
+
runWithNvm('nvm install 18');
|
|
96
|
+
const installed = getNode18Version();
|
|
97
|
+
if (installed) {
|
|
98
|
+
spinner.succeed(`Node.js 18 安装成功 ${chalk.gray(`v${installed}`)}`);
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
spinner.fail('Node.js 18 安装失败');
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
/** 自动安装 ONES CLI */
|
|
105
|
+
async function installOnesCli() {
|
|
106
|
+
const spinner = ora({ text: '安装 ONES CLI...', indent: 2, discardStdin: false });
|
|
107
|
+
spinner.start();
|
|
108
|
+
try {
|
|
109
|
+
execSync('npm install -g @ones/cli --registry=https://npm.partner.ones.cn/registry/', {
|
|
110
|
+
encoding: 'utf-8',
|
|
111
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
112
|
+
timeout: 120000,
|
|
113
|
+
});
|
|
114
|
+
const version = runCommand('ones --version');
|
|
115
|
+
if (version) {
|
|
116
|
+
spinner.succeed(`ONES CLI 安装成功 ${chalk.gray(version)}`);
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
/* fall through */
|
|
122
|
+
}
|
|
123
|
+
spinner.fail('ONES CLI 安装失败');
|
|
124
|
+
console.log(chalk.gray(' 手动安装: npm install -g @ones/cli --registry=https://npm.partner.ones.cn/registry/'));
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
/** 自动安装 npx */
|
|
128
|
+
async function installNpx() {
|
|
129
|
+
const spinner = ora({ text: '安装 npx...', indent: 2, discardStdin: false });
|
|
130
|
+
spinner.start();
|
|
131
|
+
try {
|
|
132
|
+
execSync('npm install -g npx', {
|
|
133
|
+
encoding: 'utf-8',
|
|
134
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
135
|
+
timeout: 120000,
|
|
136
|
+
});
|
|
137
|
+
const version = runCommand('npx --version');
|
|
138
|
+
if (version) {
|
|
139
|
+
spinner.succeed(`npx 安装成功 ${chalk.gray(version)}`);
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
/* fall through */
|
|
145
|
+
}
|
|
146
|
+
spinner.fail('npx 安装失败');
|
|
147
|
+
console.log(chalk.gray(' 手动安装: npm install -g npx'));
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
// ─── Core Logic ──────────────────────────────────────────────
|
|
151
|
+
/**
|
|
152
|
+
* 环境预检:检查所有必需依赖
|
|
153
|
+
* 返回是否全部通过
|
|
154
|
+
*/
|
|
155
|
+
export async function checkEnvironment() {
|
|
156
|
+
const details = [];
|
|
157
|
+
console.log(chalk.bold(' 环境预检:'));
|
|
158
|
+
console.log();
|
|
159
|
+
const node18Ok = await ensureNode18();
|
|
160
|
+
if (!node18Ok)
|
|
161
|
+
details.push('Node.js 18 未安装');
|
|
162
|
+
const checks = [
|
|
163
|
+
{ label: 'npm', cmd: 'npm --version' },
|
|
164
|
+
{
|
|
165
|
+
label: 'ONES CLI',
|
|
166
|
+
cmd: 'ones --version',
|
|
167
|
+
autoFix: installOnesCli,
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
label: 'npx',
|
|
171
|
+
cmd: 'npx --version',
|
|
172
|
+
autoFix: installNpx,
|
|
173
|
+
},
|
|
174
|
+
];
|
|
175
|
+
let allRequiredPassed = node18Ok;
|
|
176
|
+
for (const check of checks) {
|
|
177
|
+
let version = runCommand(check.cmd);
|
|
178
|
+
if (version) {
|
|
179
|
+
console.log(chalk.green(' ✓ ') + `${check.label.padEnd(12)}${chalk.gray(version)}`);
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
if (check.autoFix) {
|
|
183
|
+
const fixed = await check.autoFix();
|
|
184
|
+
if (fixed) {
|
|
185
|
+
version = runCommand(check.cmd);
|
|
186
|
+
if (version)
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
allRequiredPassed = false;
|
|
191
|
+
details.push(`${check.label} 未安装`);
|
|
192
|
+
console.log(chalk.red(' ✗ ') + `${check.label} 未安装`);
|
|
193
|
+
}
|
|
194
|
+
console.log();
|
|
195
|
+
return { passed: allRequiredPassed, details };
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* 插件初始化核心逻辑(无交互依赖)
|
|
199
|
+
* 参数由调用方提供(LLM 工具调用或斜杠命令收集)
|
|
200
|
+
*/
|
|
201
|
+
export async function pluginInitCore(options) {
|
|
202
|
+
const { pluginName, pluginDir } = options;
|
|
203
|
+
// ── 参数校验 ──
|
|
204
|
+
if (!pluginName) {
|
|
205
|
+
return { success: false, projectPath: '', message: '插件名称不能为空' };
|
|
206
|
+
}
|
|
207
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(pluginName)) {
|
|
208
|
+
return {
|
|
209
|
+
success: false,
|
|
210
|
+
projectPath: '',
|
|
211
|
+
message: '插件名称只能包含字母、数字、连字符(-)和下划线(_)',
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
// ── 环境预检 ──
|
|
215
|
+
console.log();
|
|
216
|
+
console.log(chalk.bold(' ONES 插件项目初始化'));
|
|
217
|
+
console.log();
|
|
218
|
+
const envCheck = await checkEnvironment();
|
|
219
|
+
if (!envCheck.passed) {
|
|
220
|
+
return {
|
|
221
|
+
success: false,
|
|
222
|
+
projectPath: '',
|
|
223
|
+
message: `环境预检未通过: ${envCheck.details.join('、')}。请先安装缺失的依赖。`,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
console.log(chalk.green(' 环境预检通过'));
|
|
227
|
+
console.log();
|
|
228
|
+
// ── 创建项目 ──
|
|
229
|
+
const projectPath = path.resolve(pluginDir || '.');
|
|
230
|
+
if (pluginDir) {
|
|
231
|
+
try {
|
|
232
|
+
fs.mkdirSync(path.resolve(pluginDir), { recursive: true });
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
return {
|
|
236
|
+
success: false,
|
|
237
|
+
projectPath,
|
|
238
|
+
message: `目录创建失败: ${pluginDir}`,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
console.log(chalk.gray(` 正在创建插件项目: ${pluginName}`) +
|
|
243
|
+
(pluginDir ? chalk.gray(` → ${pluginDir}/`) : '') +
|
|
244
|
+
chalk.gray(' ...'));
|
|
245
|
+
console.log();
|
|
246
|
+
let createCmd = `ones create -d ${pluginName}`;
|
|
247
|
+
if (pluginDir) {
|
|
248
|
+
createCmd += ` -s ${pluginDir}`;
|
|
249
|
+
}
|
|
250
|
+
const appId = crypto.randomBytes(4).toString('hex');
|
|
251
|
+
try {
|
|
252
|
+
execSync(createCmd, {
|
|
253
|
+
input: appId + '\n',
|
|
254
|
+
stdio: ['pipe', 'inherit', 'inherit'],
|
|
255
|
+
timeout: 300000,
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
const err = error;
|
|
260
|
+
if (err.status) {
|
|
261
|
+
return {
|
|
262
|
+
success: false,
|
|
263
|
+
projectPath,
|
|
264
|
+
message: `创建失败 (exit code: ${err.status})`,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
return {
|
|
268
|
+
success: false,
|
|
269
|
+
projectPath,
|
|
270
|
+
message: `创建失败: ${err.message ?? error}`,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
if (!fs.existsSync(projectPath)) {
|
|
274
|
+
return {
|
|
275
|
+
success: false,
|
|
276
|
+
projectPath,
|
|
277
|
+
message: `创建失败: 项目目录不存在 ${projectPath}`,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
console.log(chalk.green(` ✓ 插件项目 "${pluginName}" 创建成功`));
|
|
281
|
+
// ── 写入 .nvmrc ──
|
|
282
|
+
try {
|
|
283
|
+
fs.writeFileSync(path.join(projectPath, '.nvmrc'), '18\n', 'utf-8');
|
|
284
|
+
console.log(chalk.green(' ✓ ') + '.nvmrc 已写入');
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
console.log(chalk.yellow(' ⚠ .nvmrc 写入失败'));
|
|
288
|
+
}
|
|
289
|
+
console.log();
|
|
290
|
+
const nextSteps = [
|
|
291
|
+
`cd ${projectPath}`,
|
|
292
|
+
'npx op login',
|
|
293
|
+
'npx op pickteam local',
|
|
294
|
+
'npx op invoke run',
|
|
295
|
+
];
|
|
296
|
+
// ── 后续指引 ──
|
|
297
|
+
console.log(chalk.bold(' 本地调试步骤:'));
|
|
298
|
+
console.log();
|
|
299
|
+
nextSteps.forEach((step, i) => {
|
|
300
|
+
console.log(chalk.cyan(` ${i + 1}. `) + step);
|
|
301
|
+
});
|
|
302
|
+
console.log();
|
|
303
|
+
console.log(chalk.bold(' 开发文档: ') +
|
|
304
|
+
chalk.underline('https://developer.ones.cn/zh-CN/docs/guide/getting-started/development'));
|
|
305
|
+
console.log();
|
|
306
|
+
return {
|
|
307
|
+
success: true,
|
|
308
|
+
projectPath,
|
|
309
|
+
message: `插件项目 "${pluginName}" 创建成功`,
|
|
310
|
+
nextSteps,
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
//# sourceMappingURL=plugin-init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-init.js","sourceRoot":"","sources":["../../src/commands/plugin-init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 服务器管理:UI 层拆分
|
|
3
|
+
*
|
|
4
|
+
* 将 serverAdd 的 prompt / validate / persist 三层职责分离,
|
|
5
|
+
* 使校验和持久化逻辑可独立测试。
|
|
6
|
+
*/
|
|
7
|
+
import type { Interface as ReadlineInterface } from 'readline';
|
|
8
|
+
import type { SshServerConfig } from '../config/types.js';
|
|
9
|
+
/**
|
|
10
|
+
* 服务器输入数据(prompt 层的输出、validate 层的输入)
|
|
11
|
+
*/
|
|
12
|
+
export interface ServerInput {
|
|
13
|
+
name: string;
|
|
14
|
+
host: string;
|
|
15
|
+
user: string;
|
|
16
|
+
port: number;
|
|
17
|
+
auth_type: 'password' | 'ssh-key';
|
|
18
|
+
identity_file?: string;
|
|
19
|
+
password?: string;
|
|
20
|
+
description: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* UI 层:收集用户输入
|
|
24
|
+
* 纯交互逻辑,不做业务校验
|
|
25
|
+
*/
|
|
26
|
+
export declare function promptServerDetails(rl: ReadlineInterface): Promise<ServerInput>;
|
|
27
|
+
/**
|
|
28
|
+
* 校验层:纯校验,返回错误列表
|
|
29
|
+
* 空数组表示校验通过
|
|
30
|
+
*/
|
|
31
|
+
export declare function validateServerInput(input: ServerInput, existingNames: string[]): string[];
|
|
32
|
+
/**
|
|
33
|
+
* 持久化层:读取现有配置,追加新服务器,写回
|
|
34
|
+
*/
|
|
35
|
+
export declare function persistServer(server: SshServerConfig): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* 编排层:prompt → validate → persist
|
|
38
|
+
*/
|
|
39
|
+
export declare function serverAdd(rl: ReadlineInterface): Promise<boolean>;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { loadServers, saveServers } from '../config/manager.js';
|
|
3
|
+
import { promptQuestion, promptChoice, CancelError } from '../cli/prompt.js';
|
|
4
|
+
/**
|
|
5
|
+
* UI 层:收集用户输入
|
|
6
|
+
* 纯交互逻辑,不做业务校验
|
|
7
|
+
*/
|
|
8
|
+
export async function promptServerDetails(rl) {
|
|
9
|
+
console.log();
|
|
10
|
+
console.log(chalk.gray(' 添加服务器 [按 ESC 键取消]'));
|
|
11
|
+
console.log();
|
|
12
|
+
const name = await promptQuestion(rl, chalk.cyan(' Server name: '));
|
|
13
|
+
const host = await promptQuestion(rl, chalk.cyan(' Host: '));
|
|
14
|
+
const userInput = await promptQuestion(rl, chalk.cyan(' User [root]: '));
|
|
15
|
+
const user = userInput || 'root';
|
|
16
|
+
const portInput = await promptQuestion(rl, chalk.cyan(' Port [22]: '));
|
|
17
|
+
const port = portInput ? parseInt(portInput, 10) : 22;
|
|
18
|
+
// 认证方式选择
|
|
19
|
+
console.log();
|
|
20
|
+
console.log(chalk.cyan(' Auth method:'));
|
|
21
|
+
const authIdx = await promptChoice(rl, '', ['SSH Key', 'Password'], 0);
|
|
22
|
+
const authType = authIdx === 1 ? 'password' : 'ssh-key';
|
|
23
|
+
let identity_file;
|
|
24
|
+
let password;
|
|
25
|
+
if (authType === 'ssh-key') {
|
|
26
|
+
const identityInput = await promptQuestion(rl, chalk.cyan(' Identity file [~/.ssh/id_rsa]: '));
|
|
27
|
+
identity_file = identityInput || '~/.ssh/id_rsa';
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
password = await promptQuestion(rl, chalk.cyan(' Password: '));
|
|
31
|
+
}
|
|
32
|
+
const description = await promptQuestion(rl, chalk.cyan(' Description: '));
|
|
33
|
+
return { name, host, user, port, auth_type: authType, identity_file, password, description };
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 校验层:纯校验,返回错误列表
|
|
37
|
+
* 空数组表示校验通过
|
|
38
|
+
*/
|
|
39
|
+
export function validateServerInput(input, existingNames) {
|
|
40
|
+
const errors = [];
|
|
41
|
+
if (!input.name)
|
|
42
|
+
errors.push('服务器名称不能为空');
|
|
43
|
+
if (!input.host)
|
|
44
|
+
errors.push('主机地址不能为空');
|
|
45
|
+
if (isNaN(input.port) || input.port < 1 || input.port > 65535) {
|
|
46
|
+
errors.push('端口号无效(需为 1–65535 之间的整数)');
|
|
47
|
+
}
|
|
48
|
+
if (input.auth_type === 'password' && !input.password) {
|
|
49
|
+
errors.push('密码不能为空');
|
|
50
|
+
}
|
|
51
|
+
if (existingNames.includes(input.name)) {
|
|
52
|
+
errors.push(`服务器 "${input.name}" 已存在,请使用其他名称`);
|
|
53
|
+
}
|
|
54
|
+
return errors;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* 持久化层:读取现有配置,追加新服务器,写回
|
|
58
|
+
*/
|
|
59
|
+
export async function persistServer(server) {
|
|
60
|
+
const config = await loadServers();
|
|
61
|
+
config.servers.push(server);
|
|
62
|
+
await saveServers(config);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 编排层:prompt → validate → persist
|
|
66
|
+
*/
|
|
67
|
+
export async function serverAdd(rl) {
|
|
68
|
+
try {
|
|
69
|
+
const input = await promptServerDetails(rl);
|
|
70
|
+
// 获取已有名称用于去重校验
|
|
71
|
+
const existing = await loadServers();
|
|
72
|
+
const existingNames = existing.servers.map((s) => s.name);
|
|
73
|
+
const errors = validateServerInput(input, existingNames);
|
|
74
|
+
if (errors.length > 0) {
|
|
75
|
+
for (const err of errors) {
|
|
76
|
+
console.log(chalk.yellow(`\n ${err}`));
|
|
77
|
+
}
|
|
78
|
+
console.log();
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
await persistServer({
|
|
82
|
+
name: input.name,
|
|
83
|
+
host: input.host,
|
|
84
|
+
user: input.user,
|
|
85
|
+
port: input.port,
|
|
86
|
+
auth_type: input.auth_type,
|
|
87
|
+
identity_file: input.identity_file,
|
|
88
|
+
password: input.password,
|
|
89
|
+
description: input.description,
|
|
90
|
+
});
|
|
91
|
+
console.log(chalk.green(`\n ✓ Server "${input.name}" added successfully\n`));
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
if (error instanceof CancelError) {
|
|
96
|
+
console.log();
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"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"}
|
package/dist/config/manager.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export declare function getLogsDir(): string;
|
|
|
21
21
|
export declare function ensureConfigDir(): Promise<void>;
|
|
22
22
|
/**
|
|
23
23
|
* 解析 "provider/model_name" 格式的模型 ID
|
|
24
|
+
* 对 provider 名称做白名单校验,不合法时抛出错误
|
|
24
25
|
*/
|
|
25
26
|
export declare function parseModelId(modelId: string): {
|
|
26
27
|
provider: LLMProviderName;
|
|
@@ -39,10 +40,23 @@ export declare function getActiveProvider(config: SenoConfig): {
|
|
|
39
40
|
model: string;
|
|
40
41
|
providerConfig: ProviderConfig;
|
|
41
42
|
} | null;
|
|
43
|
+
/**
|
|
44
|
+
* 验证配置对象的结构和必需字段
|
|
45
|
+
* 纯函数,不涉及文件 I/O
|
|
46
|
+
*
|
|
47
|
+
* @param raw 待验证的原始对象
|
|
48
|
+
* @returns 验证结果:valid 标识是否通过,errors 包含所有错误描述
|
|
49
|
+
*/
|
|
50
|
+
export declare function validateConfig(raw: unknown): {
|
|
51
|
+
valid: boolean;
|
|
52
|
+
errors: string[];
|
|
53
|
+
};
|
|
42
54
|
/**
|
|
43
55
|
* 读取配置文件 ~/.seno/config.json
|
|
44
56
|
* 自动检测并迁移旧格式配置
|
|
57
|
+
*
|
|
45
58
|
* @returns 配置对象,文件不存在返回 null
|
|
59
|
+
* @throws ConfigValidationError 配置文件存在但内容无效时抛出
|
|
46
60
|
*/
|
|
47
61
|
export declare function loadConfig(): Promise<SenoConfig | null>;
|
|
48
62
|
/**
|