Annotate skill doc reads with skill names (#16813)

Addresses #16303

Problem: Skill doc reads render as plain `Read SKILL.md`, so the TUI
hides which skill was opened.

Solution: Best-effort annotate exact `SKILL.md` reads with the matching
loaded skill name from `skills_all` before rendering exec cells.

Before:
```
• Explored
  └ Read SKILL.md
```

After:
```
• Explored
  └ Read SKILL.md (pr-babysitter skill)
```
This commit is contained in:
Eric Traut
2026-04-06 08:51:34 -07:00
committed by GitHub
parent 4294031a93
commit f44eb29181
2 changed files with 31 additions and 3 deletions

View File

@@ -19,6 +19,7 @@ use codex_core::skills::model::SkillDependencies;
use codex_core::skills::model::SkillInterface;
use codex_core::skills::model::SkillMetadata;
use codex_core::skills::model::SkillToolDependency;
use codex_protocol::parse_command::ParsedCommand;
use codex_protocol::protocol::ListSkillsResponseEvent;
use codex_protocol::protocol::SkillMetadata as ProtocolSkillMetadata;
use codex_protocol::protocol::SkillsListEntry;
@@ -142,6 +143,31 @@ impl ChatWidget {
self.skills_all = skills;
self.set_skills(Some(enabled_skills_for_mentions(&self.skills_all)));
}
pub(crate) fn annotate_skill_reads_in_parsed_cmd(
&self,
mut parsed_cmd: Vec<ParsedCommand>,
) -> Vec<ParsedCommand> {
if self.skills_all.is_empty() {
return parsed_cmd;
}
for parsed in &mut parsed_cmd {
let ParsedCommand::Read { name, path, .. } = parsed else {
continue;
};
if name != "SKILL.md" {
continue;
}
// Best effort only: annotate exact SKILL.md path matches from the loaded skills list.
if let Some(skill) = self.skills_all.iter().find(|skill| skill.path == *path) {
*name = format!("{name} ({} skill)", skill.name);
}
}
parsed_cmd
}
}
fn skills_for_cwd(cwd: &Path, skills_entries: &[SkillsListEntry]) -> Vec<ProtocolSkillMetadata> {