feat: Cabinet-style skill installer in /skills UI#21
Merged
Conversation
Adds three daemon endpoints and an Install dialog so skills can be pulled from skills.sh / github.com / github:owner/repo[/skill] without leaving the UI. Backend (src/skills/): - import-source.ts: parser for skills.sh URL, github.com URL, and github:owner/repo[@/]skill shorthand. local: explicitly unsupported. - import.ts: previewSkill() hits the GitHub API + raw SKILL.md for the preview card; importSkill() shallow-clones, resolves the skill subtree (direct, /skills/, .claude-plugin manifest, recursive walk), copies with verbatimSymlinks. Tight ref whitelist guards `git clone --branch`. - lock.ts: data/skills-lock.json keyed by skill name; provenance survives restarts, drives the UI's source pill + uninstall button. Endpoints in src/server.ts: - POST /api/skills/preview, POST /api/skills/install, DELETE /api/skills/:key - GET /api/available-skills now returns each skill's lock entry - install can attach to one or more agents in a single call UI (ui/): - New SkillInstallDialog with paste-and-preview flow + agent attach toggles - /skills page gets an Install button; installed skills show source + uninstall confirm; post-install screen surfaces scanSkillDirectory findings inline (warnings never block install). 12/12 parser unit tests; smoke-tested install/list/uninstall against a local daemon (pdf skill from anthropics/skills). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
skills.sh redirects to www.skills.sh in the browser, so URLs the user pastes from the address bar were rejected with "unrecognized source format". Allow the optional www. prefix; add a regression test for the exact URL that surfaced this. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
/skillsthat pulls SKILL bundles from skills.sh, github.com URLs, orgithub:owner/repo[/skill]shortcodes — no shell needed/api/skills/preview,/api/skills/install,DELETE /api/skills/:key); install can optionally attach the skill to one or more agents in a single calldata/skills-lock.jsondrives the source pill + uninstall button on each installed-skill card; post-install screen surfacesscanSkillDirectoryfindings inline (warnings never block install)Implementation notes
src/skills/import-source.ts— parser for skills.sh (incl.www.), github.com URLs (/tree/<ref>aware), andgithub:owner/repo[@/]skillshorthand.local:paths intentionally unsupported.src/skills/import.ts— shallowgit clone --branch <ref>with a strict ref whitelist; resolves the skill subtree via direct path →/skills/<name>→.claude-plugin/plugin.json→ recursive walk; copies withverbatimSymlinksso a hostile bundle can't symlink out of the clone.src/skills/lock.ts— JSON lockfile, atomic-ish read/update/remove.src/server.ts;GET /api/available-skillsnow carries each skill's lock entry so the UI can render provenance without an extra round-trip.clearSkillCache()fires on install/uninstall.SkillInstallDialog(paste → preview → install) with agent-attach toggles;/skillspage gets uninstall confirm + source pill.Test plan
bun test src/skills/import-source.test.ts)npx tsc --noEmitclean (root + ui);next buildcleangithub:anthropics/skills/pdf→ file on disk, lockfile written, list endpoint returns provenance, uninstall cleans bothhttps://www.skills.sh/juliusbrussee/caveman/cavemanagainst live worktree daemon (the fix in 4c60b10)local:/etc/passwd(unknown source),ref=--upload-pack=evil(ref injection),DELETE /api/skills/..%2Fetc(traversal)🤖 Generated with Claude Code