feat(i18n): the tab's exited-agent badge in Chinese (zh-CN)

Owner request: translate the EXITED badge. The badge carried
data-i18n-skip on purpose, because its in-place update compared the DOM
with the English label: a translated badge would never have matched, and
every incremental tab pass would have written English back for the
translator to redo. The tab's accessible name (which carries the exit,
the badge being aria-hidden) was set unconditionally on every pass, the
same trap once it is translated.

Now the badge is left to the translator. applyPaneExitBadge remembers the
last English badge text (data-label) and accessible name
(data-aria-source), both also seeded by the full render, and compares
with those, never the DOM. The tab strip's incremental path updates tabs
in place (no row-HTML comparison), so nothing else re-renders on a
translated badge.

i18n.js: "exited" -> 已退出, patterns for "exited (N)" -> 已退出(N) and
"exited (signal N)" -> 已退出(信号 N), and for the accessible name
"<name> session, agent exited ..." -> "<name> 会话,智能体已退出 ...", the
session name passed through untranslated. The header strip, the session
sidebar and the vertical rail all host the same tab markup, so this
covers all three. English reads exactly as before.

Tests: session-pane-exit-ui pins the new markup, the remembered English
and that a translated badge and accessible name survive an unchanged
pass; i18n-exit-run-help runs every paneExitLabel form (and the
accessible name, with names that are dictionary words) through the real
translator in both languages.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer
2026-10-07 02:07:27 +02:00
parent dfb9f32e23
commit 66da91f78b
4 changed files with 139 additions and 13 deletions
+13
View File
@@ -146,6 +146,9 @@
'The agent exited': '智能体已退出',
'It cannot be restarted in place: close it from ⋯ (Close session).': '无法原地重启:请通过 ⋯(关闭会话)关闭它。',
'Could not attach the session': '无法附加会话',
// The tab's exited-agent badge (app.js applyPaneExitBadge, Ark0N/Codeman#446);
// its exit-code forms and the tab's accessible name are patterns.
exited: '已退出',
'Ultracode / Workflow agents': 'Ultracode / Workflow 智能体',
'Open ultracode workflow agents': '打开 Ultracode 工作流智能体',
Notifications: '通知',
@@ -1047,6 +1050,16 @@
],
[/^The agent exited \((-?\d+)\)$/, (_m, code) => `智能体已退出(${code})`],
[/^The agent exited \(signal (\d+)\)$/, (_m, signal) => `智能体已退出(信号 ${signal})`],
// The tab's exited-agent badge, and the tab's accessible name carrying it.
// The session name is user text: it passes through untranslated.
[/^exited \((-?\d+)\)$/, (_m, code) => `已退出(${code})`],
[/^exited \(signal (\d+)\)$/, (_m, signal) => `已退出(信号 ${signal})`],
[
/^(.+) session, agent exited \(signal (\d+)\)$/,
(_m, name, signal) => `${name} 会话,智能体已退出(信号 ${signal})`,
],
[/^(.+) session, agent exited \((-?\d+)\)$/, (_m, name, code) => `${name} 会话,智能体已退出(${code})`],
[/^(.+) session, agent exited$/, (_m, name) => `${name} 会话,智能体已退出`],
// A session name is user text: it passes through untranslated.
[
/^(.+) was stopped after crashing repeatedly\. Restart it\?$/,