@yivan-lab/pretty-please 1.1.0 → 1.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/README.md +283 -1
- package/bin/pls.tsx +1022 -104
- package/dist/bin/pls.js +894 -84
- package/dist/package.json +4 -4
- package/dist/src/alias.d.ts +41 -0
- package/dist/src/alias.js +240 -0
- package/dist/src/chat-history.js +10 -1
- package/dist/src/components/Chat.js +2 -1
- package/dist/src/components/CodeColorizer.js +26 -20
- package/dist/src/components/CommandBox.js +2 -1
- package/dist/src/components/ConfirmationPrompt.js +2 -1
- package/dist/src/components/Duration.js +2 -1
- package/dist/src/components/InlineRenderer.js +2 -1
- package/dist/src/components/MarkdownDisplay.js +2 -1
- package/dist/src/components/MultiStepCommandGenerator.d.ts +3 -1
- package/dist/src/components/MultiStepCommandGenerator.js +20 -10
- package/dist/src/components/TableRenderer.js +2 -1
- package/dist/src/config.d.ts +34 -3
- package/dist/src/config.js +71 -31
- package/dist/src/multi-step.d.ts +22 -6
- package/dist/src/multi-step.js +27 -4
- package/dist/src/remote-history.d.ts +63 -0
- package/dist/src/remote-history.js +315 -0
- package/dist/src/remote.d.ts +113 -0
- package/dist/src/remote.js +634 -0
- package/dist/src/shell-hook.d.ts +53 -0
- package/dist/src/shell-hook.js +242 -19
- package/dist/src/ui/theme.d.ts +27 -24
- package/dist/src/ui/theme.js +71 -21
- package/dist/src/upgrade.d.ts +41 -0
- package/dist/src/upgrade.js +348 -0
- package/dist/src/utils/console.js +22 -11
- package/package.json +4 -4
- package/src/alias.ts +301 -0
- package/src/chat-history.ts +11 -1
- package/src/components/Chat.tsx +2 -1
- package/src/components/CodeColorizer.tsx +27 -19
- package/src/components/CommandBox.tsx +2 -1
- package/src/components/ConfirmationPrompt.tsx +2 -1
- package/src/components/Duration.tsx +2 -1
- package/src/components/InlineRenderer.tsx +2 -1
- package/src/components/MarkdownDisplay.tsx +2 -1
- package/src/components/MultiStepCommandGenerator.tsx +25 -11
- package/src/components/TableRenderer.tsx +2 -1
- package/src/config.ts +117 -32
- package/src/multi-step.ts +43 -6
- package/src/remote-history.ts +390 -0
- package/src/remote.ts +800 -0
- package/src/shell-hook.ts +271 -19
- package/src/ui/theme.ts +101 -24
- package/src/upgrade.ts +397 -0
- package/src/utils/console.ts +22 -11
package/src/config.ts
CHANGED
|
@@ -3,6 +3,18 @@ import path from 'path'
|
|
|
3
3
|
import os from 'os'
|
|
4
4
|
import readline from 'readline'
|
|
5
5
|
import chalk from 'chalk'
|
|
6
|
+
import { getCurrentTheme } from './ui/theme.js'
|
|
7
|
+
|
|
8
|
+
// 获取主题颜色
|
|
9
|
+
function getColors() {
|
|
10
|
+
const theme = getCurrentTheme()
|
|
11
|
+
return {
|
|
12
|
+
primary: theme.primary,
|
|
13
|
+
secondary: theme.secondary,
|
|
14
|
+
success: theme.success,
|
|
15
|
+
error: theme.error
|
|
16
|
+
}
|
|
17
|
+
}
|
|
6
18
|
|
|
7
19
|
// 配置文件路径
|
|
8
20
|
export const CONFIG_DIR = path.join(os.homedir(), '.please')
|
|
@@ -27,6 +39,41 @@ type Provider = (typeof VALID_PROVIDERS)[number]
|
|
|
27
39
|
const VALID_EDIT_MODES = ['manual', 'auto'] as const
|
|
28
40
|
type EditMode = (typeof VALID_EDIT_MODES)[number]
|
|
29
41
|
|
|
42
|
+
// 主题
|
|
43
|
+
const VALID_THEMES = ['dark', 'light'] as const
|
|
44
|
+
export type ThemeName = (typeof VALID_THEMES)[number]
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* 别名配置接口
|
|
48
|
+
*/
|
|
49
|
+
export interface AliasConfig {
|
|
50
|
+
prompt: string
|
|
51
|
+
description?: string
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* 远程服务器配置接口
|
|
56
|
+
*/
|
|
57
|
+
export interface RemoteConfig {
|
|
58
|
+
host: string
|
|
59
|
+
user: string
|
|
60
|
+
port: number
|
|
61
|
+
key?: string // SSH 私钥路径
|
|
62
|
+
password?: boolean // 是否使用密码认证(密码不存储,每次交互输入)
|
|
63
|
+
workDir?: string // 默认工作目录
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* 远程服务器系统信息缓存
|
|
68
|
+
*/
|
|
69
|
+
export interface RemoteSysInfo {
|
|
70
|
+
os: string // 操作系统 (linux, darwin, etc.)
|
|
71
|
+
osVersion: string // 系统版本
|
|
72
|
+
shell: string // 默认 shell (bash, zsh, etc.)
|
|
73
|
+
hostname: string // 主机名
|
|
74
|
+
cachedAt: string // 缓存时间
|
|
75
|
+
}
|
|
76
|
+
|
|
30
77
|
/**
|
|
31
78
|
* 配置接口
|
|
32
79
|
*/
|
|
@@ -40,6 +87,10 @@ export interface Config {
|
|
|
40
87
|
commandHistoryLimit: number
|
|
41
88
|
shellHistoryLimit: number
|
|
42
89
|
editMode: EditMode
|
|
90
|
+
theme: ThemeName
|
|
91
|
+
aliases: Record<string, AliasConfig>
|
|
92
|
+
remotes: Record<string, RemoteConfig> // 远程服务器配置
|
|
93
|
+
defaultRemote?: string // 默认远程服务器名称
|
|
43
94
|
}
|
|
44
95
|
|
|
45
96
|
/**
|
|
@@ -55,6 +106,10 @@ const DEFAULT_CONFIG: Config = {
|
|
|
55
106
|
commandHistoryLimit: 10,
|
|
56
107
|
shellHistoryLimit: 15,
|
|
57
108
|
editMode: 'manual',
|
|
109
|
+
theme: 'dark',
|
|
110
|
+
aliases: {},
|
|
111
|
+
remotes: {},
|
|
112
|
+
defaultRemote: '',
|
|
58
113
|
}
|
|
59
114
|
|
|
60
115
|
/**
|
|
@@ -68,20 +123,33 @@ function ensureConfigDir(): void {
|
|
|
68
123
|
|
|
69
124
|
/**
|
|
70
125
|
* 读取配置
|
|
126
|
+
* 优化:添加缓存,避免重复读取文件
|
|
71
127
|
*/
|
|
128
|
+
let cachedConfig: Config | null = null
|
|
129
|
+
|
|
72
130
|
export function getConfig(): Config {
|
|
131
|
+
// 如果已有缓存,直接返回
|
|
132
|
+
if (cachedConfig !== null) {
|
|
133
|
+
return cachedConfig
|
|
134
|
+
}
|
|
135
|
+
|
|
73
136
|
ensureConfigDir()
|
|
74
137
|
|
|
138
|
+
let config: Config
|
|
139
|
+
|
|
75
140
|
if (!fs.existsSync(CONFIG_FILE)) {
|
|
76
|
-
|
|
141
|
+
config = { ...DEFAULT_CONFIG }
|
|
142
|
+
} else {
|
|
143
|
+
try {
|
|
144
|
+
const content = fs.readFileSync(CONFIG_FILE, 'utf-8')
|
|
145
|
+
config = { ...DEFAULT_CONFIG, ...JSON.parse(content) }
|
|
146
|
+
} catch {
|
|
147
|
+
config = { ...DEFAULT_CONFIG }
|
|
148
|
+
}
|
|
77
149
|
}
|
|
78
150
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
return { ...DEFAULT_CONFIG, ...JSON.parse(content) }
|
|
82
|
-
} catch {
|
|
83
|
-
return { ...DEFAULT_CONFIG }
|
|
84
|
-
}
|
|
151
|
+
cachedConfig = config
|
|
152
|
+
return config
|
|
85
153
|
}
|
|
86
154
|
|
|
87
155
|
/**
|
|
@@ -123,11 +191,21 @@ export function setConfigValue(key: string, value: string | boolean | number): C
|
|
|
123
191
|
throw new Error(`editMode 必须是以下之一: ${VALID_EDIT_MODES.join(', ')}`)
|
|
124
192
|
}
|
|
125
193
|
config.editMode = strValue as EditMode
|
|
126
|
-
} else if (key === '
|
|
194
|
+
} else if (key === 'theme') {
|
|
195
|
+
const strValue = String(value)
|
|
196
|
+
if (!VALID_THEMES.includes(strValue as ThemeName)) {
|
|
197
|
+
throw new Error(`theme 必须是以下之一: ${VALID_THEMES.join(', ')}`)
|
|
198
|
+
}
|
|
199
|
+
config.theme = strValue as ThemeName
|
|
200
|
+
} else if (key === 'apiKey' || key === 'baseUrl' || key === 'model' || key === 'defaultRemote') {
|
|
127
201
|
config[key] = String(value)
|
|
128
202
|
}
|
|
129
203
|
|
|
130
204
|
saveConfig(config)
|
|
205
|
+
|
|
206
|
+
// 清除缓存,下次读取时会重新加载
|
|
207
|
+
cachedConfig = null
|
|
208
|
+
|
|
131
209
|
return config
|
|
132
210
|
}
|
|
133
211
|
|
|
@@ -152,23 +230,29 @@ export function maskApiKey(apiKey: string): string {
|
|
|
152
230
|
*/
|
|
153
231
|
export function displayConfig(): void {
|
|
154
232
|
const config = getConfig()
|
|
233
|
+
const colors = getColors()
|
|
155
234
|
console.log(chalk.bold('\n当前配置:'))
|
|
156
235
|
console.log(chalk.gray('━'.repeat(50)))
|
|
157
|
-
console.log(` ${chalk.
|
|
158
|
-
console.log(` ${chalk.
|
|
159
|
-
console.log(` ${chalk.
|
|
160
|
-
console.log(` ${chalk.
|
|
236
|
+
console.log(` ${chalk.hex(colors.primary)('apiKey')}: ${maskApiKey(config.apiKey)}`)
|
|
237
|
+
console.log(` ${chalk.hex(colors.primary)('baseUrl')}: ${config.baseUrl}`)
|
|
238
|
+
console.log(` ${chalk.hex(colors.primary)('provider')}: ${config.provider}`)
|
|
239
|
+
console.log(` ${chalk.hex(colors.primary)('model')}: ${config.model}`)
|
|
161
240
|
console.log(
|
|
162
|
-
` ${chalk.
|
|
241
|
+
` ${chalk.hex(colors.primary)('shellHook')}: ${config.shellHook ? chalk.hex(colors.success)('已启用') : chalk.gray('未启用')}`
|
|
242
|
+
)
|
|
243
|
+
console.log(
|
|
244
|
+
` ${chalk.hex(colors.primary)('editMode')}: ${
|
|
245
|
+
config.editMode === 'auto' ? chalk.hex(colors.primary)('auto (自动编辑)') : chalk.gray('manual (按E编辑)')
|
|
246
|
+
}`
|
|
163
247
|
)
|
|
248
|
+
console.log(` ${chalk.hex(colors.primary)('chatHistoryLimit')}: ${config.chatHistoryLimit} 轮`)
|
|
249
|
+
console.log(` ${chalk.hex(colors.primary)('commandHistoryLimit')}: ${config.commandHistoryLimit} 条`)
|
|
250
|
+
console.log(` ${chalk.hex(colors.primary)('shellHistoryLimit')}: ${config.shellHistoryLimit} 条`)
|
|
164
251
|
console.log(
|
|
165
|
-
` ${chalk.
|
|
166
|
-
config.
|
|
252
|
+
` ${chalk.hex(colors.primary)('theme')}: ${
|
|
253
|
+
config.theme === 'dark' ? chalk.hex(colors.primary)('dark (深色)') : chalk.hex(colors.primary)('light (浅色)')
|
|
167
254
|
}`
|
|
168
255
|
)
|
|
169
|
-
console.log(` ${chalk.cyan('chatHistoryLimit')}: ${config.chatHistoryLimit} 轮`)
|
|
170
|
-
console.log(` ${chalk.cyan('commandHistoryLimit')}: ${config.commandHistoryLimit} 条`)
|
|
171
|
-
console.log(` ${chalk.cyan('shellHistoryLimit')}: ${config.shellHistoryLimit} 条`)
|
|
172
256
|
console.log(chalk.gray('━'.repeat(50)))
|
|
173
257
|
console.log(chalk.gray(`配置文件: ${CONFIG_FILE}\n`))
|
|
174
258
|
}
|
|
@@ -200,19 +284,20 @@ function question(rl: readline.Interface, prompt: string): Promise<string> {
|
|
|
200
284
|
export async function runConfigWizard(): Promise<void> {
|
|
201
285
|
const rl = createReadlineInterface()
|
|
202
286
|
const config = getConfig()
|
|
287
|
+
const colors = getColors()
|
|
203
288
|
|
|
204
|
-
console.log(chalk.bold.hex(
|
|
289
|
+
console.log(chalk.bold.hex(colors.primary)('\n🔧 Pretty Please 配置向导'))
|
|
205
290
|
console.log(chalk.gray('━'.repeat(50)))
|
|
206
291
|
console.log(chalk.gray('直接回车使用默认值,输入值后回车确认\n'))
|
|
207
292
|
|
|
208
293
|
try {
|
|
209
294
|
// 1. Provider
|
|
210
295
|
const providerHint = chalk.gray(`(可选: ${VALID_PROVIDERS.join(', ')})`)
|
|
211
|
-
const providerPrompt = `${chalk.
|
|
296
|
+
const providerPrompt = `${chalk.hex(colors.primary)('Provider')} ${providerHint}\n${chalk.gray('默认:')} ${chalk.hex(colors.secondary)(config.provider)} ${chalk.gray('→')} `
|
|
212
297
|
const provider = await question(rl, providerPrompt)
|
|
213
298
|
if (provider.trim()) {
|
|
214
299
|
if (!VALID_PROVIDERS.includes(provider.trim() as Provider)) {
|
|
215
|
-
console.log(chalk.hex(
|
|
300
|
+
console.log(chalk.hex(colors.error)(`\n✗ 无效的 provider,必须是以下之一: ${VALID_PROVIDERS.join(', ')}`))
|
|
216
301
|
console.log()
|
|
217
302
|
rl.close()
|
|
218
303
|
return
|
|
@@ -221,7 +306,7 @@ export async function runConfigWizard(): Promise<void> {
|
|
|
221
306
|
}
|
|
222
307
|
|
|
223
308
|
// 2. Base URL
|
|
224
|
-
const baseUrlPrompt = `${chalk.
|
|
309
|
+
const baseUrlPrompt = `${chalk.hex(colors.primary)('API Base URL')}\n${chalk.gray('默认:')} ${chalk.hex(colors.secondary)(config.baseUrl)} ${chalk.gray('→')} `
|
|
225
310
|
const baseUrl = await question(rl, baseUrlPrompt)
|
|
226
311
|
if (baseUrl.trim()) {
|
|
227
312
|
config.baseUrl = baseUrl.trim()
|
|
@@ -229,21 +314,21 @@ export async function runConfigWizard(): Promise<void> {
|
|
|
229
314
|
|
|
230
315
|
// 3. API Key
|
|
231
316
|
const currentKeyDisplay = config.apiKey ? maskApiKey(config.apiKey) : '(未设置)'
|
|
232
|
-
const apiKeyPrompt = `${chalk.
|
|
317
|
+
const apiKeyPrompt = `${chalk.hex(colors.primary)('API Key')} ${chalk.gray(`(当前: ${currentKeyDisplay})`)}\n${chalk.gray('→')} `
|
|
233
318
|
const apiKey = await question(rl, apiKeyPrompt)
|
|
234
319
|
if (apiKey.trim()) {
|
|
235
320
|
config.apiKey = apiKey.trim()
|
|
236
321
|
}
|
|
237
322
|
|
|
238
323
|
// 4. Model
|
|
239
|
-
const modelPrompt = `${chalk.
|
|
324
|
+
const modelPrompt = `${chalk.hex(colors.primary)('Model')}\n${chalk.gray('默认:')} ${chalk.hex(colors.secondary)(config.model)} ${chalk.gray('→')} `
|
|
240
325
|
const model = await question(rl, modelPrompt)
|
|
241
326
|
if (model.trim()) {
|
|
242
327
|
config.model = model.trim()
|
|
243
328
|
}
|
|
244
329
|
|
|
245
330
|
// 5. Shell Hook
|
|
246
|
-
const shellHookPrompt = `${chalk.
|
|
331
|
+
const shellHookPrompt = `${chalk.hex(colors.primary)('启用 Shell Hook')} ${chalk.gray('(记录终端命令历史)')}\n${chalk.gray('默认:')} ${chalk.hex(colors.secondary)(config.shellHook ? 'true' : 'false')} ${chalk.gray('→')} `
|
|
247
332
|
const shellHook = await question(rl, shellHookPrompt)
|
|
248
333
|
if (shellHook.trim()) {
|
|
249
334
|
config.shellHook = shellHook.trim() === 'true'
|
|
@@ -251,11 +336,11 @@ export async function runConfigWizard(): Promise<void> {
|
|
|
251
336
|
|
|
252
337
|
// 6. Edit Mode
|
|
253
338
|
const editModeHint = chalk.gray('(manual=按E编辑, auto=自动编辑)')
|
|
254
|
-
const editModePrompt = `${chalk.
|
|
339
|
+
const editModePrompt = `${chalk.hex(colors.primary)('编辑模式')} ${editModeHint}\n${chalk.gray('默认:')} ${chalk.hex(colors.secondary)(config.editMode)} ${chalk.gray('→')} `
|
|
255
340
|
const editMode = await question(rl, editModePrompt)
|
|
256
341
|
if (editMode.trim()) {
|
|
257
342
|
if (!VALID_EDIT_MODES.includes(editMode.trim() as EditMode)) {
|
|
258
|
-
console.log(chalk.hex(
|
|
343
|
+
console.log(chalk.hex(colors.error)(`\n✗ 无效的 editMode,必须是: manual 或 auto`))
|
|
259
344
|
console.log()
|
|
260
345
|
rl.close()
|
|
261
346
|
return
|
|
@@ -264,7 +349,7 @@ export async function runConfigWizard(): Promise<void> {
|
|
|
264
349
|
}
|
|
265
350
|
|
|
266
351
|
// 7. Chat History Limit
|
|
267
|
-
const chatHistoryPrompt = `${chalk.
|
|
352
|
+
const chatHistoryPrompt = `${chalk.hex(colors.primary)('Chat 历史保留轮数')}\n${chalk.gray('默认:')} ${chalk.hex(colors.secondary)(config.chatHistoryLimit)} ${chalk.gray('→')} `
|
|
268
353
|
const chatHistoryLimit = await question(rl, chatHistoryPrompt)
|
|
269
354
|
if (chatHistoryLimit.trim()) {
|
|
270
355
|
const num = parseInt(chatHistoryLimit.trim(), 10)
|
|
@@ -274,7 +359,7 @@ export async function runConfigWizard(): Promise<void> {
|
|
|
274
359
|
}
|
|
275
360
|
|
|
276
361
|
// 8. Command History Limit
|
|
277
|
-
const commandHistoryPrompt = `${chalk.
|
|
362
|
+
const commandHistoryPrompt = `${chalk.hex(colors.primary)('命令历史保留条数')}\n${chalk.gray('默认:')} ${chalk.hex(colors.secondary)(config.commandHistoryLimit)} ${chalk.gray('→')} `
|
|
278
363
|
const commandHistoryLimit = await question(rl, commandHistoryPrompt)
|
|
279
364
|
if (commandHistoryLimit.trim()) {
|
|
280
365
|
const num = parseInt(commandHistoryLimit.trim(), 10)
|
|
@@ -284,7 +369,7 @@ export async function runConfigWizard(): Promise<void> {
|
|
|
284
369
|
}
|
|
285
370
|
|
|
286
371
|
// 9. Shell History Limit
|
|
287
|
-
const shellHistoryPrompt = `${chalk.
|
|
372
|
+
const shellHistoryPrompt = `${chalk.hex(colors.primary)('Shell 历史保留条数')}\n${chalk.gray('默认:')} ${chalk.hex(colors.secondary)(config.shellHistoryLimit)} ${chalk.gray('→')} `
|
|
288
373
|
const shellHistoryLimit = await question(rl, shellHistoryPrompt)
|
|
289
374
|
if (shellHistoryLimit.trim()) {
|
|
290
375
|
const num = parseInt(shellHistoryLimit.trim(), 10)
|
|
@@ -296,12 +381,12 @@ export async function runConfigWizard(): Promise<void> {
|
|
|
296
381
|
saveConfig(config)
|
|
297
382
|
|
|
298
383
|
console.log('\n' + chalk.gray('━'.repeat(50)))
|
|
299
|
-
console.log(chalk.hex(
|
|
384
|
+
console.log(chalk.hex(getColors().success)('✅ 配置已保存'))
|
|
300
385
|
console.log(chalk.gray(` ${CONFIG_FILE}`))
|
|
301
386
|
console.log()
|
|
302
387
|
} catch (error) {
|
|
303
388
|
const message = error instanceof Error ? error.message : String(error)
|
|
304
|
-
console.log(chalk.hex(
|
|
389
|
+
console.log(chalk.hex(getColors().error)(`\n✗ 配置失败: ${message}`))
|
|
305
390
|
console.log()
|
|
306
391
|
} finally {
|
|
307
392
|
rl.close()
|
package/src/multi-step.ts
CHANGED
|
@@ -4,16 +4,19 @@ import { buildCommandSystemPrompt } from './prompts.js'
|
|
|
4
4
|
import { formatSystemInfo } from './sysinfo.js'
|
|
5
5
|
import { formatHistoryForAI } from './history.js'
|
|
6
6
|
import { formatShellHistoryForAI, getShellHistory } from './shell-hook.js'
|
|
7
|
-
import { getConfig } from './config.js'
|
|
7
|
+
import { getConfig, type RemoteSysInfo } from './config.js'
|
|
8
|
+
import { formatRemoteHistoryForAI, formatRemoteShellHistoryForAI, type RemoteShellHistoryItem } from './remote-history.js'
|
|
9
|
+
import { formatRemoteSysInfoForAI } from './remote.js'
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* 多步骤命令的 Zod Schema
|
|
13
|
+
* 注意:optional 字段使用 .default() 是为了绕过 Mastra 0.24.8 对 optional 字段的验证 bug
|
|
11
14
|
*/
|
|
12
15
|
export const CommandStepSchema = z.object({
|
|
13
16
|
command: z.string(),
|
|
14
|
-
continue: z.boolean().optional(),
|
|
15
|
-
reasoning: z.string().optional(),
|
|
16
|
-
nextStepHint: z.string().optional(),
|
|
17
|
+
continue: z.boolean().optional().default(false),
|
|
18
|
+
reasoning: z.string().optional().default(''),
|
|
19
|
+
nextStepHint: z.string().optional().default(''),
|
|
17
20
|
})
|
|
18
21
|
|
|
19
22
|
export type CommandStep = z.infer<typeof CommandStepSchema>
|
|
@@ -26,6 +29,15 @@ export interface ExecutedStep extends CommandStep {
|
|
|
26
29
|
output: string
|
|
27
30
|
}
|
|
28
31
|
|
|
32
|
+
/**
|
|
33
|
+
* 远程执行上下文
|
|
34
|
+
*/
|
|
35
|
+
export interface RemoteContext {
|
|
36
|
+
name: string
|
|
37
|
+
sysInfo: RemoteSysInfo
|
|
38
|
+
shellHistory: RemoteShellHistoryItem[]
|
|
39
|
+
}
|
|
40
|
+
|
|
29
41
|
/**
|
|
30
42
|
* 生成系统上下文信息(供 Mastra 使用)
|
|
31
43
|
*/
|
|
@@ -39,16 +51,37 @@ export function getFullSystemPrompt() {
|
|
|
39
51
|
return buildCommandSystemPrompt(sysinfo, plsHistory, shellHistory, shellHookEnabled)
|
|
40
52
|
}
|
|
41
53
|
|
|
54
|
+
/**
|
|
55
|
+
* 生成远程系统上下文信息
|
|
56
|
+
*/
|
|
57
|
+
export function getRemoteFullSystemPrompt(remoteContext: RemoteContext) {
|
|
58
|
+
// 格式化远程系统信息
|
|
59
|
+
const sysinfo = formatRemoteSysInfoForAI(remoteContext.name, remoteContext.sysInfo)
|
|
60
|
+
|
|
61
|
+
// 格式化远程 pls 命令历史
|
|
62
|
+
const plsHistory = formatRemoteHistoryForAI(remoteContext.name)
|
|
63
|
+
|
|
64
|
+
// 格式化远程 shell 历史
|
|
65
|
+
const shellHistory = formatRemoteShellHistoryForAI(remoteContext.shellHistory)
|
|
66
|
+
const shellHookEnabled = remoteContext.shellHistory.length > 0
|
|
67
|
+
|
|
68
|
+
return buildCommandSystemPrompt(sysinfo, plsHistory, shellHistory, shellHookEnabled)
|
|
69
|
+
}
|
|
70
|
+
|
|
42
71
|
/**
|
|
43
72
|
* 使用 Mastra 生成多步骤命令
|
|
44
73
|
*/
|
|
45
74
|
export async function generateMultiStepCommand(
|
|
46
75
|
userPrompt: string,
|
|
47
76
|
previousSteps: ExecutedStep[] = [],
|
|
48
|
-
options: { debug?: boolean } = {}
|
|
77
|
+
options: { debug?: boolean; remoteContext?: RemoteContext } = {}
|
|
49
78
|
): Promise<{ stepData: CommandStep; debugInfo?: any }> {
|
|
50
79
|
const agent = createShellAgent()
|
|
51
|
-
|
|
80
|
+
|
|
81
|
+
// 根据是否有远程上下文选择不同的系统提示词
|
|
82
|
+
const fullSystemPrompt = options.remoteContext
|
|
83
|
+
? getRemoteFullSystemPrompt(options.remoteContext)
|
|
84
|
+
: getFullSystemPrompt()
|
|
52
85
|
|
|
53
86
|
// 构建消息数组(string[] 格式)
|
|
54
87
|
const messages: string[] = [userPrompt]
|
|
@@ -85,6 +118,10 @@ export async function generateMultiStepCommand(
|
|
|
85
118
|
userPrompt,
|
|
86
119
|
previousStepsCount: previousSteps.length,
|
|
87
120
|
response: stepData,
|
|
121
|
+
remoteContext: options.remoteContext ? {
|
|
122
|
+
name: options.remoteContext.name,
|
|
123
|
+
sysInfo: options.remoteContext.sysInfo,
|
|
124
|
+
} : undefined,
|
|
88
125
|
},
|
|
89
126
|
}
|
|
90
127
|
}
|