Add persisted sections for organizing threads (#35722)

## What changed

- Replace the `isPinned` thread metadata and filters with an optional persisted
  `section` and `sectionId`.
- Add the paginated `threadSection/list` app-server method so clients can
  discover sections even when they contain no threads.
- Seed a stable `Pinned` section, validate section assignments, and support
  filtering for a specific section or for unsectioned threads.

## Testing

- Cover section protocol serialization, listing and pagination, metadata
  updates, filtering, persistence, migration compatibility, and operation
  without SQLite state.

GitOrigin-RevId: 7972b5471d29317b9387bfd90aa9f573f691ad4c
This commit is contained in:
joeytrasatti-openai authored and copyberry committed 2026-07-28 05:26:16 +00:00
1 parent 9291a123fb
commit 85c6da1c79
85 files changed
+1826 -419

No files matched your search

+3 -3
View File
@@ -361,7 +361,7 @@ pub async fn list_threads_db(
cwd_filters: Option<&[PathBuf]>,
relation_filter: Option<codex_state::ThreadRelationFilter>,
archived: bool,
is_pinned: Option<bool>,
section: Option<Option<&str>>,
search_term: Option<&str>,
) -> Option<codex_state::ThreadsPage> {
let ctx = context?;
@@ -403,7 +403,7 @@ pub async fn list_threads_db(
if let Some(relation_filter) = relation_filter {
let filters = codex_state::ThreadFilterOptions {
archived_only: archived,
is_pinned,
section,
allowed_sources: allowed_sources.as_slice(),
model_providers: model_providers.as_deref(),
cwd_filters: normalized_cwd_filters.as_deref(),
@@ -430,7 +430,7 @@ pub async fn list_threads_db(
while items.len() < page_size {
let filters = codex_state::ThreadFilterOptions {
archived_only: archived,
is_pinned,
section,
allowed_sources: allowed_sources.as_slice(),
model_providers: model_providers.as_deref(),
cwd_filters: normalized_cwd_filters.as_deref(),