mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Add runtime extra skill roots API (#24977)
## Summary - Add v2 `skills/extraRoots/set` to replace app-server process-local standalone skill roots. The setting is not persisted, accepts missing roots, and `extraRoots: []` clears the runtime set. - Wire runtime roots into core skill discovery for `skills/list` and turn loads, clear skill caches on set, and register the roots with the skills watcher so later filesystem changes emit `skills/changed`. - Update app-server docs, generated JSON/TypeScript schemas, and coverage for serialization, missing roots, empty clears, and restart behavior. ## Testing - `cargo test -p codex-app-server-protocol` - `cargo test -p codex-core-skills` - `cargo test -p codex-app-server skills_extra_roots_set_updates_process_runtime_roots` - `just fix -p codex-app-server-protocol` - `just fix -p codex-core-skills` - `just fix -p codex-app-server`
This commit is contained in:
@@ -610,6 +610,11 @@ client_request_definitions! {
|
||||
serialization: global_shared_read("config"),
|
||||
response: v2::SkillsListResponse,
|
||||
},
|
||||
SkillsExtraRootsSet => "skills/extraRoots/set" {
|
||||
params: v2::SkillsExtraRootsSetParams,
|
||||
serialization: global("config"),
|
||||
response: v2::SkillsExtraRootsSetResponse,
|
||||
},
|
||||
HooksList => "hooks/list" {
|
||||
params: v2::HooksListParams,
|
||||
serialization: global("config"),
|
||||
@@ -1721,6 +1726,17 @@ mod tests {
|
||||
Some(ClientRequestSerializationScope::GlobalSharedRead("config"))
|
||||
);
|
||||
|
||||
let skills_extra_roots_set = ClientRequest::SkillsExtraRootsSet {
|
||||
request_id: request_id(),
|
||||
params: v2::SkillsExtraRootsSetParams {
|
||||
extra_roots: vec![absolute_path("/tmp/skills")],
|
||||
},
|
||||
};
|
||||
assert_eq!(
|
||||
skills_extra_roots_set.serialization_scope(),
|
||||
Some(ClientRequestSerializationScope::Global("config"))
|
||||
);
|
||||
|
||||
let plugin_list = ClientRequest::PluginList {
|
||||
request_id: request_id(),
|
||||
params: v2::PluginListParams {
|
||||
|
||||
@@ -35,6 +35,18 @@ pub struct SkillsListResponse {
|
||||
pub data: Vec<SkillsListEntry>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct SkillsExtraRootsSetParams {
|
||||
pub extra_roots: Vec<AbsolutePathBuf>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct SkillsExtraRootsSetResponse {}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
|
||||
@@ -2626,6 +2626,27 @@ fn skills_list_params_serialization_uses_force_reload() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn skills_extra_roots_set_params_serialization_uses_extra_roots() {
|
||||
assert_eq!(
|
||||
serde_json::to_value(SkillsExtraRootsSetParams {
|
||||
extra_roots: vec![absolute_path("tmp/skills")],
|
||||
})
|
||||
.unwrap(),
|
||||
json!({
|
||||
"extraRoots": [absolute_path_string("tmp/skills")],
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn skills_extra_roots_set_params_rejects_relative_roots() {
|
||||
let result = serde_json::from_value::<SkillsExtraRootsSetParams>(json!({
|
||||
"extraRoots": ["relative/path"],
|
||||
}));
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn plugin_source_serializes_local_git_and_remote_variants() {
|
||||
let local_path = if cfg!(windows) {
|
||||
|
||||
Reference in New Issue
Block a user