Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions emrg/gui/renderer/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -757,10 +757,10 @@ const App = (() => {
const items = (res && res.recent) || [];
recent.innerHTML = "";
if (items.length === 0) {
recent.appendChild(el("div", { class: "about-recent-item" }, "还没有改进记录,输入 /rant 驱动第一次进化吧"));
recent.appendChild(el("div", { class: "about-recent-item" }, _t("app.noImprovements")));
return;
}
const header = el("div", { class: "about-recent-title" }, "最近改进");
const header = el("div", { class: "about-recent-title" }, _t("app.recentImprovements"));
recent.appendChild(header);
for (const it of items) {
const ts = String(it.timestamp || "").slice(0, 16).replace("T", " ");
Expand Down
4 changes: 4 additions & 0 deletions emrg/gui/renderer/js/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ const I18N = (() => {
"app.workdirInvalid": "工作目录不可用,请到设置里改一下。",
"app.bootFailed": "启动遇到了问题:{msg}",
"app.needSession": "请先创建一个对话。",
"app.recentImprovements": "最近改进",
"app.noImprovements": "还没有改进记录,输入 /rant 驱动第一次进化吧",
"app.cmdUnknown": "指令 {cmd} 暂未开放。",
"app.cleared": "已清空当前对话。",
"app.compacted": "已压缩当前对话历史。",
Expand Down Expand Up @@ -485,6 +487,8 @@ const I18N = (() => {
"app.workdirInvalid": "Working directory unavailable — update it in Settings.",
"app.bootFailed": "Startup failed: {msg}",
"app.needSession": "Start a conversation first.",
"app.recentImprovements": "Recent improvements",
"app.noImprovements": "No improvements recorded yet — type /rant to drive the first evolution",
"app.cmdUnknown": "Command {cmd} is not available yet.",
"app.cleared": "Current conversation cleared.",
"app.compacted": "Conversation history compacted.",
Expand Down
35 changes: 35 additions & 0 deletions emrg/gui/test/i18n.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,38 @@ test("Stage3:新增静态键双语一致(growth-card title / about / status-
assert.strictEqual(evalIn(zh, 'I18N.t("settings.recentTitle")'), "最近改进");
assert.strictEqual(evalIn(zh, 'I18N.t("sidebar.backToBottom")'), "回到底部");
});

// ── Stage 3b(cycle 20260806-230036):renderer JS 运行时中文字符串防漏网 ──
test("Stage3b:renderer JS 无未接入 i18n 的中文字符串(防 JS 侧回归)", () => {
// 扫描 renderer/js/*.js:含中文且非注释、非 i18n 取词、非词典、非功能正则的行
const fs2 = require("node:fs");
const path2 = require("node:path");
const cjk = /[\u4e00-\u9fff]/;
const leaks = [];
for (const f of fs2.readdirSync(path.join(__dirname, "..", "renderer", "js"))) {
if (!f.endsWith(".js")) continue;
if (f === "i18n.js") continue; // 词典本身全是中文(合法)
const src = fs2.readFileSync(path.join(__dirname, "..", "renderer", "js", f), "utf8");
for (const [i, line] of src.split("\n").entries()) {
let s = line.trim();
if (!cjk.test(s)) continue;
// 剥离注释:行首 //、行尾 // 注释、/* */ 块
s = s.replace(/^\/\/.*$/, "").replace(/^\*.*$/, "").replace(/ \/\/.*$/, "").replace(/\/\*.*?\*\//g, "").trim();
if (!cjk.test(s)) continue; // 仅注释含中文 → 跳过
if (s.includes("_t(") || s.includes("EMRG_I18N")) continue; // 已取词
if (s.includes("i18n")) continue; // i18n 基础设施/注释
if (s.includes("match(") || s.includes("replace(")) continue; // 功能正则(如文件路径提取)
if (s.includes("ensure_ascii")) continue; // 序列化说明
leaks.push(`${f}:L${i + 1}: ${s.slice(0, 80)}`);
}
}
assert.strictEqual(leaks.length, 0, "renderer JS 存在未接入 i18n 的中文:\n" + leaks.join("\n"));
});

test("Stage3b:最近改进列表文案双语(#502 evolution_summary 侧)", () => {
const { ctx } = makeSandbox({ navigator: { language: "en-US" } });
assert.strictEqual(evalIn(ctx, 'I18N.t("app.recentImprovements")'), "Recent improvements");
assert.strictEqual(evalIn(ctx, 'I18N.t("app.noImprovements")'), "No improvements recorded yet — type /rant to drive the first evolution");
const { ctx: zh } = makeSandbox({ navigator: { language: "zh-CN" } });
assert.strictEqual(evalIn(zh, 'I18N.t("app.recentImprovements")'), "最近改进");
});
Loading