The read_skill tool validates that requested paths are within a skills
directory by canonicalizing the input path and checking it starts with
the skills root. However, when skills are symlinks (e.g. pointing to
~/.config/zed/superpowers/skills/), canonicalization resolves the symlink
to its target, which no longer starts with the non-canonicalized skills
root.
Fix by also canonicalizing the skills root paths before the starts_with
check, so symlink targets are correctly recognized as being within the
skills directory.
Also update skills_prompt.hbs to reference the read_skill tool instead
of read_file/list_directory, which are project-scoped and cannot access
the global skills directory.
@@ -311,13 +311,18 @@ pub fn is_skills_path_canonical(
worktree_roots: &[PathBuf],
) -> Option<PathBuf> {
let global_skills_root = global_skills_dir();
- if canonical_input.starts_with(&global_skills_root) {
+ // Canonicalize the skills roots so that symlinks within the skills directory
+ // resolve to paths that still pass the `starts_with` check.
+ let canonical_global = std::fs::canonicalize(&global_skills_root).unwrap_or(global_skills_root);
+ if canonical_input.starts_with(&canonical_global) {
return Some(canonical_input.to_path_buf());
}
for worktree_root in worktree_roots {
let worktree_skills_path = worktree_root.join(".agents").join("skills");
- if canonical_input.starts_with(&worktree_skills_path) {
+ let canonical_worktree =
+ std::fs::canonicalize(&worktree_skills_path).unwrap_or(worktree_skills_path);
+ if canonical_input.starts_with(&canonical_worktree) {
return Some(canonical_input.to_path_buf());
}
}
@@ -11,18 +11,7 @@ Each skill contains:
- `references/` - Additional documentation
- `assets/` - Templates, data files, images
-To use a skill, you should use the read_file and list_directory tools to explore skill files, and only use bash for running executable scripts:--**For reading and exploring (use internal tools):**-- Read SKILL.md: `read_file` with path `~/.config/zed/skills/<skill-name>/SKILL.md`-- List skill references: `list_directory` with path `~/.config/zed/skills/<skill-name>/references/`-- List skill scripts: `list_directory` with path `~/.config/zed/skills/<skill-name>/scripts/`-- Read references: `read_file` with path `~/.config/zed/skills/<skill-name>/references/doc.md`--**For running scripts only (use bash):**-- Run scripts: `bash ~/.config/zed/skills/<skill-name>/scripts/script.sh`--Note: You typically want to run tools for the current project you're working on, which is why you should use your worktree root as the working directory.
+To use a skill, first read its SKILL.md file, then explore its resources as needed.
| Skill | Description | Location |
|-------|-------------|----------|
@@ -31,9 +20,9 @@ Note: You typically want to run tools for the current project you're working on,
{{/each}}
When a skill is relevant to the user's request:
-1. **Always start here:** Read SKILL.md to load the skill's instructions using `read_file` with path `~/.config/zed/skills/<skill-name>/SKILL.md`
+1. **Always start here:** Read SKILL.md to load the skill's instructions using `read_skill` with path `~/.config/zed/skills/<skill-name>/SKILL.md`
2. **Then, based on the instructions in SKILL.md and the user's specific needs:**
- - Use `list_directory` to explore available resources- - Use `read_file` to read reference files
+ - Use `read_skill` to explore available resources
+ - Use `read_skill` to read reference files
- Use `bash` only to run executable scripts
{{/if}}