mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-08-14 15:10:20 +02:00
优化项目对话、刷新续流、实时滚动与工具状态恢复 (#245)
* feat(chat): add project-based conversation sidebar * feat(chat): refine Codex-style conversation UI * feat(chat): add Codex-style conversation workflow * feat(ui): 优化对话框与项目侧边栏交互 * fix(chat): 修复暗色输入框圆角填色 * fix(chat): 恢复输入区分层错位布局 * fix(hitl): isolate reviewer state per conversation * feat(hitl): 增加双入口审批与倒计时进度 * fix(hitl): 汇总项目审批并隔离对话状态 * fix(ui): 修复审批状态与无项目新任务 * fix(ui): 优化审批状态与对话切换性能 * fix(ui): 修复中断任务审批仍计时 * fix(ui): 修复多对话并发切换卡顿 * fix(hitl): 主动同步审批并关闭中断状态 * fix(ui): 固定项目审批汇总为绿色 * feat(ui): 同步系统模型与推理强度 * feat(ui): 完善项目侧栏预览与新建入口 * fix(ui): 防止无项目文件夹误展开 * fix(ui): 防止长历史对话滚动误触审批 * fix(ui): 修复对话操作并补充项目置顶 * fix(ui): 移除对话分组并调整项目置顶排序 * feat(ui): 优化迭代导航与审批交互 * fix(hitl): 将 write_file 加入内置免审批工具 * fix(chat): 支持回车发送与 Shift 回车换行 * fix(chat): 优化对话刷新与 Codex 风格交互 * fix(ui): 显示对话具体更新时间 * fix(ui): 优化对话刷新与项目加载 * fix(ui): 修复 Agent 审查文字裁切 * fix(chat): 修复刷新续流与多标签页同步 * fix(chat): 修复滚动跟随与中断任务终态 * fix(ui): 修复流式滚动跳动与工具状态恢复 * fix(ui): 修复刷新后流式输出停止粘底
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
const fs = require('node:fs');
|
||||
const vm = require('node:vm');
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
|
||||
const chat = fs.readFileSync('web/static/js/chat.js', 'utf8');
|
||||
|
||||
function functionSource(source, name, nextName) {
|
||||
const start = source.indexOf(`function ${name}(`);
|
||||
const end = source.indexOf(`function ${nextName}(`, start);
|
||||
assert.notEqual(start, -1, `${name} should exist`);
|
||||
assert.notEqual(end, -1, `${nextName} should follow ${name}`);
|
||||
return source.slice(start, end);
|
||||
}
|
||||
|
||||
function createKeydownHarness() {
|
||||
const context = {
|
||||
isComposing: false,
|
||||
mentionState: { active: false },
|
||||
mentionSuggestionsEl: null,
|
||||
sendCount: 0,
|
||||
sendMessage() {
|
||||
context.sendCount += 1;
|
||||
},
|
||||
};
|
||||
vm.runInNewContext(
|
||||
`${functionSource(chat, 'handleChatInputKeydown', 'updateMentionStateFromInput')}; this.handleChatInputKeydown = handleChatInputKeydown;`,
|
||||
context
|
||||
);
|
||||
return context;
|
||||
}
|
||||
|
||||
test('聊天输入框按 Enter 发送并阻止原生换行', () => {
|
||||
const context = createKeydownHarness();
|
||||
let prevented = false;
|
||||
|
||||
context.handleChatInputKeydown({
|
||||
key: 'Enter',
|
||||
shiftKey: false,
|
||||
isComposing: false,
|
||||
keyCode: 13,
|
||||
preventDefault() {
|
||||
prevented = true;
|
||||
},
|
||||
});
|
||||
|
||||
assert.equal(prevented, true);
|
||||
assert.equal(context.sendCount, 1);
|
||||
});
|
||||
|
||||
test('聊天输入框按 Shift+Enter 只换行且不发送', () => {
|
||||
const context = createKeydownHarness();
|
||||
let prevented = false;
|
||||
|
||||
context.handleChatInputKeydown({
|
||||
key: 'Enter',
|
||||
shiftKey: true,
|
||||
isComposing: false,
|
||||
keyCode: 13,
|
||||
preventDefault() {
|
||||
prevented = true;
|
||||
},
|
||||
});
|
||||
|
||||
assert.equal(prevented, false);
|
||||
assert.equal(context.sendCount, 0);
|
||||
});
|
||||
|
||||
test('输入法确认候选词时按 Enter 不会发送', () => {
|
||||
const context = createKeydownHarness();
|
||||
|
||||
context.handleChatInputKeydown({
|
||||
key: 'Enter',
|
||||
shiftKey: false,
|
||||
isComposing: true,
|
||||
keyCode: 229,
|
||||
preventDefault() {
|
||||
throw new Error('IME Enter should not be prevented');
|
||||
},
|
||||
});
|
||||
|
||||
assert.equal(context.sendCount, 0);
|
||||
});
|
||||
Reference in New Issue
Block a user