Skip to content

feat(setup): enumerate managed skills from repo checkout - #130

Merged
emp3thy merged 1 commit into
mainfrom
feat/dynamic-skill-enumeration
Aug 31, 2026
Merged

feat(setup): enumerate managed skills from repo checkout#130
emp3thy merged 1 commit into
mainfrom
feat/dynamic-skill-enumeration

Conversation

@emp3thy

@emp3thy emp3thy commented Aug 31, 2026

Copy link
Copy Markdown
Owner

Summary

Replaces the hardcoded MANAGED_SKILLS tuple with dynamic enumeration: manifest.managed_skills(repo_root) scans <repo>/.claude/skills/*/SKILL.md. Any skill added to the repo is registered at user level (~/.claude/skills) on the next session's autocheck with no code change; a skill removed from the repo has its user-level link pruned.

Changes

  • manifest.pyMANAGED_SKILLS constant deleted; managed_skills(repo_root) enumerates skill dirs (sorted, so fingerprint() stays deterministic — a repo skill add/remove invalidates the autocheck cache for free).
  • engine.pyrender() / diff() / install_skills() consume the enumeration. New _stale_repo_skill_links(): links in the user skills dir that target the repo skills tree but whose name left the managed set are pruned by install_skills() and reported as drift by diff() (needed so autocheck's if drift: guard triggers the pruning apply). Foreign entries — user's own skill dirs, links targeting anywhere else — are never touched.
  • autocheck.py_mtimes() now stats skills_dir: a manually deleted skill link busts the fingerprint cache and gets relinked next session.
  • Docs — README + website/architecture.md updated ("three skills" prose → enumeration + prune behavior).

Testing

  • 8 new tests (manifest enumeration ×3, engine pickup/prune/foreign-preservation/diff-stale ×4, autocheck cache-bust ×1). New engine tests fall back to mklink /J junctions so they run on Windows without symlink privilege.
  • Full unit suite: 1728 passed. Setup e2e + canary-home: 9 passed (canary pins foreign user skills untouched).

🤖 Generated with Claude Code

https://claude.ai/code/session_01QMxQKgsP9Dw9b5kN53MJfo

Replace the hardcoded MANAGED_SKILLS tuple with
manifest.managed_skills(repo_root), which scans
.claude/skills/*/SKILL.md. A skill added to the repo is linked into
~/.claude/skills on the next session's autocheck with no code change;
a skill removed from the repo has its user-level link pruned (foreign
entries are never touched — only links targeting the repo skills tree).

- diff() reports stale repo-targeted links as drift, so autocheck's
  if-drift guard triggers the pruning apply()
- autocheck._mtimes() now stats skills_dir: a manually deleted link
  busts the fingerprint cache and is relinked next session
- enumeration is sorted, so fingerprint() stays deterministic and a
  repo skill add/remove invalidates the cache for free

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QMxQKgsP9Dw9b5kN53MJfo

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Claude BugBot Analysis

Reviewed the migration from a static MANAGED_SKILLS tuple to dynamic managed_skills() enumeration plus the new stale-link pruning logic in engine.py/manifest.py/autocheck.py; all call sites, the fingerprint/mtime cache-invalidation reasoning, and the prune/unlink fallback logic (consistent with the existing symlink/junction removal pattern) check out with no concrete defects found.

No bugs were detected in this PR.

@emp3thy
emp3thy merged commit 7994e61 into main Aug 31, 2026
3 checks passed
@emp3thy
emp3thy deleted the feat/dynamic-skill-enumeration branch August 31, 2026 19:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant