Add persisted thread pinning to the app server (#34840)

## What changed

- Add `isPinned` to thread responses and allow `thread/metadata/update` to pin or unpin stored threads.
- Add an `isPinned` filter to `thread/list`, including cursor-based pagination and combinations with relationship filters.
- Persist pin state in SQLite without modifying rollout files, default existing threads to unpinned, and preserve pins through reconciliation and archive transitions.

## Testing

- Cover protocol serialization, database migration and indexing, pin updates, filtered pagination, rollout reconciliation, and archive/unarchive behavior.

GitOrigin-RevId: c2eacabd6dae465e2ae6ce8a169e00740960cdb7
This commit is contained in:
joeytrasatti-openai authored and copyberry committed 2026-07-22 22:54:28 +00:00
1 parent d7e8f4c3dc
commit 400ee190c3
71 files changed
+1058 -60

No files matched your search

@@ -865,6 +865,9 @@ pub struct ThreadMetadataUpdateParams {
/// provide a string to replace the stored value.
#[ts(optional = nullable)]
pub git_info: Option<ThreadMetadataGitInfoUpdateParams>,
/// Patch whether this thread is pinned. Omit to leave the stored value unchanged.
#[ts(optional = nullable)]
pub is_pinned: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
@@ -1118,6 +1121,9 @@ pub struct ThreadListParams {
/// If false or null, only non-archived threads are returned.
#[ts(optional = nullable)]
pub archived: Option<bool>,
/// Optional pinned filter; when set, only threads matching this value are returned.
#[ts(optional = nullable)]
pub is_pinned: Option<bool>,
/// Optional cwd filter or filters; when set, only threads whose session cwd
/// exactly matches one of these paths are returned.
#[ts(optional = nullable, type = "string | Array<string> | null")]