Skip to content

fix(unicode): 避免标题截断拆开代理对 - #1275

Merged
deepcoldy merged 1 commit into
deepcoldy:masterfrom
LPX-E5BD8:fix/unicode-title-truncation
Sep 7, 2026
Merged

fix(unicode): 避免标题截断拆开代理对#1275
deepcoldy merged 1 commit into
deepcoldy:masterfrom
LPX-E5BD8:fix/unicode-title-truncation

Conversation

@LPX-E5BD8

@LPX-E5BD8 LPX-E5BD8 commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

问题

多条标题生成路径直接用 String.slice(0, N) 截断。JavaScript 按 UTF-16 code unit 索引,当 emoji 恰好跨越边界时会留下孤立 surrogate,并在 UTF-8 编码时变成替换字符

Fixes #1253

修复

  • 新增 truncateUtf16WellFormed():按 Unicode code point 遍历,同时以 UTF-16 code unit 计入原有长度预算。
  • 替换以下四条路径的直接切片:
    • 内容首行生成会话标题(50)
    • 显式群名(60)
    • 会话重命名标题(200)
    • Dashboard spawn 显式标题(200)
  • 对输入中的孤立 surrogate 使用 U+FFFD 归一化,保证返回字符串 well-formed。
  • 保持原有长度上限及会话标题省略号语义。

影响面

  • 只影响用户可见标题/群名的边界截断。
  • BMP 字符和未超长的正常 Unicode 输入行为不变。
  • 不改变 session id、消息正文或其它协议字段。

验证

  • Issue 中最小复现在修复前稳定得到 wellFormed: false
  • npx vitest run --project unit test/unicode.test.ts test/session-create.test.ts test/session-kanban.test.ts:53 passed。
  • bun run vitest run --project unit test/unicode.test.ts test/session-create.test.ts test/session-kanban.test.ts:53 passed。
  • bun run build:通过。

Copilot AI lite review requested due to automatic review settings September 6, 2026 10:33
@LPX-E5BD8
LPX-E5BD8 requested a review from deepcoldy as a code owner September 6, 2026 10:33

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

deriveSessionTitleFromContent() 在未超长时仍可能返回包含孤立 surrogate 的 non-well-formed 字符串,与 PR 目标的“始终 well-formed”不一致。

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

本 PR 旨在修复用户可见标题/群名在按 UTF-16 code unit 截断时可能切断 surrogate pair(emoji 等 astral 字符)而生成 non-well-formed Unicode、并在 UTF-8 编码时出现替换字符 的问题;通过新增统一的截断 helper 并替换关键路径的直接 .slice(0, N) 来保证边界截断结果始终是 well-formed Unicode。

Changes:

  • 新增 truncateUtf16WellFormed():按 code point 遍历、以 UTF-16 code unit 计预算,并将孤立 surrogate 归一化为 U+FFFD
  • 将会话标题、显式群名、spawn 显式标题、会话重命名标题的截断逻辑替换为新 helper,避免拆开 surrogate pair。
  • 增加/扩展单测覆盖 emoji 边界与孤立 surrogate 的修复行为。
File summaries
File Description
src/utils/unicode.ts 新增安全截断 helper,避免 surrogate pair 被切断并归一化孤立 surrogate。
src/core/session-create.ts 在标题/群名派生与 spawn title 解析中替换直接 slice 为安全截断。
src/core/session-board.ts normalizeSessionTitle() 中替换直接 slice 为安全截断。
test/unicode.test.ts 新增针对 helper 的预算/emoji/孤立 surrogate 行为测试。
test/session-create.test.ts 增加标题/群名/spawn title 的 emoji 边界回归测试。
test/session-kanban.test.ts 增加 session title 归一化在 emoji 边界处保持 well-formed 的回归测试。
Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 55 to 59
export function deriveSessionTitleFromContent(content: string): string {
const firstLine = content.split(/\r?\n/).map(s => s.trim()).find(Boolean) ?? '';
if (!firstLine) return t('cmd.createSession.untitled');
return firstLine.length > TITLE_MAX ? firstLine.slice(0, TITLE_MAX) + '…' : firstLine;
return firstLine.length > TITLE_MAX ? truncateUtf16WellFormed(firstLine, TITLE_MAX) + '…' : firstLine;
}
新增按 Unicode code point 遍历、按 UTF-16 code unit 计预算的截断 helper,并应用到会话标题、群名和显式标题入口,避免边界 emoji 被编码为替换字符。

Refs: deepcoldy#1253

Co-authored-by: TRAE CLI <noreply@bytedance.com>
@LPX-E5BD8
LPX-E5BD8 force-pushed the fix/unicode-title-truncation branch from 993c39f to d9664f8 Compare September 6, 2026 10:45
@deepcoldy

Copy link
Copy Markdown
Owner

你好!这是 Botmux 的自动评审流程。

本 PR 的评审群已创建:https://applink.feishu.cn/client/chat/open?openChatId=oc_442938fc0e50c5db0987038a28e8d171

但你暂时未被拉入群中——你的 GitHub 账号(LPX-E5BD8)不在自动拉群名单里。请把你的 GitHub 账号和飞书信息补进名单文档:
https://bytedance.larkoffice.com/wiki/WJ1nwWbtxi89erkNGNbcgkt9nUe

补好后,后续复审会自动把你拉进群。感谢贡献!

@deepcoldy deepcoldy left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

双审 0 阻断,本地已在最新 master 上验证:53/53(vitest + bun 双运行时)、tsc exit 0、bun run build exit 0、反变异两枪全红。issue #1253 最小复现修前 false → 修后 true。

@deepcoldy
deepcoldy merged commit 02dea10 into deepcoldy:master Sep 7, 2026
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown

🚀 Released in v3.19.3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(unicode): 会话/群标题截断会切断 emoji 的 UTF-16 代理对

3 participants