conversationKey derived the group session key from chat_id alone, so in
Feishu topic groups every topic shared one Harness session: context,
/new, pending approvals, and batch-input state all leaked across topics.
Append the event's thread_id to the session key when present. Topic
groups stamp every message with a thread_id, so each topic now maps to
its own group:<chat_id>🧵<thread_id> session. Regular group chats
carry no thread_id and keep the single shared group:<chat_id> key; p2p
keys are untouched.
- message-utils.mjs: thread-aware conversationKey
- message-utils.test.mjs: topic isolation + regular-group fallback cases
- lib/index.js: regenerated host bundle
Wrap all user-facing chat text in src/channels with a host-side t()
translator (Chinese is the identity default, so untranslated text is
always sent verbatim in Chinese). English is selected via the host
plugin config `language: en` or the DSH_IM_LANGUAGE environment
variable, and the settings UI keeps following the DSH web locale.
- add src/channels/shared/i18n.mjs with setImHostLanguage/t() and a
Chinese-key -> English dictionary split by area (shared + channels)
- complete the English dictionary for every t() key in src/channels,
including the feishu channel (welcome/help, repair flow, interactive
cards, watch flow) and the shared command/approval/stream text
- wrap previously untranslated chat-facing strings in feishu bridge,
feishu runtime, editable-message-stream, harness-client,
connection-test and image-prompt
- dedupe dictionary entries that existed in multiple channel files and
canonicalize conflicting translations into the shared dictionaries
- extend the i18n unit test to decode string-literal escapes so keys
containing \n are checked correctly
- document the language switch in README.md, README.en.md and
CHANGELOG.md, and rebuild lib/index.js
Added English support for bot chat messages across all nine IM
channels and AI Office without changing any Chinese output.