Skip to content

Plugin skill silently dropped from /skills list despite "Installed N skills" confirming load #3546

Closed

Description

@shinyay

Describe the bug

Installing my plugin shinyay/tokopt-skills (9 skills + 2 agents) reports Installed 9 skills, and copilot plugin list confirms registration, but /skills list consistently shows only 8 of the 9 skills. The missing skill is exactly the same one every time: slim-apply. The other 8 (antipattern-scan, heavy-tail, hygiene-coach, prompt-anatomy, prompt-optimizer, slim-rewind, slim-suggest, token-audit) appear correctly.

Verified:

  • ✅ On disk: ~/.copilot/installed-plugins/_direct/shinyay--tokopt-skills/skills/slim-apply/SKILL.md exists, well-formed (3452 B, ASCII frontmatter, no BOM)
  • ✅ Install log says Installed 9 skills → loader sees it
  • ❌ /skills list shows 8/9 → display/filter layer drops one
  • ❌ Cwd-shadowing ruled out — same result from /tmp (outside repo) and from inside the repo
  • ❌ Description length ruled out — slim-apply is 346 chars, well within range of visible skills (233–357 chars)
  • ❌ Frontmatter formatting ruled out — identical structure (just name: + description:) to the 8 visible skills

Repro repo: https://github.com/shinyay/tokopt-skills (public, v0.1.0)

Affected version

GitHub Copilot CLI 1.0.55-6.

Steps to reproduce the behavior

copilot plugin install shinyay/tokopt-skills
# → "Plugin "tokopt-skills" installed successfully. Installed 9 skills."

copilot plugin list | grep tokopt
# → "  • tokopt-skills (v0.1.0)"

ls ~/.copilot/installed-plugins/_direct/shinyay--tokopt-skills/skills/
# → 9 entries including slim-apply/

Then in an interactive copilot session:

/skills list

Count entries in the plugin: section that belong to tokopt-skills. Result: 8 entries, slim-apply missing.

Expected behavior

/skills list should show all 9 skills from the plugin, including slim-apply, matching the loader's Installed 9 skills count.

Additional context

Workarounds attempted (none worked):

  1. Uninstall + reinstall — same 8/9
  2. Edited SKILL.md to rename ## DO NOT → ## Guardrails and Destructive. → Note: (in case a safety-keyword filter was matching) — still 8/9
  3. Cleared a stale duplicate directory _direct/tokopt-skills/ left over from an earlier local-path install — caused all 9 to disappear; re-established via symlink to recover the 8/9 state (separate-but-related quirk: the loader appears to resolve plugin dir by plugin-manifest name, not by <org>--<repo> directory name)

Description content of slim-apply (in case the filter is keyword-based):

Apply tokopt slim's compression IN-PLACE after the user has reviewed a slim-suggest preview AND explicitly approved. Writes compressed output back to disk with full safety: requires clean git tree, refuses symlinks, detects races. Use ONLY when the prior turn ran slim-suggest for the SAME single file. Never for first-pass analysis.

It is the only skill in the plugin whose description references another skill by name (slim-suggest, twice). Could /skills list be deduplicating or filtering based on cross-references in descriptions?

Environment:

  • OS: Linux (WSL2, kernel 6.6.114.1-microsoft-standard)
  • Arch: x86_64
  • Node: v22.22.0
  • Shell: bash
  • Terminal: VS Code Insiders integrated terminal

Related quirk (separate finding from the same investigation):

When a plugin is installed from a GitHub repo shorthand (e.g., copilot plugin install shinyay/tokopt-skills), the plugin is unpacked to ~/.copilot/installed-plugins/_direct/shinyay--tokopt-skills/, but /skills list only sees the skills if a _direct/<plugin-manifest-name>/ directory (without the <org>-- prefix) is also present. Removing the orphan unprefixed directory leaves only the prefixed one, and the loader then loads 0 skills from the plugin, even though copilot plugin list still reports it as installed. A symlink _direct/tokopt-skills -> shinyay--tokopt-skills restores the loader. This suggests the plugin-name → directory resolution may not be handling the gh-shorthand naming convention consistently.

Activity

  1. added
    area:pluginsPlugin system, marketplace, hooks, skills, extensions, and custom agents
    on May 28, 2026
  2. added theissue type on May 28, 2026
  3. shinyay commented on May 31, 2026

    @shinyay
    Author

    Follow-up on CLI 1.0.57-2 (re-tested 2026-05-31)

    Re-tested on a fresh CLI build (GitHub Copilot CLI 1.0.57-2) using the same shinyay/tokopt-skills v0.1.0 plugin. Half the symptoms are fixed, half persist. Sharing data to help triage.

    Re-test matrix

    Test 1.0.55-6 (original report) 1.0.57-2 (today)
    Plugin install via copilot plugin install shinyay/tokopt-skills works, unpacks to _direct/shinyay--tokopt-skills/ same
    Skills loaded WITHOUT _direct/<bare-name> symlink 0/9 (loader couldn't find anything) 8/9 ✅
    Skills loaded WITH _direct/tokopt-skills -> shinyay--tokopt-skills symlink 8/9 (slim-apply missing) 8/9 (slim-apply missing)
    Missing skill slim-apply (always the same one) slim-apply (always the same one)

    So:

    1. ✅ The gh-shorthand directory-resolution quirk is fixed in 1.0.57-2. The symlink workaround mentioned at the bottom of the original report is no longer needed. I confirmed this by removing the symlink and running a non-interactive copilot -p '…list skills…' query — 8 of 9 still loaded. Looking at the loader code path (installFromRepo → getDirectSourceId → stores cache_path: '…/_direct/<owner>--<repo>' → getInstalledPluginSkillDirs reads o.cache_path first), the resolution is now cache_path-based and works correctly.
    2. ❌ The primary symptom — slim-apply being silently dropped from /skills list despite Installed 9 skills confirming load — still reproduces in 1.0.57-2, identically. All 8 non-slim-apply skills appear; slim-apply does not. Re-confirmed ~/.copilot/installed-plugins/_direct/shinyay--tokopt-skills/skills/slim-apply/SKILL.md is present, well-formed, frontmatter intact.

    Repro on 1.0.57-2

    copilot --version
    # GitHub Copilot CLI 1.0.57-2.
    
    # (Plugin already installed; no symlink in _direct/)
    ls ~/.copilot/installed-plugins/_direct/
    # shinyay--awesome-shinyay-skills/
    # shinyay--tokopt-skills/
    
    ls ~/.copilot/installed-plugins/_direct/shinyay--tokopt-skills/skills/ | wc -l
    # 9
    
    copilot -p 'List all available skills from the tokopt-skills plugin only. Comma-separated names only.' --allow-all-tools
    # antipattern-scan, heavy-tail, hygiene-coach, prompt-anatomy,
    # prompt-optimizer, slim-rewind, slim-suggest, token-audit
    # (8 — slim-apply still missing)

    Adjacent concern: namespace collision in /skills list

    While re-verifying, a related design gap surfaced. The loader now keeps _direct/<owner>--<repo>/ as the install dir (good — namespace-safe at the filesystem level), but /skills list displays skills by bare name (prompt-optimizer), with no <plugin>: or <owner>/<repo>: prefix. Agents already render as <plugin-name>:<agent-name> (e.g., tokopt-skills:prompt-optimizer); skills do not. So if two plugins each ship a skill named prompt-optimizer, users would see two identical rows with no way to disambiguate which one is being invoked.

    Suggested follow-on (separate issue if preferred):

    • Either always prefix skills with <plugin-name>: in /skills list, matching the agent convention, or
    • Detect collisions and qualify only on collision (less verbose, but inconsistent with agents).

    Suggested next steps

    • For the primary bug (this issue): would it be helpful for me to attach a minimal repro plugin (single skill that reliably reproduces the drop) so the filter logic can be bisected? I have a strong hunch the filter is keyword/content based on the SKILL.md description text — slim-apply is the only one in the plugin whose description references another skill by name (slim-suggest, twice), uses strongly directive language (IN-PLACE, ONLY, Never), and has destructive-operation framing. Happy to construct a reduced test corpus.
    • The "needs symlink workaround" caveat in the original report can be marked stale for 1.0.57+ — I'll update my plugin's README to reflect this.

    Environment for re-test: Linux (WSL2), Node v22.22.0, GitHub Copilot CLI 1.0.57-2.

  4. patniko commented on Oct 26, 2026

    @patniko
    Collaborator

    Thanks for the thorough investigation and follow-up. The plugin directory-resolution problem was fixed in v1.0.57 (as your re-test confirmed), and the missing slim-apply skill turned out to be a YAML parse error in its frontmatter (the unquoted : in the description), which you've since fixed in the plugin; to keep failures like this from being silent, copilot skill list has surfaced skill loading errors and warnings since Copilot CLI v1.0.69. On naming, skills that collide across plugins are listed as <plugin>:<skill>, and #5249 covers resolving the qualified form for uniquely named plugin skills. If a valid skill still goes missing on the latest version, feel free to reopen.

    Triaged as part of a Copilot SDK backlog review, with help from GitHub Copilot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:pluginsPlugin system, marketplace, hooks, skills, extensions, and custom agents

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions