@aalis/plugin-cli 0.1.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 +21 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +982 -0
- package/dist/index.js.map +1 -0
- package/dist/log-file.d.ts +3 -0
- package/dist/log-file.d.ts.map +1 -0
- package/dist/log-file.js +23 -0
- package/dist/log-file.js.map +1 -0
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +47 -0
package/README.md
ADDED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ConfigSchema, Context } from '@aalis/core';
|
|
2
|
+
export type { CLIService } from './types.js';
|
|
3
|
+
declare module '@aalis/core' {
|
|
4
|
+
interface AalisEvents {
|
|
5
|
+
'terminal:claimed': [owner: string];
|
|
6
|
+
'terminal:released': [owner: string];
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export declare const name = "@aalis/plugin-cli";
|
|
10
|
+
export declare const displayName = "CLI \u7EC8\u7AEF";
|
|
11
|
+
export declare const subsystem = "platform";
|
|
12
|
+
export declare const inject: {
|
|
13
|
+
optional: string[];
|
|
14
|
+
};
|
|
15
|
+
export declare const provides: string[];
|
|
16
|
+
export declare const configSchema: ConfigSchema;
|
|
17
|
+
export declare const defaultConfig: {
|
|
18
|
+
prompt: string;
|
|
19
|
+
sessionId: string;
|
|
20
|
+
startupView: string;
|
|
21
|
+
lastView: string;
|
|
22
|
+
};
|
|
23
|
+
export declare function apply(ctx: Context, config: Record<string, unknown>): void;
|
|
24
|
+
declare module '@aalis/core' {
|
|
25
|
+
interface ServiceTypeMap {
|
|
26
|
+
cli: import('./types.js').CLIService;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAc,YAAY,EAAE,OAAO,EAAY,MAAM,aAAa,CAAC;AAU/E,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAQ7C,OAAO,QAAQ,aAAa,CAAC;IAC3B,UAAU,WAAW;QACnB,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACpC,mBAAmB,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;KACtC;CACF;AAID,eAAO,MAAM,IAAI,sBAAsB,CAAC;AACxC,eAAO,MAAM,WAAW,qBAAW,CAAC;AACpC,eAAO,MAAM,SAAS,aAAa,CAAC;AACpC,eAAO,MAAM,MAAM;;CAElB,CAAC;AACF,eAAO,MAAM,QAAQ,UAAsB,CAAC;AAE5C,eAAO,MAAM,YAAY,EAAE,YAc1B,CAAC;AAEF,eAAO,MAAM,aAAa;;;;;CAKzB,CAAC;AAWF,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAkFzE;AA+2BD,OAAO,QAAQ,aAAa,CAAC;IAC3B,UAAU,cAAc;QACtB,GAAG,EAAE,OAAO,YAAY,EAAE,UAAU,CAAC;KACtC;CACF"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,982 @@
|
|
|
1
|
+
import { stdin as input, stdout as output } from 'node:process';
|
|
2
|
+
import * as readline from 'node:readline';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import cliTruncate from 'cli-truncate';
|
|
5
|
+
import stringWidth from 'string-width';
|
|
6
|
+
import { LogHub } from '@aalis/core';
|
|
7
|
+
import { readLogFileTail } from './log-file.js';
|
|
8
|
+
// ===== 插件元数据 =====
|
|
9
|
+
export const name = '@aalis/plugin-cli';
|
|
10
|
+
export const displayName = 'CLI 终端';
|
|
11
|
+
export const subsystem = 'platform';
|
|
12
|
+
export const inject = {
|
|
13
|
+
optional: ['llm', 'authority', 'commands'],
|
|
14
|
+
};
|
|
15
|
+
export const provides = ['cli', 'platform'];
|
|
16
|
+
export const configSchema = {
|
|
17
|
+
prompt: { type: 'string', label: '提示符', default: 'You', description: '命令行输入提示符前缀' },
|
|
18
|
+
startupView: {
|
|
19
|
+
type: 'select',
|
|
20
|
+
label: '启动视图',
|
|
21
|
+
default: 'last',
|
|
22
|
+
description: 'CLI 接管终端后的默认视图。last 表示恢复上次视图',
|
|
23
|
+
options: [
|
|
24
|
+
{ label: '恢复上次', value: 'last' },
|
|
25
|
+
{ label: '聊天', value: 'chat' },
|
|
26
|
+
{ label: '日志', value: 'logs' },
|
|
27
|
+
{ label: '状态', value: 'status' },
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
export const defaultConfig = {
|
|
32
|
+
prompt: 'You',
|
|
33
|
+
sessionId: 'cli-default',
|
|
34
|
+
startupView: 'last',
|
|
35
|
+
lastView: 'chat',
|
|
36
|
+
};
|
|
37
|
+
export function apply(ctx, config) {
|
|
38
|
+
const cliConfig = {
|
|
39
|
+
prompt: config.prompt ?? defaultConfig.prompt,
|
|
40
|
+
sessionId: config.sessionId ?? defaultConfig.sessionId,
|
|
41
|
+
startupView: parseStartupView(config.startupView),
|
|
42
|
+
lastView: parseView(config.lastView, 'chat'),
|
|
43
|
+
};
|
|
44
|
+
const sessionId = cliConfig.sessionId;
|
|
45
|
+
let tui = null;
|
|
46
|
+
const adapter = {
|
|
47
|
+
adapterName: 'CLI',
|
|
48
|
+
platform: 'cli',
|
|
49
|
+
sessionTypes: [], // CLI 单会话,不区分 sessionType
|
|
50
|
+
getConnections() {
|
|
51
|
+
return [{ id: sessionId, platform: 'cli', status: tui?.isRunning() ? 'online' : 'offline' }];
|
|
52
|
+
},
|
|
53
|
+
// sessionId 由配置直接给出(不带 platform 前缀),需显式声明只接管自己的 sessionId
|
|
54
|
+
canHandle(sid) {
|
|
55
|
+
return sid === sessionId;
|
|
56
|
+
},
|
|
57
|
+
async sendMessage(_sessionId, content) {
|
|
58
|
+
tui?.pushAssistant(content);
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
ctx.provide('platform', adapter, { capabilities: ['cli', 'text'] });
|
|
62
|
+
const cliService = {
|
|
63
|
+
getSessionId: () => sessionId,
|
|
64
|
+
isRunning: () => tui?.isRunning() ?? false,
|
|
65
|
+
};
|
|
66
|
+
ctx.provide('cli', cliService);
|
|
67
|
+
ctx.on('outbound:message', msg => {
|
|
68
|
+
if (msg.sessionId !== sessionId)
|
|
69
|
+
return;
|
|
70
|
+
if (tui?.consumeStreamedSend())
|
|
71
|
+
return; // 同一轮已流式输出,跳过重复
|
|
72
|
+
adapter.sendMessage(msg.sessionId, msg.content);
|
|
73
|
+
});
|
|
74
|
+
ctx.on('outbound:stream', chunk => {
|
|
75
|
+
if (chunk.sessionId !== sessionId)
|
|
76
|
+
return;
|
|
77
|
+
tui?.applyStreamChunk(chunk);
|
|
78
|
+
});
|
|
79
|
+
// 临时缓冲:plugin apply 早于 app:started,但晚于 bootstrap-buffer.dispose();
|
|
80
|
+
// 我们订阅一个 onEntry 把这段窗口的实时 entry 留住,并在 app:started 时合并
|
|
81
|
+
// data/latest.log 尾部(覆盖 plugin apply 之前的早期 boot 日志)。
|
|
82
|
+
const liveBuffer = [];
|
|
83
|
+
let liveBufferActive = true;
|
|
84
|
+
const stopLiveBuffer = LogHub.default.onEntry(entry => {
|
|
85
|
+
if (liveBufferActive)
|
|
86
|
+
liveBuffer.push(entry);
|
|
87
|
+
});
|
|
88
|
+
ctx.on('app:started', async () => {
|
|
89
|
+
let initial = [];
|
|
90
|
+
try {
|
|
91
|
+
initial = await readLogFileTail(2000);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// 文件未就绪可忽略——只是无早期历史
|
|
95
|
+
}
|
|
96
|
+
// 合并:file tail 与 live buffer 都可能含同一 seq,按 seq 去重排序
|
|
97
|
+
const seen = new Set();
|
|
98
|
+
const merged = [];
|
|
99
|
+
for (const e of initial) {
|
|
100
|
+
if (seen.has(e.seq))
|
|
101
|
+
continue;
|
|
102
|
+
seen.add(e.seq);
|
|
103
|
+
merged.push(e);
|
|
104
|
+
}
|
|
105
|
+
for (const e of liveBuffer) {
|
|
106
|
+
if (seen.has(e.seq))
|
|
107
|
+
continue;
|
|
108
|
+
seen.add(e.seq);
|
|
109
|
+
merged.push(e);
|
|
110
|
+
}
|
|
111
|
+
merged.sort((a, b) => a.seq - b.seq);
|
|
112
|
+
liveBufferActive = false;
|
|
113
|
+
stopLiveBuffer();
|
|
114
|
+
tui = new CliTui(ctx, cliConfig, sessionId, merged);
|
|
115
|
+
tui.start();
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
function parseView(value, fallback) {
|
|
119
|
+
return value === 'chat' || value === 'logs' || value === 'status' || value === 'help' ? value : fallback;
|
|
120
|
+
}
|
|
121
|
+
function parseStartupView(value) {
|
|
122
|
+
if (value === 'last')
|
|
123
|
+
return 'last';
|
|
124
|
+
if (value === 'chat' || value === 'logs' || value === 'status' || value === 'help')
|
|
125
|
+
return value;
|
|
126
|
+
return 'last';
|
|
127
|
+
}
|
|
128
|
+
class CliTui {
|
|
129
|
+
ctx;
|
|
130
|
+
config;
|
|
131
|
+
sessionId;
|
|
132
|
+
view;
|
|
133
|
+
previousView = 'chat';
|
|
134
|
+
running = false;
|
|
135
|
+
inputLine = '';
|
|
136
|
+
cursor = 0;
|
|
137
|
+
history = [];
|
|
138
|
+
historyIndex = null;
|
|
139
|
+
chatLines = [];
|
|
140
|
+
logLines;
|
|
141
|
+
logScroll = 0;
|
|
142
|
+
logWrap = false;
|
|
143
|
+
statusScroll = 0;
|
|
144
|
+
helpScroll = 0;
|
|
145
|
+
removeLogListener = null;
|
|
146
|
+
// 流式状态:记录本 session 当前正在生成的 assistant 回复首行在 chatLines 中的下标
|
|
147
|
+
streamingStartIndex = null;
|
|
148
|
+
streamingContent = '';
|
|
149
|
+
streamedRecently = false;
|
|
150
|
+
confirmResolver = null;
|
|
151
|
+
/** 鼠标 SGR 序列在处理中:readline 会把序列中间的数字/分号拆成独立 keypress,
|
|
152
|
+
* 需要从看到 \x1b[< 起到看到 M/m 为止吞掉所有 keypress。 */
|
|
153
|
+
inMouseSeq = false;
|
|
154
|
+
confirmText = '';
|
|
155
|
+
renderQueued = false;
|
|
156
|
+
closing = false;
|
|
157
|
+
restoreOnExit = () => restoreTerminalState();
|
|
158
|
+
constructor(ctx, config, sessionId, initialEntries = []) {
|
|
159
|
+
this.ctx = ctx;
|
|
160
|
+
this.config = config;
|
|
161
|
+
this.sessionId = sessionId;
|
|
162
|
+
this.view = config.startupView === 'last' ? config.lastView : config.startupView;
|
|
163
|
+
// 启动期日志由 apply() 通过尾读 data/latest.log + 实时 buffer 合并后注入,
|
|
164
|
+
// 之后通过 LogHub.onEntry 实时累积;按 seq 单调,下方 onEntry 用 lastSeq 去重避免与 initial 重复。
|
|
165
|
+
this.logLines = initialEntries.slice();
|
|
166
|
+
}
|
|
167
|
+
isRunning() {
|
|
168
|
+
return this.running;
|
|
169
|
+
}
|
|
170
|
+
start() {
|
|
171
|
+
if (this.running)
|
|
172
|
+
return;
|
|
173
|
+
this.running = true;
|
|
174
|
+
// 宣告"我接管终端"——任何写 stdout 的订阅者(runtime/console-sink 等)
|
|
175
|
+
// 自行响应该事件停止写入,CLI 不直接干预日志系统。
|
|
176
|
+
this.ctx.emit('terminal:claimed', 'cli').catch(() => { });
|
|
177
|
+
// 1049h: 进入备用屏 / 25l: 隐藏光标 / 1007h: alternate scroll(兜底,部分终端不支持)
|
|
178
|
+
// 1000h+1006h: SGR 鼠标上报,覆盖滚轮事件以便所有终端都能滚动
|
|
179
|
+
// 注意:开启 1000h 后终端会把左/右键也发给程序,导致原生选择被吞。
|
|
180
|
+
// 我们在 handleData 里仅处理滚轮 (button 64/65),其它按键事件直接忽略。
|
|
181
|
+
// 选择文本时按住平台修饰键即可绕过鼠标上报(见 help 页提示)。
|
|
182
|
+
output.write('\x1b[?1049h\x1b[?25l\x1b[?1007h\x1b[?1000h\x1b[?1006h');
|
|
183
|
+
output.write('\x1b[2J\x1b[H');
|
|
184
|
+
readline.emitKeypressEvents(input);
|
|
185
|
+
if (input.isTTY)
|
|
186
|
+
input.setRawMode(true);
|
|
187
|
+
input.resume();
|
|
188
|
+
input.on('data', this.handleData);
|
|
189
|
+
process.once('exit', this.restoreOnExit);
|
|
190
|
+
// 已注入 initialEntries 中最大的 seq;onEntry 收到 seq <= 此值的视为重复跳过
|
|
191
|
+
let lastSeq = this.logLines.length > 0 ? this.logLines[this.logLines.length - 1].seq : -1;
|
|
192
|
+
this.removeLogListener = LogHub.default.onEntry(entry => {
|
|
193
|
+
if (entry.seq <= lastSeq)
|
|
194
|
+
return;
|
|
195
|
+
lastSeq = entry.seq;
|
|
196
|
+
// 不限长——启动期起累积,渲染仅访问可见窗口,内存价格可接受
|
|
197
|
+
this.logLines.push(entry);
|
|
198
|
+
// 用户已主动向上滚(logScroll > 0)时,新日志到来应保持视图锚定在原历史位置,
|
|
199
|
+
// 而非随 raw.length 增长把旧内容挤出可见区。logScroll === 0 表示跟随底部。
|
|
200
|
+
if (this.view === 'logs' && this.logScroll > 0)
|
|
201
|
+
this.logScroll += 1;
|
|
202
|
+
if (this.view === 'logs')
|
|
203
|
+
this.queueRender();
|
|
204
|
+
});
|
|
205
|
+
const persona = this.ctx.getService('persona');
|
|
206
|
+
const assistantName = persona?.getPersonaName() ?? 'Aalis';
|
|
207
|
+
this.chatLines.push(chalk.gray(this.formatCont()) + chalk.gray(`欢迎使用 ${assistantName}。按 ${chalk.cyan('Ctrl+G')} 查看快捷键。`));
|
|
208
|
+
this.ctx.getService('authority')?.setConfirmHandler('cli', async (request) => {
|
|
209
|
+
return this.askConfirm(`/${request.name} 是高危指令,按 y 确认,其他键取消`);
|
|
210
|
+
});
|
|
211
|
+
input.on('keypress', this.handleKeypress);
|
|
212
|
+
output.on('resize', this.queueRender);
|
|
213
|
+
this.ctx.onDispose(() => this.stop());
|
|
214
|
+
this.render();
|
|
215
|
+
}
|
|
216
|
+
stop() {
|
|
217
|
+
if (this.closing)
|
|
218
|
+
return;
|
|
219
|
+
this.closing = true;
|
|
220
|
+
this.running = false;
|
|
221
|
+
this.removeLogListener?.();
|
|
222
|
+
this.removeLogListener = null;
|
|
223
|
+
input.off('keypress', this.handleKeypress);
|
|
224
|
+
input.off('data', this.handleData);
|
|
225
|
+
output.off('resize', this.queueRender);
|
|
226
|
+
process.off('exit', this.restoreOnExit);
|
|
227
|
+
restoreTerminalState();
|
|
228
|
+
// 归还终端——sink 等订阅者可自行恢复
|
|
229
|
+
this.ctx.emit('terminal:released', 'cli').catch(() => { });
|
|
230
|
+
}
|
|
231
|
+
pushAssistant(content) {
|
|
232
|
+
if (!content.trim())
|
|
233
|
+
return;
|
|
234
|
+
this.appendAssistantLines(content);
|
|
235
|
+
this.trimChat();
|
|
236
|
+
if (this.view === 'chat')
|
|
237
|
+
this.queueRender();
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* 上一轮 是否有流式内容。调用后会重置。转发文件时 outbound:message 看到流完整后重复发送,需要跳过。
|
|
241
|
+
*/
|
|
242
|
+
consumeStreamedSend() {
|
|
243
|
+
if (this.streamedRecently) {
|
|
244
|
+
this.streamedRecently = false;
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
applyStreamChunk(chunk) {
|
|
250
|
+
if (chunk.done) {
|
|
251
|
+
// 完结本轮流式
|
|
252
|
+
if (this.streamingStartIndex !== null) {
|
|
253
|
+
this.streamedRecently = true;
|
|
254
|
+
this.streamingStartIndex = null;
|
|
255
|
+
this.streamingContent = '';
|
|
256
|
+
if (this.view === 'chat')
|
|
257
|
+
this.queueRender();
|
|
258
|
+
}
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
if (!chunk.contentDelta)
|
|
262
|
+
return;
|
|
263
|
+
// 首个块:创建一个新的 assistant 条目
|
|
264
|
+
if (this.streamingStartIndex === null) {
|
|
265
|
+
this.streamingContent = '';
|
|
266
|
+
this.streamingStartIndex = this.chatLines.length;
|
|
267
|
+
// 占位行,formatAssistantBlock 会立即替换
|
|
268
|
+
this.chatLines.push('');
|
|
269
|
+
}
|
|
270
|
+
this.streamingContent += chunk.contentDelta;
|
|
271
|
+
// 根据累积内容重建该消息占据的行
|
|
272
|
+
const rebuilt = this.formatAssistantBlock(this.streamingContent);
|
|
273
|
+
this.chatLines.splice(this.streamingStartIndex, this.chatLines.length - this.streamingStartIndex, ...rebuilt);
|
|
274
|
+
this.trimChat();
|
|
275
|
+
if (this.view === 'chat')
|
|
276
|
+
this.queueRender();
|
|
277
|
+
}
|
|
278
|
+
appendAssistantLines(content) {
|
|
279
|
+
const lines = this.formatAssistantBlock(content);
|
|
280
|
+
for (const l of lines)
|
|
281
|
+
this.chatLines.push(l);
|
|
282
|
+
}
|
|
283
|
+
/** 所有标签对齐到同一列宽,确保 │ 竖线垂直对齐 */
|
|
284
|
+
labelCol() {
|
|
285
|
+
const persona = this.ctx.getService('persona')?.getPersonaName() ?? 'Aalis';
|
|
286
|
+
return Math.max(visibleLen(`✦ ${persona}`), // assistant
|
|
287
|
+
visibleLen(`❯ ${this.config.prompt}`), // user
|
|
288
|
+
visibleLen('◆ System'), // system
|
|
289
|
+
visibleLen('∘'));
|
|
290
|
+
}
|
|
291
|
+
/** 把 label 右侧补空格到 labelCol 宽,再加 ` │ ` */
|
|
292
|
+
formatHead(label) {
|
|
293
|
+
const col = this.labelCol();
|
|
294
|
+
const pad = Math.max(0, col - visibleLen(label));
|
|
295
|
+
return `${label + ' '.repeat(pad)} ${chalk.gray('│')} `;
|
|
296
|
+
}
|
|
297
|
+
formatCont() {
|
|
298
|
+
const col = this.labelCol();
|
|
299
|
+
return `${' '.repeat(col)} ${chalk.gray('│')} `;
|
|
300
|
+
}
|
|
301
|
+
formatAssistantBlock(content) {
|
|
302
|
+
const persona = this.ctx.getService('persona')?.getPersonaName() ?? 'Aalis';
|
|
303
|
+
const firstHead = this.formatHead(chalk.green(`✦ ${persona}`));
|
|
304
|
+
const contHead = this.formatCont();
|
|
305
|
+
return content.split('\n').map((line, i) => (i === 0 ? firstHead : contHead) + line);
|
|
306
|
+
}
|
|
307
|
+
/** SGR 鼠标事件:\x1b[<button;col;row(M|m)。仅处理滚轮(button 64=up, 65=down,加 4/8/16 表示 Shift/Alt/Ctrl);
|
|
308
|
+
* 其它按键 (0/1/2 = 左/中/右) 一律丢弃,避免抢走原生选择/复制。 */
|
|
309
|
+
handleData = (chunk) => {
|
|
310
|
+
if (!this.running)
|
|
311
|
+
return;
|
|
312
|
+
const s = typeof chunk === 'string' ? chunk : chunk.toString('utf8');
|
|
313
|
+
if (!s.includes('\x1b[<'))
|
|
314
|
+
return;
|
|
315
|
+
// biome-ignore lint/suspicious/noControlCharactersInRegex: 解析 SGR 鼠标协议需要按字面匹配 ESC
|
|
316
|
+
const re = /\x1b\[<(\d+);\d+;\d+([Mm])/g;
|
|
317
|
+
let m = re.exec(s);
|
|
318
|
+
while (m !== null) {
|
|
319
|
+
if (m[2] === 'M') {
|
|
320
|
+
const button = parseInt(m[1], 10);
|
|
321
|
+
const base = button & ~28; // 去掉 Shift(4)/Alt(8)/Ctrl(16)
|
|
322
|
+
const big = (button & 4) !== 0; // Shift+滚轮 = 翻页
|
|
323
|
+
if (base === 64)
|
|
324
|
+
this.scrollCurrentView(+1, big);
|
|
325
|
+
else if (base === 65)
|
|
326
|
+
this.scrollCurrentView(-1, big);
|
|
327
|
+
// base === 0/1/2 (左/中/右) 直接忽略:让用户在终端层做选择/复制
|
|
328
|
+
}
|
|
329
|
+
m = re.exec(s);
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
/** 统一的滚动入口:direction +1 = 往旧/上滚,-1 = 往新/下滚。 */
|
|
333
|
+
scrollCurrentView(direction, big) {
|
|
334
|
+
const step = (big ? 10 : 3) * direction;
|
|
335
|
+
if (this.view === 'logs') {
|
|
336
|
+
const max = Math.max(0, this.logLines.length - 1);
|
|
337
|
+
this.logScroll = Math.max(0, Math.min(max, this.logScroll + step));
|
|
338
|
+
}
|
|
339
|
+
else if (this.view === 'status') {
|
|
340
|
+
this.statusScroll = Math.max(0, this.statusScroll - step);
|
|
341
|
+
}
|
|
342
|
+
else if (this.view === 'help') {
|
|
343
|
+
this.helpScroll = Math.max(0, this.helpScroll - step);
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
this.queueRender();
|
|
349
|
+
}
|
|
350
|
+
handleKeypress = async (chunk, key) => {
|
|
351
|
+
if (!this.running)
|
|
352
|
+
return;
|
|
353
|
+
// 鼠标 SGR 序列状态机:从 \x1b[< 到 M/m 之间的所有 keypress 都吞掉
|
|
354
|
+
if (key.sequence?.startsWith('\x1b[<') || chunk?.startsWith('\x1b[<')) {
|
|
355
|
+
this.inMouseSeq = true;
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
if (this.inMouseSeq) {
|
|
359
|
+
if (chunk === 'M' || chunk === 'm' || key.sequence === 'M' || key.sequence === 'm') {
|
|
360
|
+
this.inMouseSeq = false;
|
|
361
|
+
}
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
if (this.confirmResolver) {
|
|
365
|
+
const ok = key.name === 'y' || chunk.toLowerCase() === 'y';
|
|
366
|
+
const resolve = this.confirmResolver;
|
|
367
|
+
this.confirmResolver = null;
|
|
368
|
+
this.confirmText = '';
|
|
369
|
+
resolve(ok);
|
|
370
|
+
this.queueRender();
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
if (key.ctrl && key.name === 'c') {
|
|
374
|
+
this.stop();
|
|
375
|
+
process.kill(process.pid, 'SIGINT');
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
if (key.ctrl && key.name === 'l') {
|
|
379
|
+
this.switchView('logs');
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
if (key.ctrl && key.name === 't') {
|
|
383
|
+
this.switchView('chat');
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
if (key.ctrl && key.name === 's') {
|
|
387
|
+
this.switchView('status');
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
if (key.ctrl && key.name === 'g') {
|
|
391
|
+
this.switchView('help');
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
if (key.name === 'escape') {
|
|
395
|
+
this.switchView(this.previousView);
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
if (this.view === 'logs') {
|
|
399
|
+
this.handleLogsKey(key);
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
if (this.view === 'status') {
|
|
403
|
+
this.handleScrollKey(key, 'statusScroll');
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
if (this.view === 'help') {
|
|
407
|
+
this.handleScrollKey(key, 'helpScroll');
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
if (this.view !== 'chat')
|
|
411
|
+
return;
|
|
412
|
+
// 换行快捷:Ctrl+J / Shift+Enter / Alt+Enter / 原始 \n 输入
|
|
413
|
+
const isNewline = (key.ctrl && key.name === 'j') ||
|
|
414
|
+
(key.shift && key.name === 'return') ||
|
|
415
|
+
(key.meta && (key.name === 'return' || key.name === 'enter')) ||
|
|
416
|
+
(!key.ctrl && !key.meta && chunk === '\n' && key.name !== 'return');
|
|
417
|
+
if (isNewline) {
|
|
418
|
+
this.inputLine = `${this.inputLine.slice(0, this.cursor)}\n${this.inputLine.slice(this.cursor)}`;
|
|
419
|
+
this.cursor++;
|
|
420
|
+
this.queueRender();
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
if (key.name === 'return') {
|
|
424
|
+
await this.submitLine();
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
if (key.name === 'backspace') {
|
|
428
|
+
if (this.cursor > 0) {
|
|
429
|
+
this.inputLine = this.inputLine.slice(0, this.cursor - 1) + this.inputLine.slice(this.cursor);
|
|
430
|
+
this.cursor--;
|
|
431
|
+
this.queueRender();
|
|
432
|
+
}
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
if (key.name === 'delete') {
|
|
436
|
+
if (this.cursor < this.inputLine.length) {
|
|
437
|
+
this.inputLine = this.inputLine.slice(0, this.cursor) + this.inputLine.slice(this.cursor + 1);
|
|
438
|
+
this.queueRender();
|
|
439
|
+
}
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
if (key.name === 'left') {
|
|
443
|
+
this.cursor = Math.max(0, this.cursor - 1);
|
|
444
|
+
this.queueRender();
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
if (key.name === 'right') {
|
|
448
|
+
this.cursor = Math.min(this.inputLine.length, this.cursor + 1);
|
|
449
|
+
this.queueRender();
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
if (key.name === 'home') {
|
|
453
|
+
this.cursor = 0;
|
|
454
|
+
this.queueRender();
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
if (key.name === 'end') {
|
|
458
|
+
this.cursor = this.inputLine.length;
|
|
459
|
+
this.queueRender();
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
if (key.name === 'up') {
|
|
463
|
+
this.recallHistory(-1);
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
if (key.name === 'down') {
|
|
467
|
+
this.recallHistory(1);
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
if (!key.ctrl && !key.meta && chunk && chunk >= ' ') {
|
|
471
|
+
this.inputLine = this.inputLine.slice(0, this.cursor) + chunk + this.inputLine.slice(this.cursor);
|
|
472
|
+
this.cursor += chunk.length;
|
|
473
|
+
this.queueRender();
|
|
474
|
+
}
|
|
475
|
+
};
|
|
476
|
+
handleLogsKey(key) {
|
|
477
|
+
if (key.ctrl && key.name === 'w') {
|
|
478
|
+
this.logWrap = !this.logWrap;
|
|
479
|
+
this.logScroll = 0;
|
|
480
|
+
this.queueRender();
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
const maxScroll = Math.max(0, this.logLines.length - 1);
|
|
484
|
+
if (key.name === 'up')
|
|
485
|
+
this.logScroll = Math.min(maxScroll, this.logScroll + 1);
|
|
486
|
+
else if (key.name === 'down')
|
|
487
|
+
this.logScroll = Math.max(0, this.logScroll - 1);
|
|
488
|
+
else if (key.name === 'pageup')
|
|
489
|
+
this.logScroll = Math.min(maxScroll, this.logScroll + 10);
|
|
490
|
+
else if (key.name === 'pagedown')
|
|
491
|
+
this.logScroll = Math.max(0, this.logScroll - 10);
|
|
492
|
+
else if (key.name === 'home')
|
|
493
|
+
this.logScroll = maxScroll;
|
|
494
|
+
else if (key.name === 'end')
|
|
495
|
+
this.logScroll = 0;
|
|
496
|
+
this.queueRender();
|
|
497
|
+
}
|
|
498
|
+
handleScrollKey(key, field) {
|
|
499
|
+
if (key.name === 'up')
|
|
500
|
+
this[field] = Math.max(0, this[field] - 1);
|
|
501
|
+
else if (key.name === 'down')
|
|
502
|
+
this[field] = this[field] + 1;
|
|
503
|
+
else if (key.name === 'pageup')
|
|
504
|
+
this[field] = Math.max(0, this[field] - 10);
|
|
505
|
+
else if (key.name === 'pagedown')
|
|
506
|
+
this[field] = this[field] + 10;
|
|
507
|
+
else if (key.name === 'home')
|
|
508
|
+
this[field] = 0;
|
|
509
|
+
this.queueRender();
|
|
510
|
+
}
|
|
511
|
+
async submitLine() {
|
|
512
|
+
const text = this.inputLine.trim();
|
|
513
|
+
this.inputLine = '';
|
|
514
|
+
this.cursor = 0;
|
|
515
|
+
this.historyIndex = null;
|
|
516
|
+
this.queueRender();
|
|
517
|
+
if (!text)
|
|
518
|
+
return;
|
|
519
|
+
this.history.push(text);
|
|
520
|
+
if (this.history.length > 100)
|
|
521
|
+
this.history.shift();
|
|
522
|
+
const firstHead = this.formatHead(chalk.cyan(`❯ ${this.config.prompt}`));
|
|
523
|
+
const contHead = this.formatCont();
|
|
524
|
+
for (const [i, line] of text.split('\n').entries()) {
|
|
525
|
+
this.chatLines.push((i === 0 ? firstHead : contHead) + line);
|
|
526
|
+
}
|
|
527
|
+
this.trimChat();
|
|
528
|
+
// 指令解析已统一到全局 inbound:command 相位(plugin-commands)。
|
|
529
|
+
// 适配器不再内联解析:未注册命令被放行为普通消息进入 agent,命中命令
|
|
530
|
+
// 由该相位执行并经 outbound:message 回送渲染到 TUI,与 onebot/webui 一致。
|
|
531
|
+
// shutdown/restart 的 TUI 清理由 ctx.onDispose(() => this.stop()) 兜底。
|
|
532
|
+
// userId 'console':本地终端身份(物理访问 = 运维者本人),命中 authority 的
|
|
533
|
+
// cli:console owner 快速通道;缺省 userId 会被当成匿名回退 defaultAuthority。
|
|
534
|
+
await this.ctx.emit('inbound:message', {
|
|
535
|
+
content: text,
|
|
536
|
+
sessionId: this.sessionId,
|
|
537
|
+
platform: 'cli',
|
|
538
|
+
userId: 'console',
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
recallHistory(delta) {
|
|
542
|
+
if (this.history.length === 0)
|
|
543
|
+
return;
|
|
544
|
+
if (this.historyIndex === null) {
|
|
545
|
+
if (delta > 0)
|
|
546
|
+
return;
|
|
547
|
+
this.historyIndex = this.history.length - 1;
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
this.historyIndex += delta;
|
|
551
|
+
if (this.historyIndex < 0)
|
|
552
|
+
this.historyIndex = 0;
|
|
553
|
+
if (this.historyIndex >= this.history.length) {
|
|
554
|
+
this.historyIndex = null;
|
|
555
|
+
this.inputLine = '';
|
|
556
|
+
this.cursor = 0;
|
|
557
|
+
this.queueRender();
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
this.inputLine = this.history[this.historyIndex];
|
|
562
|
+
this.cursor = this.inputLine.length;
|
|
563
|
+
this.queueRender();
|
|
564
|
+
}
|
|
565
|
+
askConfirm(text) {
|
|
566
|
+
this.confirmText = text;
|
|
567
|
+
this.queueRender();
|
|
568
|
+
return new Promise(resolve => {
|
|
569
|
+
this.confirmResolver = resolve;
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
switchView(view) {
|
|
573
|
+
if (this.view !== view) {
|
|
574
|
+
this.previousView = this.view;
|
|
575
|
+
this.view = view;
|
|
576
|
+
this.persistLastView(view);
|
|
577
|
+
}
|
|
578
|
+
this.queueRender();
|
|
579
|
+
}
|
|
580
|
+
persistLastView(view) {
|
|
581
|
+
if (view === 'help')
|
|
582
|
+
return;
|
|
583
|
+
const pluginConfig = this.ctx.config.getPluginConfig(name);
|
|
584
|
+
this.ctx.config.setPluginConfig(name, { ...pluginConfig, lastView: view });
|
|
585
|
+
this.ctx.getService('app')?.saveConfig();
|
|
586
|
+
}
|
|
587
|
+
trimChat() {
|
|
588
|
+
if (this.chatLines.length > 300)
|
|
589
|
+
this.chatLines.splice(0, this.chatLines.length - 300);
|
|
590
|
+
}
|
|
591
|
+
queueRender = () => {
|
|
592
|
+
if (this.renderQueued)
|
|
593
|
+
return;
|
|
594
|
+
this.renderQueued = true;
|
|
595
|
+
setImmediate(() => {
|
|
596
|
+
this.renderQueued = false;
|
|
597
|
+
this.render();
|
|
598
|
+
});
|
|
599
|
+
};
|
|
600
|
+
render() {
|
|
601
|
+
if (!this.running)
|
|
602
|
+
return;
|
|
603
|
+
const width = Math.max(40, output.columns || 100);
|
|
604
|
+
const height = Math.max(14, output.rows || 30);
|
|
605
|
+
// 输入框可变高度(多行输入):内容行数 + 上下边框,最多 8 行内容
|
|
606
|
+
const inputContentLines = this.computeInputDisplayLines(width);
|
|
607
|
+
const inputBoxHeight = inputContentLines.length + 2;
|
|
608
|
+
// 布局:header(1) + sep(1) + body + inputBox(inputBoxHeight) + footer(1)
|
|
609
|
+
const bodyHeight = Math.max(3, height - 3 - inputBoxHeight);
|
|
610
|
+
const out = [];
|
|
611
|
+
out.push(this.renderHeader(width));
|
|
612
|
+
out.push(chalk.gray(LINE_H.repeat(width)));
|
|
613
|
+
out.push(...this.renderBody(width, bodyHeight));
|
|
614
|
+
out.push(...this.renderInputBox(width, inputContentLines));
|
|
615
|
+
out.push(this.renderFooter(width));
|
|
616
|
+
output.write('\x1b[?25l\x1b[H');
|
|
617
|
+
output.write(out.map(line => clearLine(line, width)).join('\n'));
|
|
618
|
+
if (this.view === 'chat' && !this.confirmText) {
|
|
619
|
+
// 计算光标在多行输入中的 (row, col)
|
|
620
|
+
const { row: cRow, col: cCol } = this.cursorPosInInput(width);
|
|
621
|
+
// 行号布局(1-based):1=header, 2=sep, 3..2+bodyHeight=body, 之后是 inputBox(顶/中.../底), 最后是 footer
|
|
622
|
+
const inputMidStartRow = 2 + bodyHeight + 1 + 1; // header+sep+body+boxTop = 1+1+bodyHeight+1,再 +1 进入第一行内容
|
|
623
|
+
const screenRow = inputMidStartRow + cRow;
|
|
624
|
+
const promptLen = cRow === 0 ? visibleLen(this.makePrompt()) : visibleLen(this.makeContPrompt());
|
|
625
|
+
const screenCol = 2 /* │ 之后 */ + promptLen + cCol;
|
|
626
|
+
output.write(`\x1b[${screenRow};${screenCol}H\x1b[?25h`);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
renderHeader(width) {
|
|
630
|
+
const persona = this.ctx.getService('persona')?.getPersonaName() ?? 'default';
|
|
631
|
+
const left = ` ${chalk.bold.magenta('●')} ${chalk.bold('Aalis')} ${chalk.gray('·')} ${chalk.cyan(persona)} `;
|
|
632
|
+
const tabs = ['chat', 'logs', 'status', 'help']
|
|
633
|
+
.map(v => {
|
|
634
|
+
const label = v.toUpperCase();
|
|
635
|
+
return v === this.view ? chalk.bold.cyan(`[${label}]`) : chalk.gray(` ${label} `);
|
|
636
|
+
})
|
|
637
|
+
.join(' ');
|
|
638
|
+
const status = this.confirmResolver ? chalk.yellow('● confirm') : chalk.green('● online');
|
|
639
|
+
const right = ` ${tabs} ${status} `;
|
|
640
|
+
const pad = Math.max(1, width - visibleLen(left) - visibleLen(right));
|
|
641
|
+
return left + ' '.repeat(pad) + right;
|
|
642
|
+
}
|
|
643
|
+
renderBody(width, height) {
|
|
644
|
+
const raw = this.getBodyLines(width, height);
|
|
645
|
+
// 应用滚动 / 取末尾
|
|
646
|
+
let visible;
|
|
647
|
+
if (this.view === 'chat') {
|
|
648
|
+
visible = raw.slice(-height);
|
|
649
|
+
}
|
|
650
|
+
else if (this.view === 'logs') {
|
|
651
|
+
// 限制 logScroll,使最顶端日志固定在窗口顶部后无法继续向上滚动
|
|
652
|
+
// (否则会出现"内容从下往上消失"的视觉错觉)
|
|
653
|
+
const maxLogScroll = Math.max(0, raw.length - height);
|
|
654
|
+
if (this.logScroll > maxLogScroll)
|
|
655
|
+
this.logScroll = maxLogScroll;
|
|
656
|
+
const end = Math.max(0, raw.length - this.logScroll);
|
|
657
|
+
visible = raw.slice(Math.max(0, end - height), end);
|
|
658
|
+
}
|
|
659
|
+
else {
|
|
660
|
+
const scroll = this.view === 'status' ? this.statusScroll : this.helpScroll;
|
|
661
|
+
const maxScroll = Math.max(0, raw.length - height);
|
|
662
|
+
const offset = Math.min(scroll, maxScroll);
|
|
663
|
+
visible = raw.slice(offset, offset + height);
|
|
664
|
+
}
|
|
665
|
+
while (visible.length < height)
|
|
666
|
+
visible.push('');
|
|
667
|
+
return visible.slice(0, height).map(line => clipAnsi(line, width));
|
|
668
|
+
}
|
|
669
|
+
getBodyLines(width, _height) {
|
|
670
|
+
if (this.view === 'logs')
|
|
671
|
+
return this.getLogViewLines(width);
|
|
672
|
+
if (this.view === 'status')
|
|
673
|
+
return this.getStatusViewLines();
|
|
674
|
+
if (this.view === 'help')
|
|
675
|
+
return this.getHelpViewLines();
|
|
676
|
+
return this.getChatViewLines(width);
|
|
677
|
+
}
|
|
678
|
+
getChatViewLines(width) {
|
|
679
|
+
const lines = [];
|
|
680
|
+
const inner = width - 2; // 缩进 2 列
|
|
681
|
+
for (const raw of this.chatLines) {
|
|
682
|
+
// 宽度感知截断为单行;超长内容直接尾部省略。
|
|
683
|
+
lines.push(` ${clipAnsi(raw, inner)}`);
|
|
684
|
+
}
|
|
685
|
+
return lines;
|
|
686
|
+
}
|
|
687
|
+
getLogViewLines(width) {
|
|
688
|
+
const inner = width - 2;
|
|
689
|
+
// 与 console 输出格式保持一致:ts LEVEL scope message
|
|
690
|
+
const lines = [];
|
|
691
|
+
for (const entry of this.logLines) {
|
|
692
|
+
// LogEntry.timestamp 是完整 ISO,CLI 只需 HH:mm:ss.sss
|
|
693
|
+
const ts = chalk.gray(entry.timestamp.slice(11, 23));
|
|
694
|
+
const level = LEVEL_TAG[entry.level];
|
|
695
|
+
const scope = chalk.magenta(entry.scope);
|
|
696
|
+
const head = `${ts} ${level} ${scope} `;
|
|
697
|
+
const headW = visibleLen(head);
|
|
698
|
+
const msgW = Math.max(1, inner - headW);
|
|
699
|
+
if (!this.logWrap) {
|
|
700
|
+
// 默认:压成单行展示(避免 alternate screen 中跨行覆盖)
|
|
701
|
+
const flat = sanitizeForSingleLine(entry.message);
|
|
702
|
+
const msg = stringWidth(flat) <= msgW ? flat : clipExact(flat, msgW);
|
|
703
|
+
lines.push(` ${head}${msg}`);
|
|
704
|
+
continue;
|
|
705
|
+
}
|
|
706
|
+
// 换行模式:保留真实换行 + 按宽度软折行;每个续行用 contHead 缩进对齐到消息列
|
|
707
|
+
const contHead = ' '.repeat(headW);
|
|
708
|
+
const rawLines = entry.message
|
|
709
|
+
.replace(/\r\n|\r/g, '\n')
|
|
710
|
+
.replace(/\t/g, ' ')
|
|
711
|
+
.split('\n');
|
|
712
|
+
let isFirst = true;
|
|
713
|
+
for (const raw of rawLines) {
|
|
714
|
+
// 按可见宽度软折行
|
|
715
|
+
const wrapped = wrapByVisibleWidth(raw, msgW);
|
|
716
|
+
const segs = wrapped.length > 0 ? wrapped : [''];
|
|
717
|
+
for (const seg of segs) {
|
|
718
|
+
const prefix = isFirst ? head : contHead;
|
|
719
|
+
lines.push(` ${prefix}${seg}`);
|
|
720
|
+
isFirst = false;
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
return lines;
|
|
725
|
+
}
|
|
726
|
+
getStatusViewLines() {
|
|
727
|
+
const services = this.ctx.getServiceNames();
|
|
728
|
+
const platform = this.ctx.getService('platform', ['cli']);
|
|
729
|
+
const connections = platform?.getConnections?.() ?? [];
|
|
730
|
+
const persona = this.ctx.getService('persona')?.getPersonaName() ?? '-';
|
|
731
|
+
const sec = (t) => chalk.bold.cyan(`▎ ${t}`);
|
|
732
|
+
const kv = (k, v) => ` ${chalk.gray(k.padEnd(14))} ${v}`;
|
|
733
|
+
const out = [];
|
|
734
|
+
out.push(sec('运行时'));
|
|
735
|
+
out.push(kv('persona', persona));
|
|
736
|
+
out.push(kv('cli session', this.sessionId));
|
|
737
|
+
out.push(kv('log buffer', `${this.logLines.length} 条`));
|
|
738
|
+
out.push('');
|
|
739
|
+
out.push(sec(`服务 (${services.length})`));
|
|
740
|
+
for (const s of services)
|
|
741
|
+
out.push(` ${chalk.green('●')} ${s}`);
|
|
742
|
+
out.push('');
|
|
743
|
+
out.push(sec(`平台连接 (${connections.length})`));
|
|
744
|
+
if (connections.length === 0)
|
|
745
|
+
out.push(` ${chalk.gray('— 无')}`);
|
|
746
|
+
else
|
|
747
|
+
for (const c of connections) {
|
|
748
|
+
const dot = c.status === 'online' ? chalk.green('●') : c.status === 'connecting' ? chalk.yellow('●') : chalk.red('●');
|
|
749
|
+
out.push(` ${dot} ${chalk.cyan(c.platform)}:${c.id} ${chalk.gray(c.status)}`);
|
|
750
|
+
}
|
|
751
|
+
return out.map(l => (l.length === 0 ? '' : ` ${l}`));
|
|
752
|
+
}
|
|
753
|
+
getHelpViewLines() {
|
|
754
|
+
const sec = (t) => chalk.bold.cyan(`▎ ${t}`);
|
|
755
|
+
const row = (k, v) => ` ${chalk.cyan(k.padEnd(10))} ${chalk.gray(v)}`;
|
|
756
|
+
const out = [];
|
|
757
|
+
out.push(sec('视图切换'));
|
|
758
|
+
out.push(row('Ctrl+T', 'Chat · 聊天 / 命令输入'));
|
|
759
|
+
out.push(row('Ctrl+L', 'Logs · 实时日志'));
|
|
760
|
+
out.push(row('Ctrl+S', 'Status · 服务与平台状态'));
|
|
761
|
+
out.push(row('Ctrl+G', 'Help · 当前页'));
|
|
762
|
+
out.push(row('Esc', '返回上一个视图'));
|
|
763
|
+
out.push(row('Ctrl+C', '退出'));
|
|
764
|
+
out.push('');
|
|
765
|
+
out.push(sec('滚动 (Logs / Status / Help)'));
|
|
766
|
+
out.push(row('↑ / ↓', '逐行滚动'));
|
|
767
|
+
out.push(row('PgUp/Dn', '翻页'));
|
|
768
|
+
out.push(row('Home', '回到顶部'));
|
|
769
|
+
out.push(row('Ctrl+W', '日志页:切换换行模式(多行完整展示)'));
|
|
770
|
+
out.push('');
|
|
771
|
+
out.push(sec('编辑'));
|
|
772
|
+
out.push(row('Enter', '提交输入'));
|
|
773
|
+
out.push(row('Ctrl+J', '插入换行(macOS Ctrl+Enter)'));
|
|
774
|
+
out.push(row('Shift+Ent', '插入换行(如终端支持)'));
|
|
775
|
+
out.push(row('↑ / ↓', '历史记录回溯(chat 视图)'));
|
|
776
|
+
out.push('');
|
|
777
|
+
out.push(sec('提示'));
|
|
778
|
+
out.push(` ${chalk.gray('• 完整日志写入 data/latest.log(每次启动覆盖);可用 tail -f 查看。')}`);
|
|
779
|
+
out.push(` ${chalk.gray('• 退出时自动恢复原终端内容(alternate screen)。')}`);
|
|
780
|
+
out.push(` ${chalk.gray('• 输入以 / 开头会按命令解析,否则发给 agent。')}`);
|
|
781
|
+
out.push(` ${chalk.gray('• 鼠标滚轮可滚动 Logs / Status / Help。')}`);
|
|
782
|
+
out.push(` ${chalk.gray(`• 选择 / 复制文本:${selectionHint()}`)}`);
|
|
783
|
+
return out.map(l => (l.length === 0 ? '' : ` ${l}`));
|
|
784
|
+
}
|
|
785
|
+
/** 计算输入框的多行内容(不含边框、不含 padding) */
|
|
786
|
+
computeInputDisplayLines(width) {
|
|
787
|
+
const inner = width - 2;
|
|
788
|
+
if (this.confirmText)
|
|
789
|
+
return [`${chalk.yellow('?')} ${this.confirmText}`];
|
|
790
|
+
if (this.view !== 'chat') {
|
|
791
|
+
const total = this.view === 'logs'
|
|
792
|
+
? this.logLines.length
|
|
793
|
+
: this.view === 'status'
|
|
794
|
+
? this.getStatusViewLines().length
|
|
795
|
+
: this.getHelpViewLines().length;
|
|
796
|
+
const scroll = this.view === 'logs' ? this.logScroll : this.view === 'status' ? this.statusScroll : this.helpScroll;
|
|
797
|
+
return [chalk.gray(`${this.view} · ${total} 行 · scroll ${scroll} · 按 Ctrl+T 回到聊天`)];
|
|
798
|
+
}
|
|
799
|
+
const inputLines = this.inputLine.split('\n');
|
|
800
|
+
const display = [];
|
|
801
|
+
const promptLen = visibleLen(this.makePrompt());
|
|
802
|
+
const contLen = visibleLen(this.makeContPrompt());
|
|
803
|
+
const maxBody = Math.max(1, inner - Math.max(promptLen, contLen));
|
|
804
|
+
for (let i = 0; i < inputLines.length; i++) {
|
|
805
|
+
const head = i === 0 ? this.makePrompt() : this.makeContPrompt();
|
|
806
|
+
// 宽度感知截断(CJK / emoji 占 2 列),不加省略号以免误导
|
|
807
|
+
const body = clipExact(inputLines[i], maxBody);
|
|
808
|
+
display.push(head + body);
|
|
809
|
+
}
|
|
810
|
+
// 限制最多 8 行
|
|
811
|
+
if (display.length > 8)
|
|
812
|
+
return display.slice(-8);
|
|
813
|
+
return display;
|
|
814
|
+
}
|
|
815
|
+
/** 根据 cursor 索引计算其在多行输入中的 (row, col),col 为终端可见列宽 */
|
|
816
|
+
cursorPosInInput(_width) {
|
|
817
|
+
if (this.view !== 'chat' || this.confirmText)
|
|
818
|
+
return { row: 0, col: 0 };
|
|
819
|
+
const before = this.inputLine.slice(0, this.cursor);
|
|
820
|
+
const lines = before.split('\n');
|
|
821
|
+
return { row: lines.length - 1, col: stringWidth(lines[lines.length - 1]) };
|
|
822
|
+
}
|
|
823
|
+
renderInputBox(width, contentLines) {
|
|
824
|
+
const inner = width - 2;
|
|
825
|
+
const top = chalk.gray(`${BOX_TL}${LINE_H.repeat(inner)}${BOX_TR}`);
|
|
826
|
+
const mid = contentLines.map(line => `${chalk.gray(BOX_V)}${padAnsi(line, inner)}${chalk.gray(BOX_V)}`);
|
|
827
|
+
const bot = chalk.gray(`${BOX_BL}${LINE_H.repeat(inner)}${BOX_BR}`);
|
|
828
|
+
return [top, ...mid, bot];
|
|
829
|
+
}
|
|
830
|
+
makePrompt() {
|
|
831
|
+
return `${chalk.cyan('❯')} ${chalk.bold(this.config.prompt)} `;
|
|
832
|
+
}
|
|
833
|
+
makeContPrompt() {
|
|
834
|
+
return `${chalk.gray('…')} ${' '.repeat(this.config.prompt.length)} `;
|
|
835
|
+
}
|
|
836
|
+
renderFooter(width) {
|
|
837
|
+
const baseItems = [
|
|
838
|
+
`${chalk.cyan('^T')} chat`,
|
|
839
|
+
`${chalk.cyan('^L')} logs`,
|
|
840
|
+
`${chalk.cyan('^S')} status`,
|
|
841
|
+
`${chalk.cyan('^G')} help`,
|
|
842
|
+
`${chalk.cyan('Esc')} back`,
|
|
843
|
+
`${chalk.cyan('^C')} exit`,
|
|
844
|
+
];
|
|
845
|
+
if (this.view === 'logs') {
|
|
846
|
+
baseItems.push(`${chalk.cyan('^W')} wrap:${this.logWrap ? chalk.green('on') : chalk.gray('off')}`);
|
|
847
|
+
}
|
|
848
|
+
const items = baseItems.join(chalk.gray(' · '));
|
|
849
|
+
const left = ` ${items} `;
|
|
850
|
+
return padAnsi(chalk.gray.dim(left), width);
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
// ===== 视觉常量 / 工具 =====
|
|
854
|
+
const LINE_H = '─';
|
|
855
|
+
const BOX_TL = '╭';
|
|
856
|
+
const BOX_TR = '╮';
|
|
857
|
+
const BOX_BL = '╰';
|
|
858
|
+
const BOX_BR = '╯';
|
|
859
|
+
const BOX_V = '│';
|
|
860
|
+
const LEVEL_TAG = {
|
|
861
|
+
debug: chalk.gray('DEBUG'),
|
|
862
|
+
info: chalk.cyan('INFO '),
|
|
863
|
+
warn: chalk.yellow('WARN '),
|
|
864
|
+
error: chalk.red('ERROR'),
|
|
865
|
+
};
|
|
866
|
+
/**
|
|
867
|
+
* 兜底恢复终端状态:进程在 TUI 启动后异常退出时,Context dispose 可能来不及执行。
|
|
868
|
+
* 这里关闭鼠标上报、恢复光标、退出备用屏,并关闭 raw mode。
|
|
869
|
+
*/
|
|
870
|
+
function restoreTerminalState() {
|
|
871
|
+
try {
|
|
872
|
+
if (input.isTTY)
|
|
873
|
+
input.setRawMode(false);
|
|
874
|
+
}
|
|
875
|
+
catch {
|
|
876
|
+
/* ignore */
|
|
877
|
+
}
|
|
878
|
+
try {
|
|
879
|
+
output.write('\x1b[?1006l\x1b[?1000l\x1b[?1007l\x1b[?25h\x1b[?1049l');
|
|
880
|
+
}
|
|
881
|
+
catch {
|
|
882
|
+
/* ignore */
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
/** 终端可见宽度(处理 ANSI / CJK / emoji / 零宽字符) */
|
|
886
|
+
function visibleLen(s) {
|
|
887
|
+
return stringWidth(s);
|
|
888
|
+
}
|
|
889
|
+
/** 按终端列宽截断(保留 ANSI 颜色),尾部加省略号 */
|
|
890
|
+
function clipAnsi(s, width) {
|
|
891
|
+
if (width <= 0)
|
|
892
|
+
return '';
|
|
893
|
+
if (stringWidth(s) <= width)
|
|
894
|
+
return s;
|
|
895
|
+
return cliTruncate(s, width, { position: 'end', preferTruncationOnSpace: false });
|
|
896
|
+
}
|
|
897
|
+
/** 按终端列宽截断(保留 ANSI 颜色),不加省略号 — 用于输入框等所见即所得场景 */
|
|
898
|
+
function clipExact(s, width) {
|
|
899
|
+
if (width <= 0)
|
|
900
|
+
return '';
|
|
901
|
+
if (stringWidth(s) <= width)
|
|
902
|
+
return s;
|
|
903
|
+
return cliTruncate(s, width, { position: 'end', preferTruncationOnSpace: false, truncationCharacter: '' });
|
|
904
|
+
}
|
|
905
|
+
/**
|
|
906
|
+
* 把单行字符串按可见宽度软折行(CJK 算 2 列,emoji/ANSI 不破坏)。
|
|
907
|
+
* 返回若干段,每段宽度 ≤ width。空字符串返回 [''] 以保留视觉空行。
|
|
908
|
+
*/
|
|
909
|
+
function wrapByVisibleWidth(s, width) {
|
|
910
|
+
if (width <= 0)
|
|
911
|
+
return [s];
|
|
912
|
+
if (stringWidth(s) <= width)
|
|
913
|
+
return [s];
|
|
914
|
+
const segs = [];
|
|
915
|
+
let remaining = s;
|
|
916
|
+
// 防御:极端长字符串避免无限循环
|
|
917
|
+
while (remaining.length > 0 && segs.length < 1000) {
|
|
918
|
+
if (stringWidth(remaining) <= width) {
|
|
919
|
+
segs.push(remaining);
|
|
920
|
+
break;
|
|
921
|
+
}
|
|
922
|
+
// cli-truncate 在 width 处截断,得到第一段
|
|
923
|
+
const head = cliTruncate(remaining, width, {
|
|
924
|
+
position: 'end',
|
|
925
|
+
preferTruncationOnSpace: false,
|
|
926
|
+
truncationCharacter: '',
|
|
927
|
+
});
|
|
928
|
+
if (!head)
|
|
929
|
+
break;
|
|
930
|
+
segs.push(head);
|
|
931
|
+
// 计算消耗的字符数:以可见宽度对齐,逐字符切到与 head 同等宽度
|
|
932
|
+
let consumed = 0;
|
|
933
|
+
let acc = 0;
|
|
934
|
+
for (const ch of remaining) {
|
|
935
|
+
acc += stringWidth(ch);
|
|
936
|
+
consumed += ch.length;
|
|
937
|
+
if (acc >= stringWidth(head))
|
|
938
|
+
break;
|
|
939
|
+
}
|
|
940
|
+
remaining = remaining.slice(consumed);
|
|
941
|
+
}
|
|
942
|
+
return segs.length > 0 ? segs : [''];
|
|
943
|
+
}
|
|
944
|
+
/** 按终端列宽右侧补空格 */
|
|
945
|
+
function padAnsi(s, width) {
|
|
946
|
+
const w = stringWidth(s);
|
|
947
|
+
if (w >= width)
|
|
948
|
+
return clipAnsi(s, width);
|
|
949
|
+
return s + ' '.repeat(width - w);
|
|
950
|
+
}
|
|
951
|
+
/** 行尾补宽 + \x1b[K 清残影 */
|
|
952
|
+
function clearLine(s, width) {
|
|
953
|
+
return `${padAnsi(s, width)}\x1b[K`;
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
* 清洗多行 / 含控制字符的日志消息,使之可安全渲染到 alternate screen 单行内。
|
|
957
|
+
* - \r\n / \r / \n 一律折叠为 ' ↵ '(可见的回车标记)
|
|
958
|
+
* - \t 换为 4 个空格
|
|
959
|
+
* - 其它 C0 控制字符(\x00-\x1F 除 \x1b 颜色序列)剔除
|
|
960
|
+
*/
|
|
961
|
+
function sanitizeForSingleLine(s) {
|
|
962
|
+
return (s
|
|
963
|
+
.replace(/\r\n|\r|\n/g, ' \u21b5 ')
|
|
964
|
+
.replace(/\t/g, ' ')
|
|
965
|
+
// 保留 ESC(颜色),剔除其它 C0 控制字符
|
|
966
|
+
// biome-ignore lint/suspicious/noControlCharactersInRegex: 需要按字面匹配 C0 控制字符以清洗终端输入
|
|
967
|
+
.replace(/[\x00-\x08\x0B\x0C\x0E-\x1A\x1C-\x1F]/g, ''));
|
|
968
|
+
}
|
|
969
|
+
/** 不同平台终端绕过鼠标上报、回到原生选择/复制的指引 */
|
|
970
|
+
function selectionHint() {
|
|
971
|
+
switch (process.platform) {
|
|
972
|
+
case 'darwin':
|
|
973
|
+
return '按住 Option(⌥)拖拽选择,再用 ⌘C 复制(iTerm2 / Terminal.app / VS Code 终端通用)';
|
|
974
|
+
case 'win32':
|
|
975
|
+
return 'Windows Terminal 按住 Shift 拖拽选择,右键复制;ConEmu 按住 Alt 拖拽';
|
|
976
|
+
case 'linux':
|
|
977
|
+
return 'GNOME/Konsole/xterm 按住 Shift 拖拽选择,再用 Ctrl+Shift+C 复制';
|
|
978
|
+
default:
|
|
979
|
+
return '按住 Shift(多数终端)或 Option(macOS)拖拽即可绕过鼠标上报';
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-file.d.ts","sourceRoot":"","sources":["../src/log-file.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,QAAQ,EAAgB,MAAM,aAAa,CAAC;AAI1D,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAUxE"}
|
package/dist/log-file.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// data/latest.log 是 runtime 约定的"持久化日志单一数据源"(每次启动覆盖);
|
|
2
|
+
// CLI 启动时尾读它来恢复 boot 期早期日志(plugin apply 时 LogHub 已 emit 过若干
|
|
3
|
+
// 早期 entry 但 CLI 还未订阅)。与 webui-server 走相同契约,避免插件直连 runtime。
|
|
4
|
+
import { existsSync } from 'node:fs';
|
|
5
|
+
import { readFile } from 'node:fs/promises';
|
|
6
|
+
import { resolve } from 'node:path';
|
|
7
|
+
import { parseLogLine } from '@aalis/core';
|
|
8
|
+
const LOG_FILE_PATH = resolve(process.cwd(), 'data/latest.log');
|
|
9
|
+
export async function readLogFileTail(limit) {
|
|
10
|
+
if (!existsSync(LOG_FILE_PATH))
|
|
11
|
+
return [];
|
|
12
|
+
const raw = await readFile(LOG_FILE_PATH, 'utf8');
|
|
13
|
+
const out = [];
|
|
14
|
+
for (const line of raw.split('\n')) {
|
|
15
|
+
if (!line)
|
|
16
|
+
continue;
|
|
17
|
+
const entry = parseLogLine(line);
|
|
18
|
+
if (entry)
|
|
19
|
+
out.push(entry);
|
|
20
|
+
}
|
|
21
|
+
return out.slice(-limit);
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=log-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-file.js","sourceRoot":"","sources":["../src/log-file.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,4DAA4D;AAC5D,4DAA4D;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAiB,YAAY,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,iBAAiB,CAAC,CAAC;AAEhE,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAa;IACjD,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;QAAE,OAAO,EAAE,CAAC;IAC1C,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAClD,MAAM,GAAG,GAAe,EAAE,CAAC;IAC3B,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,KAAK;YAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI 服务 —— 命令行交互界面
|
|
3
|
+
*
|
|
4
|
+
* 提供终端 REPL 交互,支持指令输入和对话。
|
|
5
|
+
* 核心要求此服务必须运行。
|
|
6
|
+
* 默认由 plugin-cli 提供,第三方可提供自己的 CLI 实现。
|
|
7
|
+
*/
|
|
8
|
+
export interface CLIService {
|
|
9
|
+
/** 获取当前会话 ID */
|
|
10
|
+
getSessionId(): string;
|
|
11
|
+
/** CLI 是否正在运行 */
|
|
12
|
+
isRunning(): boolean;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,gBAAgB;IAChB,YAAY,IAAI,MAAM,CAAC;IACvB,iBAAiB;IACjB,SAAS,IAAI,OAAO,CAAC;CACtB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,uBAAuB"}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aalis/plugin-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"aalis-plugin"
|
|
7
|
+
],
|
|
8
|
+
"main": "dist/index.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"chalk": "^5.4.0",
|
|
15
|
+
"cli-truncate": "^6.0.0",
|
|
16
|
+
"string-width": "^8.2.0"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@types/node": "^22.0.0",
|
|
20
|
+
"typescript": "^5.7.0",
|
|
21
|
+
"@aalis/core": "0.1.0",
|
|
22
|
+
"@aalis/plugin-message-api": "0.1.0",
|
|
23
|
+
"@aalis/plugin-authority-api": "0.1.0",
|
|
24
|
+
"@aalis/plugin-persona-api": "0.1.0",
|
|
25
|
+
"@aalis/plugin-platform-api": "0.1.0"
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"@aalis/core": "^0.1.0"
|
|
29
|
+
},
|
|
30
|
+
"aalis": {
|
|
31
|
+
"service": {
|
|
32
|
+
"optional": [
|
|
33
|
+
"llm",
|
|
34
|
+
"authority",
|
|
35
|
+
"commands"
|
|
36
|
+
],
|
|
37
|
+
"provides": [
|
|
38
|
+
"cli",
|
|
39
|
+
"platform"
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsc",
|
|
45
|
+
"dev": "tsc --watch"
|
|
46
|
+
}
|
|
47
|
+
}
|