feat: add per-project dev-shell skills placement (task 0003) #3
Reference in New Issue
Block a user
Delete Branch "task-0003-per-project-placement-dev-shell"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Task:
.claude/tasks/0003-per-project-placement-dev-shell.mdSummary
Adds the per-project placement output: a dev-shell helper that drops a project's selected skills into its own
.claude/skills/, plus the check that proves it.lib.mkSkillsShellHook(lib/mk-skills-shell-hook.nix) takes a list of selected skill derivations and returns a shellHook string. Selection is by derivation; the symlink name comes from each derivation's eval-timeskillName. The hook is plain POSIX shell needing no home-manager context..claude/skills/, pointing into the store. It is stateless: each entry first removes only store-pointing symlinks (deselected skills included), then relinks the current selection, so stale skills disappear with no manifest..claude/skills/.gitignoreis regenerated each entry, listing only the names the hook actually linked, so store symlinks stay out of git while hand-authored skills remain tracked.nix flake check(checks/shell-hook.nix) sources the produced hook against a fixture project across two selections and asserts the full lifecycle.Deviations
.gitignorecontents, and no state file. This is a strict superset that proves the spec-mandated lifecycle (criteria 3–7) rather than trusting a string match..gitignorecorrectness was tightened during implementation: a skill skipped due to a name collision is kept out of the managed set, so it is never gitignored and the hand-authored directory stays tracked. Only actually-linked skills are listed.Review
Risk
Overall: Medium
flake.nix'sliboutput and checks; no existing behavior altered.nix flake checkfixture exercising linking, stale-removal, collision-skip, hand-authored safety, and.gitignoreregeneration across two successive selections.rm -fon symlinks under a developer's.claude/skills/on every shell entry; deletion logic near real files warrants care, though it is guarded to store-pointing symlinks only.Unaddressed findings
Standards
skillNameinto the shell string would break on a name containing a single quote (judgement, latent). Left as-is: skill names are kebab-case by convention, and hardening the charset belongs to the content tier, not this helper.readlinkis used to classify symlinks and is not strictly POSIX (judgement). Left as-is: it is present on every Nix-based machine this targets and has no clean substitute; the non-POSIXln -nflag was removed in response to review.Spec