feat(skills): per-skill install/uninstall + approve/reject + list --filter#56
Merged
Merged
Conversation
Adds four new subcommands plus a --filter flag on `skills list`:
promptconduit skills install <name> [--scope project|global] [--force]
promptconduit skills install --all
promptconduit skills uninstall <name> [--force]
promptconduit skills uninstall --all
promptconduit skills approve <name>
promptconduit skills reject <name>
promptconduit skills list --filter new|ready|removed|all
Targets the Claude Code skill-bundle path (.claude/skills/<name>/SKILL.md),
not the slash-command path (.claude/commands/<name>.md) that bulk `sync`
writes. Skills installed this way auto-load via the Skill tool on trigger
phrases instead of needing /<name> at the prompt.
New internal/skills package provides:
- Manifest (~/.config/promptconduit/skills-installed.json) — source of
truth for what we wrote. Records id, name, scope, install time, sha256
per file. Atomic writes via CreateTemp + Rename.
- ResolveScope — project (in current git repo) vs global routing, with
auto-detect when --scope is unset.
- ValidateName — enforces the Anthropic ^[a-z0-9-]{1,64}$ rule before
any filesystem operation.
Safety guarantees:
- Re-install at the same sha is a no-op
- Re-install over a hand-edited file prompts (or fails on non-TTY) unless
--force is given
- Uninstall refuses to delete a file whose on-disk sha doesn't match the
manifest record, unless --force is given
- Skills not in the manifest are never touched by uninstall, even
with --force
- Manifest writes are atomic; --all batches save once at end so a
crash mid-batch leaves a consistent record
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
Four new subcommands and a new
--filterflag bringpromptconduit skillsto parity with the web UI's per-skill controls. Targets the skill-bundle path (.claude/skills/<name>/SKILL.md) which auto-loads via the Skill tool on trigger phrases — distinct from the slash-command path that bulksyncwrites.Backed by:
internal/skillspackage (Manifest, ResolveScope, ValidateName) — atomic file writes (CreateTemp + Rename), single source of truth at~/.config/promptconduit/skills-installed.json.client.GetSkills/client.ApproveSkill/client.GetSkillCommandFile— no API client surface change.Why a separate skill-bundle path
The web UI explicitly says "Save each download to
.claude/skills/<name>/SKILL.md" and the API returnsX-Skill-Suggested-Pathmatching that. Existingsyncwrites the slash-command form at.claude/commands/<name>.md. Both are valid Claude Code features but address different UX (auto-trigger vs typed/foo). This PR adds the bundle form without changingsync.Behavior contract
install foowhen not on servernot foundinstall foofreshinstall fooat same shaalready up to dateinstall fooafter hand-edit, no --forceinstall foo --forceover editsinstall --alluninstall foocleanuninstall fooafter hand-edit, no --forcelocal modificationsuninstall foo --forceuninstall foo, not in manifestnot trackeduninstall --alllist --filter ready/removed/new/allOut of scope (deferred)
reference/*.md,scripts/*) — needs platform changes to bundle generation + R2 storage. Manifest array shape is forward-compatible.Test plan
make test— all packages green (29 new tests)make lint— no new issues introduced by this PRmake build— cleanapprove→install→ file landed at correct path with manifest entry →uninstall→ file gone, manifest cleared →rejectto revert stateAfter merge: tag v0.3.5 (patch bump, additive). GoReleaser + homebrew-tap will auto-update.