Repository navigation
Refresh Skills After a Release Without Moving the Claude Marketplace - #2020
Conversation
`claude plugin marketplace add` silently re-points an existing registration at whichever checkout runs the installer, so a release refresh run from a worktree left Claude Code loading a tree that was then removed. The installer now reads the listing first and leaves a registration from another existing directory in place, printing the command that moves it. A new --snapshot-only mode refreshes the Codex/opencode copy without touching the registration, and merge-and-release step 7 runs it from a detached worktree at origin/main instead of switching the primary checkout to main. Fixes #2017 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A github source always lists its cache directory, so the check now reads the source type rather than whether a location is present, and a cleared cache no longer converts it. A registered directory that cannot be stat'd is kept rather than raising after the copy was already written, and replacing a dead registration prints both paths. Step 8 of merge-and-release no longer assumes step 7 left the base clone on main, and scripts/README.md now states the registration rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Path.is_dir() stopped raising for an unreadable path on Python 3.14, so an unreadable registered checkout read as gone and was moved. The check now reads os.stat, treating only a missing path as gone, and the path comparison no longer raises on a symlink loop before 3.13. The unreadable-directory test uses a real locked directory. check-this-repo and skill-lifecycle step 8 now refresh with --snapshot-only, since both run from a fetched checkout that the Claude Code registration should not move to. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
--report still read the registered directory with Path.is_dir(), so a symlink loop read as missing while the installer kept it, and an unreadable path crashed the report step 7 runs after the install. It now uses directory_gone(), and the bootstrap-tree check no longer raises on an unreadable path. A path carrying a NUL byte is kept rather than raising ValueError, and the registration docstring now says a gone directory's move is announced. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Repository: ptr727/ProjectTemplate/.coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #2020 +/- ##
===========================================
+ Coverage 55.29% 55.66% +0.36%
===========================================
Files 16 16
Lines 7266 7317 +51
===========================================
+ Hits 4018 4073 +55
+ Misses 3248 3244 -4
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
It changes a fleet-wide release procedure and the core Skills installer with subtle git-worktree and marketplace-registration semantics that warrant final human verification.
Review effort: Balanced
Findings: None
What changed in this PR
This PR fixes a side effect in the fleet's Skills installer (scripts/skills_install.py): because claude plugin marketplace add silently re-points an existing marketplace registration to whatever directory runs the script, refreshing Skills from a temporary worktree moved Claude Code's registered source there, and removing that worktree left Claude Code loading Skills from a directory that no longer existed. The change makes registration listing-aware and adds a snapshot-only refresh mode, then updates the release/self-check procedures to use it. It fits the repository's role as the fleet hub, where these installer and skill-doc changes propagate to every downstream repo.
Changes:
register_claude_marketplace()now reads the CLI listing first (existing_registration()), and only moves a directory registration whose directory is gone (or re-adds from the same checkout); any other registration is left in place with the move command printed, and a missing listing registers nothing and exits non-zero.- New
--snapshot-onlymode refreshes only the Codex/opencode copy and stamp without touching the Claude registration;live_channel()andis_bootstrap_tree()are hardened to judge unreadable/gone paths without crashing. merge-and-releasestep 7/8,check-this-repo, andskill-lifecycleare updated to refresh via a detached worktree with--snapshot-only, and the docs (scripts/README.md,docs/host-setup.md,host-setup/README.md) describe the new behavior.
| File | Description |
|---|---|
| scripts/skills_install.py | Adds directory_gone/same_directory/existing_registration/install_claude_plugin helpers, --snapshot-only, and listing-aware registration; hardens is_bootstrap_tree and live_channel. |
| tests/test_skills_install.py | Adds RegisterCase plus live-channel and snapshot-only tests covering the new registration branches and edge cases. |
| scripts/README.md | Documents listing-aware registration and --snapshot-only. |
| docs/host-setup.md | Notes registration is left in place and adds the --snapshot-only usage line. |
| host-setup/README.md | Reworks "never replaces" to "never moves a registration whose directory still exists". |
| .agents/skills/merge-and-release/SKILL.md | Rewrites step 7 to use a detached worktree + --snapshot-only, and step 8 to stop assuming the base clone was left on main. |
| .agents/skills/skill-lifecycle/SKILL.md | Step 8 refresh now uses --snapshot-only. |
| .agents/skills/check-this-repo/SKILL.md | Safe-to-fix re-run now uses --snapshot-only. |
| .github/skills/* , .claude-plugin/fleet-skills/* , .source-digests/* | Generated mirrors of the three edited source skills and their regenerated digests. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…g the Claude Marketplace (#2021) ## Summary Promotes develop to main, carrying [#2020](#2020). That PR stops `scripts/skills_install.py` from quietly moving Claude Code's marketplace registration to whichever checkout runs it. The installer now reads the CLI's listing first and moves a registration only when its directory is gone, saying so when it does. A new `--snapshot-only` mode refreshes the Codex/opencode copy without touching the registration. `merge-and-release` step 7 now refreshes from a detached worktree at `origin/main` with that mode instead of switching a checkout to `main`, and `check-this-repo` and `skill-lifecycle` use it for their refreshes too. Closes #2017 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Summary
Addresses #2017.
claude plugin marketplace addre-points an existing registration without failing, so runningscripts/skills_install.pyfrom a worktree moved Claude Code's registered source there, and removing the worktree left Claude Code loading Skills from nowhere.--snapshot-onlymode. It refreshes the Codex/opencode copy and its stamp without touching the registration.merge-and-releasestep 7 now runs--snapshot-onlyfrom a detached worktree atorigin/maininstead of switching a checkout tomain. Step 8 no longer assumes the base clone was left onmain.check-this-repo's safe-to-fix re-run andskill-lifecyclestep 8 use--snapshot-onlytoo.--report's live channel judges the registered directory the same way the installer does, so an unreadable path no longer crashes the report that step 7 runs.scripts/README.md,docs/host-setup.md, andhost-setup/README.mddescribe the new behavior.Follow-up gaps deferred to #2019.
Verification
tests/test_skills_install.py: 71 tests pass on Python 3.11 through 3.14. The file needed 3.11 before this branch. The locked-directory and symlink-loop cases use real filesystem state rather than a mock, becausePath.is_dir()changed behavior in 3.14.spec/validate.py,build_dist.py --check, markdownlint, editorconfig-checker, and cspell all pass.local-strict-reviewpasses ran. The findings still open after the last one are in Close the Installer Gaps Left After the Marketplace Re-Point Fix #2019.🤖 Generated with Claude Code