Repository navigation
fix: keep derived session titles from splitting emoji surrogate pairs - #981
Conversation
🦋 Changeset detectedLatest commit: c6acc41 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
thesujai
left a comment
There was a problem hiding this comment.
Thanks @soumojit-D48, just one change and this will be good to merge
|
Done — thanks for catching that, the surrogate back-off would indeed have mangled 👋🏽 into 👋. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 9cfd45b. Configure here.
20eab0f to
c6acc41
Compare

Summary
Derived session titles could end in a lone surrogate when the 50-character cap landed inside an emoji, storing malformed Unicode (visible as a replacement character in the session list). This PR backs off one unit when the cut would split a surrogate pair, so titles stay well-formed while keeping the existing length limit.
Closes #980
Changes
packages/trueforge/src/apis/turns.ts: routederiveSessionTitlethrough a newtruncateSessionTitlehelper that drops a trailing high surrogate after capping.packages/trueforge/tests/unit/apis/turns.test.ts: newderiveSessionTitleblock (cap behavior, short/empty inputs, intact pair inside the cap, split-pair back-off asserting the exact result)..changeset/session-title-surrogate-boundary.md:patchbump for@truefoundry/trueforge.How was this tested?
pnpm --filter @truefoundry/trueforge test -- tests/unit/apis/turns.test.ts: 14/14 pass (9 pre-existing + 5 new).pnpm --filter @truefoundry/trueforge typecheck: exit 0 (src + tests projects).eslinton the changed source file: clean (test files are eslint-ignored per repo config).prettier --checkon all changed/added files: pass.pnpm build,pnpm test, andpnpm smokewere NOT run in this environment (Windows); CI covers the rest.Checklist
pnpm build,pnpm test,pnpm typecheck,pnpm lint:ci, andpnpm format:checkpass locally (package-level test/typecheck/eslint/prettier pass; full workspace gates pending CI — see above)packages/trueforge-sdk,python/trueforge_sdk,.github/fern/openapi/openapi.json,docs/openapi.json) — fork PRs omit SDK regen; maintainers regenerate after merge.env.exampleupdated if configuration or behavior changed (not needed: no config or operator-visible behavior change beyond the bug fix)Note
Low Risk
Localized first-turn title derivation and display formatting; no auth, API contract, or persistence schema changes beyond avoiding malformed or blank titles.
Overview
Fixes derived session titles so the 50-character cap no longer cuts through emoji or other multi-code-unit graphemes (surrogate pairs, skin tones, ZWJ sequences).
deriveSessionTitlenow caps via a newtruncateSessionTitlehelper that walksIntl.Segmentergrapheme clusters and omits any cluster that would exceed the limit, instead of using a rawslice. If nothing fits—including when a single cluster is longer than the cap—the function returnsundefinedso the session store does not persist an empty title on first write.Unit tests cover length limits, empty input, and several Unicode edge cases;
@truefoundry/trueforgegets a patch changeset.Reviewed by Cursor Bugbot for commit c6acc41. Bugbot is set up for automated code reviews on this repo. Configure here.