From 7177137cde1cebd19b45cd6bea37d5412488dfe1 Mon Sep 17 00:00:00 2001 From: spoukyii <61633921+spoukyii@users.noreply.github.com> Date: Tue, 3 Nov 2026 12:37:14 -0800 Subject: [PATCH 1/2] test(client-runtime): cover an untitled subagent prompt that ends on an emoji at the cut --- packages/client-runtime/src/state/subagentRuntime.test.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/client-runtime/src/state/subagentRuntime.test.ts b/packages/client-runtime/src/state/subagentRuntime.test.ts index c40c9fe42d81e..0d65e1d36a2fd 100644 --- a/packages/client-runtime/src/state/subagentRuntime.test.ts +++ b/packages/client-runtime/src/state/subagentRuntime.test.ts @@ -119,6 +119,13 @@ describe("projectedSubagentsToRuntime workflow expansion", () => { expect(members?.[0]?.speed).toBeUndefined(); }, ); + + it("titles an untitled subagent from its prompt without splitting an emoji", () => { + const [untitled] = projectedSubagentsToRuntime([ + subagent({ title: null, prompt: `${"a".repeat(76)}😀 and more work.` }), + ]); + expect(untitled?.title).toBe(`${"a".repeat(76)}...`); + }); }); describe("deriveWorkflowGroups over a dynamic workflow", () => { From ebf626ee89b7b220bfe1195fb3363d1d23819b0a Mon Sep 17 00:00:00 2001 From: spoukyii <61633921+spoukyii@users.noreply.github.com> Date: Tue, 3 Nov 2026 12:37:45 -0800 Subject: [PATCH 2/2] fix(client-runtime): untitled subagent titles no longer end in a broken character A subagent with no title of its own is titled from its prompt. A prompt longer than 80 UTF-16 code units is cut at 77 units and gets "...". When an emoji straddled the cut, the title kept only its high surrogate and showed a replacement character before the "...". The full title shows in the mobile Agents sheet header of a Claude workflow that has no title and no name yet, and in that header's screen-reader labels on web and mobile. The cut now steps back one unit when it would land between a high and a low surrogate, the same check #29563 and #29163 added to thread titles. Bug: an untitled subagent's title ends in a broken character when an emoji sits at the 77-unit cut --- .../client-runtime/src/state/subagentRuntime.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/client-runtime/src/state/subagentRuntime.ts b/packages/client-runtime/src/state/subagentRuntime.ts index e3807362fbdf6..df6e4ce6e8870 100644 --- a/packages/client-runtime/src/state/subagentRuntime.ts +++ b/packages/client-runtime/src/state/subagentRuntime.ts @@ -175,6 +175,17 @@ function workflowMembersToRuntime( }); } +function promptTitle(prompt: string): string { + if (prompt.length <= 80) return prompt; + let end = 77; + const previous = prompt.charCodeAt(end - 1); + const next = prompt.charCodeAt(end); + if (previous >= 0xd800 && previous <= 0xdbff && next >= 0xdc00 && next <= 0xdfff) { + end -= 1; + } + return `${prompt.slice(0, end)}...`; +} + export function projectedSubagentsToRuntime( subagents: ReadonlyArray<{ readonly id: string; @@ -200,9 +211,7 @@ export function projectedSubagentsToRuntime( const coordinator = { id: subagent.id, kind: workflow === undefined ? "subagent" : "workflow", - title: - subagent.title ?? - (subagent.prompt.length > 80 ? `${subagent.prompt.slice(0, 77)}...` : subagent.prompt), + title: subagent.title ?? promptTitle(subagent.prompt), role: null, model: subagent.model, effort: null,