🌱 EMRG 刚刚完成一次自我进化!
diff --git a/emrg/gui/renderer/js/app.js b/emrg/gui/renderer/js/app.js
index 540f294..7e4ecbf 100644
--- a/emrg/gui/renderer/js/app.js
+++ b/emrg/gui/renderer/js/app.js
@@ -222,11 +222,11 @@ const App = (() => {
break;
case "/sessions":
case "/resume":
- // P2:/resume
直接切换;无参数 → 会话列表对话框
+ // P2:/resume 直接切换;无参数 → 现代两步弹窗(rant 14:10:14 P6:sessions-dialog 移除,侧边栏会话区 + /open 已覆盖)
if (parsed.args.length > 0) {
await switchSession(parsed.args[0]);
} else {
- showSessionsDialog();
+ Dialogs.showOpenSessionDialog();
}
break;
case "/open":
@@ -271,11 +271,12 @@ const App = (() => {
showSkillsDialog();
break;
case "/rant":
- // P4:/rant 直接跟内容 → 快速提交;无参数 → 进化对话框
+ // P4:/rant 直接跟内容 → 快速提交;无参数 → 打开 Rant 面板 + 新建表单(rant 14:10:14 P6:rant-dialog 移除)
if (parsed.args.length > 0) {
await submitRant(parsed.args.join(" "), "");
} else {
- showRantDialog();
+ await openRantsPanel();
+ Dialogs.openRantForm();
}
break;
case "/trigger":
@@ -294,31 +295,6 @@ const App = (() => {
}
}
- // /sessions /resume:会话列表对话框(复用 help-list 样式)
- async function showSessionsDialog() {
- const list = $("sessions-list");
- const dialog = $("sessions-dialog");
- if (!list || !dialog) return;
- await refreshSessions(); // 确保 state.sessions 最新
- list.innerHTML = "";
- if (state.sessions.length === 0) {
- list.innerHTML = `${_t("app.helpNoSessions")}
`;
- }
- state.sessions.forEach((s) => {
- const row = el("button", { class: "help-row", type: "button", style: "width:100%;text-align:left;cursor:pointer;background:none;border:none;" });
- const name = el("span", { class: "help-cmd" }, s.title || _t("app.unnamed"));
- const hint = el("span", { class: "help-hint" }, s.session_id === state.sessionId ? _t("app.current") : "");
- row.appendChild(name);
- row.appendChild(hint);
- row.addEventListener("click", async () => {
- dialog.close();
- await switchSession(s.session_id);
- });
- list.appendChild(row);
- });
- dialog.showModal();
- }
-
// /rewind:历史消息点选择对话框(daemon list_history → 选择 → rewind_session)
async function showRewindDialog() {
const list = $("rewind-list");
@@ -446,26 +422,6 @@ const App = (() => {
}
}
- // /rant:进化对话框(项目下拉 + 文本输入 → daemon rant 协议)
- async function showRantDialog() {
- const dialog = $("rant-dialog");
- const msgInput = $("rant-message");
- const projSel = $("rant-project");
- if (!dialog || !msgInput) return;
- // 加载项目列表填充下拉
- try {
- const projects = await window.emrg.listProjects();
- projSel.innerHTML = ``;
- for (const p of projects) {
- const name = typeof p === "string" ? p : (p.name || "");
- if (name) projSel.appendChild(el("option", { value: name }, name));
- }
- } catch { /* 项目加载失败则只留全局项 */ }
- msgInput.value = "";
- dialog.showModal();
- msgInput.focus();
- }
-
async function submitRant(message, project) {
const text = String(message || "").trim();
if (!text) {
@@ -1545,17 +1501,10 @@ const App = (() => {
$("confirm-cancel").addEventListener("click", Dialogs.closeConfirm);
$("confirm-ok").addEventListener("click", Dialogs.confirmOk);
$("help-close").addEventListener("click", () => $("help-dialog").close());
- $("sessions-close").addEventListener("click", () => $("sessions-dialog").close());
$("rewind-close").addEventListener("click", () => $("rewind-dialog").close());
$("memory-close").addEventListener("click", () => $("memory-dialog").close());
$("skills-close").addEventListener("click", () => $("skills-dialog").close());
- $("rant-cancel").addEventListener("click", () => $("rant-dialog").close());
- $("rant-submit").addEventListener("click", async () => {
- const msg = $("rant-message")?.value || "";
- const proj = $("rant-project")?.value || "";
- $("rant-dialog").close();
- await submitRant(msg, proj);
- });
+ // rant 14:10:14 P6:sessions-dialog / rant-dialog 已移除(侧边栏会话区 + /open + Rant 面板覆盖)
// rant 14:10:14 P2:设置面板 tab 切换(模型服务/工作目录/GitHub/外观/语言/关于)
document.querySelectorAll("#settings-tabs .panel-tab").forEach((tab) => {
diff --git a/emrg/gui/test/app-commands.test.js b/emrg/gui/test/app-commands.test.js
index 550199e..3051089 100644
--- a/emrg/gui/test/app-commands.test.js
+++ b/emrg/gui/test/app-commands.test.js
@@ -46,6 +46,8 @@ function makeEl(id) {
if (frag) this.innerHTML += frag;
},
removeChild() {},
+ setAttribute() {},
+ removeAttribute() {},
querySelectorAll: () => [],
getBoundingClientRect: () => ({ left: 0, right: 100, top: 0, bottom: 100, width: 100, height: 100 }),
showModal() { this.__open = true; },
@@ -207,24 +209,29 @@ test("P3:/skills 打开技能列表对话框并调用 listSkills", async () =>
assert.ok(els["skills-dialog"] && els["skills-dialog"].__open === true, "skills dialog opened");
});
-test("P4:/rant 无参数打开进化对话框(项目下拉加载)", async () => {
+test("P4:/rant 无参数打开 Rant 面板 + 新建表单(rant 14:10:14 P6:rant-dialog 移除)", async () => {
const { ctx, els } = makeSandbox({
listProjects: async () => [{ name: "emrg" }],
sendRant: async () => ({ ok: true, count: 5 }),
});
await tick();
+ vm.runInContext('document.getElementById("rant-form").classList.add("hidden")', ctx); // 镜像 index.html 初始态
await vm.runInContext("App.handleCommand({ type: 'command', cmd: '/rant', args: [] })", ctx);
- assert.ok(els["rant-dialog"] && els["rant-dialog"].__open === true, "rant dialog opened");
+ await tick();
+ const panel = els["panel-rants"];
+ assert.ok(panel && !panel.classList.contains("hidden"), "rants panel should be open");
+ assert.ok(els["rant-form"] && !els["rant-form"].classList.contains("hidden"), "rant form should be open");
});
-test("P4:/rant 直接跟内容快速提交(不打开对话框)", async () => {
+test("P4:/rant 直接跟内容快速提交(不打开面板)", async () => {
const { ctx, els } = makeSandbox({
listProjects: async () => [{ name: "emrg" }],
sendRant: async () => ({ ok: true, count: 5 }),
});
await tick();
await vm.runInContext("App.handleCommand({ type: 'command', cmd: '/rant', args: ['希望支持主题切换'] })", ctx);
- assert.ok(!(els["rant-dialog"] && els["rant-dialog"].__open), "direct rant submit should not open dialog");
+ const panel = els["panel-rants"];
+ assert.ok(!(panel && !panel.classList.contains("hidden")), "direct rant submit should not open panel");
});
test("P4:/trigger 无参数打开任务面板", async () => {
diff --git a/emrg/gui/test/renderer.smoke.test.js b/emrg/gui/test/renderer.smoke.test.js
index 90dfefd..a489890 100644
--- a/emrg/gui/test/renderer.smoke.test.js
+++ b/emrg/gui/test/renderer.smoke.test.js
@@ -134,11 +134,9 @@ const ELEMENT_IDS = [
"model-list", "add-model-btn", "model-form", "model-form-name", "model-form-id",
"model-form-vision", "model-form-save", "model-form-cancel", "back-to-bottom",
"cmd-menu", "help-dialog", "help-list", "help-close",
- "sessions-dialog", "sessions-list", "sessions-close",
"rewind-dialog", "rewind-list", "rewind-close",
"memory-dialog", "memory-list", "memory-detail", "memory-close",
"skills-dialog", "skills-list", "skills-close",
- "rant-dialog", "rant-message", "rant-project", "rant-cancel", "rant-submit",
"result-panel", "result-list", "result-toggle",
"result-tabs", "result-tab-files", "result-tab-artifacts", "result-tabbar", "result-files", "result-viewer", "result-resizer",
"growth-card", "growth-count", "about-recent",