fix: clarify the value of SkillMetadata.path (#12729)

Rename `SkillMetadata.path` to `SkillMetadata.path_to_skills_md` for
clarity.

Would ideally change the type to `AbsolutePathBuf`, but that can be done
later.
This commit is contained in:
Michael Bolin
2026-02-24 17:15:54 -08:00
committed by GitHub
Unverified
parent 63c2ac96cd
commit 448fb6ac22
14 changed files with 80 additions and 73 deletions
@@ -6526,7 +6526,7 @@ fn skills_to_info(
skills
.iter()
.map(|skill| {
let enabled = !disabled_paths.contains(&skill.path);
let enabled = !disabled_paths.contains(&skill.path_to_skills_md);
codex_app_server_protocol::SkillMetadata {
name: skill.name.clone(),
description: skill.description.clone(),
@@ -6557,7 +6557,7 @@ fn skills_to_info(
.collect(),
}
}),
path: skill.path.clone(),
path: skill.path_to_skills_md.clone(),
scope: skill.scope.into(),
enabled,
}
+2 -2
View File
@@ -4734,9 +4734,9 @@ fn skills_to_info(
.collect(),
}
}),
path: skill.path.clone(),
path: skill.path_to_skills_md.clone(),
scope: skill.scope,
enabled: !disabled_paths.contains(&skill.path),
enabled: !disabled_paths.contains(&skill.path_to_skills_md),
})
.collect()
}
+1 -1
View File
@@ -434,7 +434,7 @@ mod tests {
dependencies: Some(SkillDependencies { tools }),
policy: None,
permissions: None,
path: PathBuf::from("skill"),
path_to_skills_md: PathBuf::from("skill"),
scope: SkillScope::User,
}
}
+1 -1
View File
@@ -55,7 +55,7 @@ pub(crate) fn build_skill_name_counts(
let mut exact_counts: HashMap<String, usize> = HashMap::new();
let mut lower_counts: HashMap<String, usize> = HashMap::new();
for skill in skills {
if disabled_paths.contains(&skill.path) {
if disabled_paths.contains(&skill.path_to_skills_md) {
continue;
}
*exact_counts.entry(skill.name.clone()).or_insert(0) += 1;
+18 -14
View File
@@ -37,18 +37,18 @@ pub(crate) async fn build_skill_injections(
let mut invocations = Vec::new();
for skill in mentioned_skills {
match fs::read_to_string(&skill.path).await {
match fs::read_to_string(&skill.path_to_skills_md).await {
Ok(contents) => {
emit_skill_injected_metric(otel, skill, "ok");
invocations.push(SkillInvocation {
skill_name: skill.name.clone(),
skill_scope: skill.scope,
skill_path: skill.path.clone(),
skill_path: skill.path_to_skills_md.clone(),
invocation_type: InvocationType::Explicit,
});
result.items.push(ResponseItem::from(SkillInstructions {
name: skill.name.clone(),
path: skill.path.to_string_lossy().into_owned(),
path: skill.path_to_skills_md.to_string_lossy().into_owned(),
contents,
}));
}
@@ -57,7 +57,7 @@ pub(crate) async fn build_skill_injections(
let message = format!(
"Failed to load skill {name} at {path}: {err:#}",
name = skill.name,
path = skill.path.display()
path = skill.path_to_skills_md.display()
);
result.warnings.push(message);
}
@@ -121,9 +121,9 @@ pub(crate) fn collect_explicit_skill_mentions(
if let Some(skill) = selection_context
.skills
.iter()
.find(|skill| skill.path.as_path() == path.as_path())
.find(|skill| skill.path_to_skills_md.as_path() == path.as_path())
{
seen_paths.insert(skill.path.clone());
seen_paths.insert(skill.path_to_skills_md.clone());
seen_names.insert(skill.name.clone());
selected.push(skill.clone());
}
@@ -304,23 +304,27 @@ fn select_skills_from_mentions(
.collect();
for skill in selection_context.skills {
if selection_context.disabled_paths.contains(&skill.path)
|| seen_paths.contains(&skill.path)
if selection_context
.disabled_paths
.contains(&skill.path_to_skills_md)
|| seen_paths.contains(&skill.path_to_skills_md)
{
continue;
}
let path_str = skill.path.to_string_lossy();
let path_str = skill.path_to_skills_md.to_string_lossy();
if mention_skill_paths.contains(path_str.as_ref()) {
seen_paths.insert(skill.path.clone());
seen_paths.insert(skill.path_to_skills_md.clone());
seen_names.insert(skill.name.clone());
selected.push(skill.clone());
}
}
for skill in selection_context.skills {
if selection_context.disabled_paths.contains(&skill.path)
|| seen_paths.contains(&skill.path)
if selection_context
.disabled_paths
.contains(&skill.path_to_skills_md)
|| seen_paths.contains(&skill.path_to_skills_md)
{
continue;
}
@@ -347,7 +351,7 @@ fn select_skills_from_mentions(
}
if seen_names.insert(skill.name.clone()) {
seen_paths.insert(skill.path.clone());
seen_paths.insert(skill.path_to_skills_md.clone());
selected.push(skill.clone());
}
}
@@ -479,7 +483,7 @@ mod tests {
dependencies: None,
policy: None,
permissions: None,
path: PathBuf::from(path),
path_to_skills_md: PathBuf::from(path),
scope: codex_protocol::protocol::SkillScope::User,
}
}
+5 -5
View File
@@ -32,10 +32,10 @@ pub(crate) fn build_implicit_skill_path_indexes(
let mut by_scripts_dir = HashMap::new();
let mut by_skill_doc_path = HashMap::new();
for skill in skills {
let skill_doc_path = normalize_path(skill.path.as_path());
let skill_doc_path = normalize_path(skill.path_to_skills_md.as_path());
by_skill_doc_path.insert(skill_doc_path, skill.clone());
if let Some(skill_dir) = skill.path.parent() {
if let Some(skill_dir) = skill.path_to_skills_md.parent() {
let scripts_dir = normalize_path(&skill_dir.join("scripts"));
by_scripts_dir.insert(scripts_dir, skill);
}
@@ -118,7 +118,7 @@ pub(crate) async fn ensure_skill_approval_for_command(
let cache_key = SkillApprovalCacheKey {
skill_name: skill.name.clone(),
skill_path: skill.path.clone(),
skill_path: skill.path_to_skills_md.clone(),
skill_scope: skill.scope,
};
let already_approved = {
@@ -162,7 +162,7 @@ pub(crate) async fn maybe_emit_implicit_skill_invocation(
let invocation = SkillInvocation {
skill_name: candidate.name,
skill_scope: candidate.scope,
skill_path: candidate.path,
skill_path: candidate.path_to_skills_md,
invocation_type: InvocationType::Implicit,
};
let skill_scope = match invocation.skill_scope {
@@ -337,7 +337,7 @@ mod tests {
dependencies: None,
policy: None,
permissions: None,
path: skill_doc_path,
path_to_skills_md: skill_doc_path,
scope: codex_protocol::protocol::SkillScope::User,
}
}
+29 -29
View File
@@ -167,7 +167,7 @@ where
let mut seen: HashSet<PathBuf> = HashSet::new();
outcome
.skills
.retain(|skill| seen.insert(skill.path.clone()));
.retain(|skill| seen.insert(skill.path_to_skills_md.clone()));
fn scope_rank(scope: SkillScope) -> u8 {
// Higher-priority scopes first (matches root scan order for dedupe).
@@ -183,7 +183,7 @@ where
scope_rank(a.scope)
.cmp(&scope_rank(b.scope))
.then_with(|| a.name.cmp(&b.name))
.then_with(|| a.path.cmp(&b.path))
.then_with(|| a.path_to_skills_md.cmp(&b.path_to_skills_md))
});
outcome
@@ -528,7 +528,7 @@ fn parse_skill_file(path: &Path, scope: SkillScope) -> Result<SkillMetadata, Ski
dependencies,
policy,
permissions,
path: resolved_path,
path_to_skills_md: resolved_path,
scope,
})
}
@@ -1049,7 +1049,7 @@ mod tests {
dependencies: None,
policy: None,
permissions: None,
path: normalized(&skill_path),
path_to_skills_md: normalized(&skill_path),
scope: SkillScope::User,
}]
);
@@ -1197,7 +1197,7 @@ mod tests {
}),
policy: None,
permissions: None,
path: normalized(&skill_path),
path_to_skills_md: normalized(&skill_path),
scope: SkillScope::User,
}]
);
@@ -1253,7 +1253,7 @@ interface:
dependencies: None,
policy: None,
permissions: None,
path: normalized(skill_path.as_path()),
path_to_skills_md: normalized(skill_path.as_path()),
scope: SkillScope::User,
}]
);
@@ -1587,7 +1587,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: normalized(&skill_path),
path_to_skills_md: normalized(&skill_path),
scope: SkillScope::User,
}]
);
@@ -1628,7 +1628,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: normalized(&skill_path),
path_to_skills_md: normalized(&skill_path),
scope: SkillScope::User,
}]
);
@@ -1682,7 +1682,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: normalized(&skill_path),
path_to_skills_md: normalized(&skill_path),
scope: SkillScope::User,
}]
);
@@ -1724,7 +1724,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: normalized(&skill_path),
path_to_skills_md: normalized(&skill_path),
scope: SkillScope::User,
}]
);
@@ -1769,7 +1769,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: normalized(&shared_skill_path),
path_to_skills_md: normalized(&shared_skill_path),
scope: SkillScope::User,
}]
);
@@ -1830,7 +1830,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: normalized(&skill_path),
path_to_skills_md: normalized(&skill_path),
scope: SkillScope::User,
}]
);
@@ -1867,7 +1867,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: normalized(&shared_skill_path),
path_to_skills_md: normalized(&shared_skill_path),
scope: SkillScope::Admin,
}]
);
@@ -1908,7 +1908,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: normalized(&linked_skill_path),
path_to_skills_md: normalized(&linked_skill_path),
scope: SkillScope::Repo,
}]
);
@@ -1976,7 +1976,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: normalized(&within_depth_path),
path_to_skills_md: normalized(&within_depth_path),
scope: SkillScope::User,
}]
);
@@ -2004,7 +2004,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: normalized(&skill_path),
path_to_skills_md: normalized(&skill_path),
scope: SkillScope::User,
}]
);
@@ -2036,7 +2036,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: normalized(&skill_path),
path_to_skills_md: normalized(&skill_path),
scope: SkillScope::User,
}]
);
@@ -2149,7 +2149,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: normalized(&skill_path),
path_to_skills_md: normalized(&skill_path),
scope: SkillScope::Repo,
}]
);
@@ -2185,7 +2185,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: normalized(&skill_path),
path_to_skills_md: normalized(&skill_path),
scope: SkillScope::Repo,
}]
);
@@ -2239,7 +2239,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: normalized(&nested_skill_path),
path_to_skills_md: normalized(&nested_skill_path),
scope: SkillScope::Repo,
},
SkillMetadata {
@@ -2250,7 +2250,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: normalized(&root_skill_path),
path_to_skills_md: normalized(&root_skill_path),
scope: SkillScope::Repo,
},
]
@@ -2290,7 +2290,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: normalized(&skill_path),
path_to_skills_md: normalized(&skill_path),
scope: SkillScope::Repo,
}]
);
@@ -2328,7 +2328,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: normalized(&skill_path),
path_to_skills_md: normalized(&skill_path),
scope: SkillScope::Repo,
}]
);
@@ -2370,7 +2370,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: normalized(&repo_skill_path),
path_to_skills_md: normalized(&repo_skill_path),
scope: SkillScope::Repo,
},
SkillMetadata {
@@ -2381,7 +2381,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: normalized(&user_skill_path),
path_to_skills_md: normalized(&user_skill_path),
scope: SkillScope::User,
},
]
@@ -2446,7 +2446,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: first_path,
path_to_skills_md: first_path,
scope: SkillScope::Repo,
},
SkillMetadata {
@@ -2457,7 +2457,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: second_path,
path_to_skills_md: second_path,
scope: SkillScope::Repo,
},
]
@@ -2529,7 +2529,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: normalized(&skill_path),
path_to_skills_md: normalized(&skill_path),
scope: SkillScope::Repo,
}]
);
@@ -2588,7 +2588,7 @@ permissions:
dependencies: None,
policy: None,
permissions: None,
path: normalized(&skill_path),
path_to_skills_md: normalized(&skill_path),
scope: SkillScope::System,
}]
);
+3 -2
View File
@@ -16,7 +16,8 @@ pub struct SkillMetadata {
pub policy: Option<SkillPolicy>,
// This is an experimental field.
pub permissions: Option<Permissions>,
pub path: PathBuf,
/// Path to the SKILLS.md file that declares this skill.
pub path_to_skills_md: PathBuf,
pub scope: SkillScope,
}
@@ -76,7 +77,7 @@ pub struct SkillLoadOutcome {
impl SkillLoadOutcome {
pub fn is_skill_enabled(&self, skill: &SkillMetadata) -> bool {
!self.disabled_paths.contains(&skill.path)
!self.disabled_paths.contains(&skill.path_to_skills_md)
}
pub fn is_skill_allowed_for_implicit_invocation(&self, skill: &SkillMetadata) -> bool {
+1 -1
View File
@@ -11,7 +11,7 @@ pub fn render_skills_section(skills: &[SkillMetadata]) -> Option<String> {
lines.push("### Available skills".to_string());
for skill in skills {
let path_str = skill.path.to_string_lossy().replace('\\', "/");
let path_str = skill.path_to_skills_md.to_string_lossy().replace('\\', "/");
let name = skill.name.as_str();
let description = skill.description.as_str();
lines.push(format!("- {name}: {description} (file: {path_str})"));
@@ -3559,7 +3559,7 @@ impl ChatComposer {
description,
insert_text: format!("${skill_name}"),
search_terms,
path: Some(skill.path.to_string_lossy().into_owned()),
path: Some(skill.path_to_skills_md.to_string_lossy().into_owned()),
category_tag: (skill.scope == codex_protocol::protocol::SkillScope::Repo)
.then(|| "[Repo]".to_string()),
});
+1 -1
View File
@@ -1495,7 +1495,7 @@ mod tests {
dependencies: None,
policy: None,
permissions: None,
path: PathBuf::from("test-skill"),
path_to_skills_md: PathBuf::from("test-skill"),
scope: SkillScope::User,
}]),
});
+7 -5
View File
@@ -4066,12 +4066,14 @@ impl ChatWidget {
.strip_prefix("skill://")
.unwrap_or(binding.path.as_str());
let path = Path::new(path);
if let Some(skill) = skills.iter().find(|skill| skill.path.as_path() == path)
&& selected_skill_paths.insert(skill.path.clone())
if let Some(skill) = skills
.iter()
.find(|skill| skill.path_to_skills_md.as_path() == path)
&& selected_skill_paths.insert(skill.path_to_skills_md.clone())
{
items.push(UserInput::Skill {
name: skill.name.clone(),
path: skill.path.clone(),
path: skill.path_to_skills_md.clone(),
});
}
}
@@ -4079,13 +4081,13 @@ impl ChatWidget {
let skill_mentions = find_skill_mentions_with_tool_mentions(&mentions, skills);
for skill in skill_mentions {
if bound_names.contains(skill.name.as_str())
|| !selected_skill_paths.insert(skill.path.clone())
|| !selected_skill_paths.insert(skill.path_to_skills_md.clone())
{
continue;
}
items.push(UserInput::Skill {
name: skill.name.clone(),
path: skill.path.clone(),
path: skill.path_to_skills_md.clone(),
});
}
}
+7 -7
View File
@@ -78,7 +78,7 @@ impl ChatWidget {
let display_name = skill_display_name(&core_skill).to_string();
let description = skill_description(&core_skill).to_string();
let name = core_skill.name.clone();
let path = core_skill.path;
let path = core_skill.path_to_skills_md;
SkillsToggleItem {
name: display_name,
skill_name: name,
@@ -191,7 +191,7 @@ fn protocol_skill_to_core(skill: &ProtocolSkillMetadata) -> SkillMetadata {
}),
policy: None,
permissions: None,
path: skill.path.clone(),
path_to_skills_md: skill.path.clone(),
scope: skill.scope,
}
}
@@ -229,23 +229,23 @@ pub(crate) fn find_skill_mentions_with_tool_mentions(
let mut matches: Vec<SkillMetadata> = Vec::new();
for skill in skills {
if seen_paths.contains(&skill.path) {
if seen_paths.contains(&skill.path_to_skills_md) {
continue;
}
let path_str = skill.path.to_string_lossy();
let path_str = skill.path_to_skills_md.to_string_lossy();
if mention_skill_paths.contains(path_str.as_ref()) {
seen_paths.insert(skill.path.clone());
seen_paths.insert(skill.path_to_skills_md.clone());
seen_names.insert(skill.name.clone());
matches.push(skill.clone());
}
}
for skill in skills {
if seen_paths.contains(&skill.path) {
if seen_paths.contains(&skill.path_to_skills_md) {
continue;
}
if mentions.names.contains(&skill.name) && seen_names.insert(skill.name.clone()) {
seen_paths.insert(skill.path.clone());
seen_paths.insert(skill.path_to_skills_md.clone());
matches.push(skill.clone());
}
}
+2 -2
View File
@@ -931,7 +931,7 @@ async fn submission_prefers_selected_duplicate_skill_path() {
dependencies: None,
policy: None,
permissions: None,
path: repo_skill_path,
path_to_skills_md: repo_skill_path,
scope: SkillScope::Repo,
},
SkillMetadata {
@@ -942,7 +942,7 @@ async fn submission_prefers_selected_duplicate_skill_path() {
dependencies: None,
policy: None,
permissions: None,
path: user_skill_path.clone(),
path_to_skills_md: user_skill_path.clone(),
scope: SkillScope::User,
},
]));