[BUG] Tab autocomplete completes skill names to dash form, losing argument-hint rendering vs. colon form
Summary
Tab autocomplete for slash commands matches the skill directory basename (dash form) instead of the name: field declared in SKILL.md frontmatter. When a skill uses a colon-separated name: (e.g. t1k:git), the two forms behave inconsistently:
| Form | How produced | Argument-hint shown? |
|---|---|---|
| /t1k:git | typed manually | ✅ yes |
| /t1k-git | inserted by Tab | ❌ no |
Both forms execute the same skill, but only the colon form triggers argument-hint rendering and parameter suggestion UI. This makes Tab autocomplete a discoverability regression: it actively hides hints the user would get by typing manually.
Environment
- Claude Code:
2.1.145 - Node:
v24.13.0 - Platform: Linux (also reproduced by team on macOS; Windows blocked by separate filesystem constraint, see below)
Repro
- Create a skill with colon-namespaced
name:in frontmatter:
````
~/.claude/skills/t1k-git/SKILL.md
---
name: t1k:git
description: Git operations with conventional commits.
argument-hint: <cm|cp|pr|merge> [args...]
---
(Directory MUST be dash because : is hostile to Windows NTFS and shell globs — see "Why two forms" below.)
- In the Claude Code prompt, type
/t1k:and press <kbd>Tab</kbd>.
- Expected: autocomplete inserts
/t1k:gitand shows theargument-hintparameter suggestions.
- Actual: autocomplete inserts
/t1k-git(the filesystem directory name). No argument-hint is displayed. Typing/t1k:gitby hand instead works correctly.
Root cause hypothesis
The slash-command completion engine globs ~/.claude/skills/*/ directory names rather than reading the name: field from each SKILL.md. The dispatcher that runs the skill DOES read name: (both forms resolve), but the completion candidate list is filesystem-driven.
Why we use two forms (and why "just rename the directory" isn't viable)
The TheOneKit ecosystem (~326 skills across 9 repos, used by ~50 internal developers) enforces this rule:
- Filesystem directory uses dash (
t1k-git/) — because:is reserved on Windows NTFS (alternate data streams), breaks shell globs (ls *:*), and confuses many tools. - SKILL.md
name:uses colon (t1k:git) — because that is how the Claude Code slash UI renders namespaced skills, and it's the form documented in the skills guide examples for namespaced commands.
The two slugs are byte-identical after -↔: conversion. Renaming the directory to use : is not an option for cross-platform kits.
Suggested fix
Change the autocomplete resolver to enumerate completion candidates from each SKILL.md's name: frontmatter field (with fallback to directory basename when name: is missing). The execution path already handles both forms correctly — only the completion list needs updating.
Rough pseudocode for the change:
// Before (hypothetical):
const candidates = fs.readdirSync(skillsDir);
// After:
const candidates = fs.readdirSync(skillsDir).map(dir => {
const skillMd = path.join(skillsDir, dir, 'SKILL.md');
const fm = parseFrontmatter(skillMd);
return fm.name || dir; // prefer declared name, fall back to dirname
});
Related issues (all closed, but adjacent)
- #9768 — Tab autocomplete for slash commands broken in v2.0.0+ (VSCode extension)
- #20667 — Keep argument-hint visible while typing
- #18574 — argument-hint not included in Skill tool metadata for agent-to-agent invocation
- #43401 — Feature: Support argument-hint in Skills YAML frontmatter
None of those track this specific dash/colon completion mismatch.
Impact
- Every skill that uses colon-namespaced
name:is affected (TheOneKit alone has ~326 such skills). - Affects discoverability for new users: Tab inserts the form WITHOUT hints, training people away from the form that has them.
- No local workaround exists — Claude Code is closed-source,
settings.jsonhas no autocomplete hook,~/.claude/keybindings.jsononly remaps keys, and:-named symlinks don't work cross-platform.
Workaround (until fixed)
Type the colon form manually and don't accept Tab completions for skill names. Painful at scale.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗