app-server: Emit thread archive/unarchive notifications (#12030)

* Add v2 server notifications `thread/archived` and `thread/unarchived`
with a `threadId` payload.
* Wire new events into `thread/archive` and `thread/unarchive` success
paths.
* Update app-server protocol/schema/docs accordingly.

Testing:
- Updated archive/unarchive end-to-end tests to verify both
notifications are emitted with the expected thread id payload.
This commit is contained in:
Ruslan Nigmatullin
2026-02-17 14:53:58 -08:00
committed by GitHub
parent 709e2133bb
commit 31cbebd3c2
17 changed files with 234 additions and 8 deletions

View File

@@ -10,11 +10,13 @@ use codex_app_server_protocol::ThreadStartParams;
use codex_app_server_protocol::ThreadStartResponse;
use codex_app_server_protocol::ThreadUnarchiveParams;
use codex_app_server_protocol::ThreadUnarchiveResponse;
use codex_app_server_protocol::ThreadUnarchivedNotification;
use codex_app_server_protocol::TurnStartParams;
use codex_app_server_protocol::TurnStartResponse;
use codex_app_server_protocol::UserInput;
use codex_core::find_archived_thread_path_by_id_str;
use codex_core::find_thread_path_by_id_str;
use pretty_assertions::assert_eq;
use std::fs::FileTimes;
use std::fs::OpenOptions;
use std::path::Path;
@@ -120,6 +122,17 @@ async fn thread_unarchive_moves_rollout_back_into_sessions_directory() -> Result
let ThreadUnarchiveResponse {
thread: unarchived_thread,
} = to_response::<ThreadUnarchiveResponse>(unarchive_resp)?;
let unarchive_notification = timeout(
DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_notification_message("thread/unarchived"),
)
.await??;
let unarchived_notification: ThreadUnarchivedNotification = serde_json::from_value(
unarchive_notification
.params
.expect("thread/unarchived notification params"),
)?;
assert_eq!(unarchived_notification.thread_id, thread.id);
assert!(
unarchived_thread.updated_at > old_timestamp,
"expected updated_at to be bumped on unarchive"