[Bug] sk update always fails 'no SKILL.md in source' for git sources — install stores subpath=skillName instead of the real path

Aperta
#133 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

@tridev-tej ci sta già lavorando.

Dal 14/10/2026.

  • #157 di @tridev-tej — aperta

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
68/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Tranquilla
Stack tecnologico
git, typescript
Ambito
cli, devtools

Direzione di ricerca

Start with src/commands/install.ts and src/commands/update.ts, tracing how discoverSkills provides skill.path and how that value is stored and later joined. Reproduce with a git source whose skill is nested or at the repository root, then verify that updates resolve the actual SKILL.md. The change is done when metadata records the discovered relative path, root-level skills use an empty path correctly, and the documented update commands succeed.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Summary

sk update <name> is broken for every GitHub/git-sourced skill: it always fails with <name>: no SKILL.md in source and skips the update. The root cause is that install persists subpath: skillName unconditionally, while the skill almost never lives at <repo-root>/<skillName>/SKILL.md. update then trusts that wrong subpath and looks in the wrong directory.

Version: [email protected], @skillkit/[email protected] (latest on npm).

Root cause

Install writes the metadata with a hardcoded subpath equal to the skill name, regardless of where the skill was actually discovered (@skillkit/cli, src/commands/install.ts; in the published bundle dist/index.js:~2920):

const metadata = {
  name: skillName,
  source: this.source,
  sourceType: providerAdapter.type,
  subpath: skillName,        // <-- always the skill name, not the real path
  ...
};

But discovery (@skillkit/core discoverSkills, dist/index.js:~3969) sets skill.path to the actual location of the skill, which can be:

  • the repo root (<root>/SKILL.md),
  • a nested dir (<root>/skills/<name>/SKILL.md, e.g. anthropics/skills),
  • something else entirely.

skill.name comes from the SKILL.md frontmatter name:, not from the directory.

Update then applies the recorded subpath literally (@skillkit/cli, src/commands/update.ts; dist/index.js:~3187):

const sourcePath = metadata.subpath ? join(result.path, metadata.subpath) : result.path;
const skillMdPath = join(sourcePath, "SKILL.md");
if (!existsSync(skillMdPath)) {
  s.stop(colors.warning(`${skill.name}: no SKILL.md in source`));
  // ...skipped
}

So for a skill discovered at <root>/skills/pdf/SKILL.md, subpath is stored as "pdf", and update looks for <clone>/pdf/SKILL.md — which does not exist. The only layout where the stored subpath happens to be correct is <root>/<name>/SKILL.md (a top-level dir named exactly after the frontmatter name, with no wrapper dir and no root-level SKILL.md), which is rare in practice.

Reproduction / evidence

sk update <name> --force (the --force bypasses the GitHub "no changes detected" short-circuit so the SKILL.md existence check is actually reached) on skills from 5 unrelated sources — all fail:

Skill Source repo Real layout stored subpath sk update --force
pdf anthropics/skills skills/pdf/SKILL.md pdf ❌ no SKILL.md in source
agent-browser vercel-labs/agent-browser — agent-browser ❌
linear-list Finesssee/linear-cli — linear-list ❌
ui-ux-pro-max nextlevelbuilder/ui-ux-pro-max-skill src/ + skill.json ui-ux-pro-max ❌
agent-mobile jeanpfs/agent-mobile SKILL.md at root agent-mobile ❌

Steps:

sk install anthropics/skills --all --global -y    # installs pdf, etc.
sk update pdf --force
# => "pdf: no SKILL.md in source"  (Updated: 0, Skipped: 1)

Note: without --force, GitHub-sourced skills often print no changes detected (the activity short-circuit at the top of the update loop returns before the clone+SKILL.md check), which masks the bug and can read as success — this may be why #128 reports that individual sk update <name> "works".

Proposed fix

Store the real relative subpath at install time instead of the skill name:

// install: derive from where the skill was actually discovered
subpath: path.relative(cloneResult.path, skill.path),  // "" for root, "skills/pdf" for nested

With subpath: "" for a root-level skill, the existing metadata.subpath ? join(clone, subpath) : clone in update resolves to the clone root correctly.

Optionally, make update resilient: if join(clone, subpath)/SKILL.md is missing, fall back to re-running discovery on the clone and matching by name before giving up.

Related

  • #128 — bulk sk update reporting Updated: 0 with ghost entries. Likely the same underlying subpath mismatch; the per-skill no changes detected short-circuit masks it as "individual update works".
Lingua principale
TypeScript
Stelle
1.6k
Fork
156
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di rohitg00/skillkit

Tutte le issue di rohitg00/skillkit

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.