Broadcast thread section changes to connected clients (#58380)

## Why

Clients need to refresh section membership and ordering when another client moves a thread.

## What changed

Broadcast `thread/section/changed` after a successful `thread/section/move`, including moves within the same section. Send the response before the notification, and include `threadId` and the destination `sectionId`, using `null` for removal. Failed moves do not emit the notification.

Add the notification to the protocol schemas, TypeScript exports, and Python SDK models and registry, and document its behavior.

## Testing

Add a WebSocket integration test with separate writer and observer clients covering section insertion, reordering, removal, and a failed move.

GitOrigin-RevId: 128ba7eddc9aae8e3bac766f47e4a2c55c64a6a5
This commit is contained in:
Charlie Marsh
2026-10-30 16:09:46 +00:00
committed by copyberry
parent 483d98a441
commit 1f0290c607
22 changed files with 307 additions and 15 deletions
@@ -6308,6 +6308,20 @@ class ThreadSectionAppearance(BaseModel):
icon: str | None = None
class ThreadSectionChangedNotification(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
section_id: Annotated[
str | None,
Field(
alias="sectionId",
description="Destination section, or `null` when the thread was removed from its section.",
),
]
thread_id: Annotated[str, Field(alias="threadId")]
class ThreadSectionCreateParams(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
@@ -9697,6 +9711,23 @@ class ThreadNameUpdatedServerNotification(BaseModel):
params: ThreadNameUpdatedNotification
class ThreadSectionChangedServerNotification(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
emitted_at_ms: Annotated[
int | None,
Field(
alias="emittedAtMs",
description="Unix timestamp (in milliseconds) when app-server emitted this notification.",
),
] = None
method: Annotated[
Literal["thread/section/changed"], Field(title="Thread/section/changedNotificationMethod")
]
params: ThreadSectionChangedNotification
class ThreadAttachmentUpdatedServerNotification(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
@@ -13634,6 +13665,7 @@ class ServerNotification(
| ThreadRevertedServerNotification
| SkillsChangedServerNotification
| ThreadNameUpdatedServerNotification
| ThreadSectionChangedServerNotification
| ThreadAttachmentUpdatedServerNotification
| ThreadGoalUpdatedServerNotification
| ThreadPredictionUpdatedServerNotification
@@ -13722,6 +13754,7 @@ class ServerNotification(
| ThreadRevertedServerNotification
| SkillsChangedServerNotification
| ThreadNameUpdatedServerNotification
| ThreadSectionChangedServerNotification
| ThreadAttachmentUpdatedServerNotification
| ThreadGoalUpdatedServerNotification
| ThreadPredictionUpdatedServerNotification