From 0a67f227e14bfb980730dae659df438e0127f81f Mon Sep 17 00:00:00 2001 From: Alex Southwell <4596216+saphid@users.noreply.github.com> Date: Mon, 2 Nov 2026 18:56:52 +1100 Subject: [PATCH] fix(server): create_threads titles no longer end in a broken character Co-Authored-By: Claude Opus 5.5 --- apps/server/src/mcp/OrchestratorMcpService.test.ts | 8 ++++++++ apps/server/src/mcp/OrchestratorMcpService.ts | 9 ++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/apps/server/src/mcp/OrchestratorMcpService.test.ts b/apps/server/src/mcp/OrchestratorMcpService.test.ts index 47a6bda166ce1..328d32f635685 100644 --- a/apps/server/src/mcp/OrchestratorMcpService.test.ts +++ b/apps/server/src/mcp/OrchestratorMcpService.test.ts @@ -2037,6 +2037,14 @@ describe("OrchestratorMcpService provider resolution", () => { ...request, clientRequestId: "empty", }); + const emojiAtLimit = yield* service.createThreads(scope, { + threads: [{ ...request.threads[0]!, prompt: `${"a".repeat(76)}😀 and more work.` }], + clientRequestId: "emoji-title", + }); + const titled = yield* orchestrator.getThreadProjection( + emojiAtLimit.threads[0]!.threadId, + ); + assert.equal(titled.thread.title, `${"a".repeat(76)}...`); yield* settings.updateSettings({ projectSettingsOverrides: { diff --git a/apps/server/src/mcp/OrchestratorMcpService.ts b/apps/server/src/mcp/OrchestratorMcpService.ts index 910a1531aedb8..108ab946245a0 100644 --- a/apps/server/src/mcp/OrchestratorMcpService.ts +++ b/apps/server/src/mcp/OrchestratorMcpService.ts @@ -742,7 +742,14 @@ function threadTitle(input: { }): string { const detail = input.title?.trim() || input.prompt?.trim(); if (!detail) return `${input.parentTitle} thread ${input.index + 1}`; - return detail.length > 80 ? `${detail.slice(0, 77)}...` : detail; + if (detail.length <= 80) return detail; + let end = 77; + const previous = detail.charCodeAt(end - 1); + const next = detail.charCodeAt(end); + if (previous >= 0xd800 && previous <= 0xdbff && next >= 0xdc00 && next <= 0xdfff) { + end -= 1; + } + return `${detail.slice(0, end)}...`; } function threadSettlement(