feat(app-server): add optional thread_id to experimentalFeature/list (#23335)

## Why

`experimentalFeature/list` reports effective feature enablement, but
currently does not resolve it against a working directory where
project-local config.toml files can exist and toggle on/off features
when merged into the effective config after resolving the various config
layers. That means we effectively (and incorrectly) ignore features set
in project-local config.

To address that, this PR exposes an optional `thread_id` param which
allows us to load the thread's `cwd.

## Testing

- `cargo test -p codex-app-server-protocol`
- `cargo test -p codex-app-server experimental_feature_list`
This commit is contained in:
Owen Lin authored and GitHub committed 2026-05-18 12:12:14 -07:00
1 parent 8e52578e66
commit 139365a4bb
10 files changed
+191 -5

No files matched your search

@@ -285,8 +285,28 @@ impl CatalogRequestProcessor {
&self,
params: ExperimentalFeatureListParams,
) -> Result<ExperimentalFeatureListResponse, JSONRPCErrorError> {
let ExperimentalFeatureListParams { cursor, limit } = params;
let config = self.load_latest_config(/*fallback_cwd*/ None).await?;
let ExperimentalFeatureListParams {
cursor,
limit,
thread_id,
} = params;
let config = match thread_id.as_deref() {
Some(thread_id) => {
let thread_id = ThreadId::from_string(thread_id)
.map_err(|err| invalid_request(format!("invalid thread id: {err}")))?;
let thread = self
.thread_manager
.get_thread(thread_id)
.await
.map_err(|_| invalid_request(format!("thread not found: {thread_id}")))?;
let thread_config = thread.config().await;
self.config_manager
.load_latest_config_for_thread(thread_config.as_ref())
.await
.map_err(|err| internal_error(format!("failed to reload config: {err}")))?
}
None => self.load_latest_config(/*fallback_cwd*/ None).await?,
};
let auth = self.auth_manager.auth().await;
let workspace_codex_plugins_enabled = self
.workspace_codex_plugins_enabled(&config, auth.as_ref())