Skip to content

Refresh Skills After a Release Without Moving the Claude Marketplace - #2020

Merged
ptr727 merged 4 commits into
developfrom
feature/skills-refresh-snapshot-only
Sep 29, 2026
Merged

ptr727 merged 4 commits into
developfrom
feature/skills-refresh-snapshot-only

Conversation

@ptr727

@ptr727 ptr727 commented Sep 29, 2026

Copy link
Copy Markdown
Owner

Summary

Addresses #2017. claude plugin marketplace add re-points an existing registration without failing, so running scripts/skills_install.py from a worktree moved Claude Code's registered source there, and removing the worktree left Claude Code loading Skills from nowhere.

  • The installer reads the listing before it adds. It moves a registration only where it is a directory source whose directory is gone, and says so. Every other registration, including one from another existing checkout, a non-directory source, or an unreadable path, is left in place with the command that moves it printed. Where the CLI gives no listing, the installer registers nothing and exits non-zero.
  • New --snapshot-only mode. It refreshes the Codex/opencode copy and its stamp without touching the registration.
  • merge-and-release step 7 now runs --snapshot-only from a detached worktree at origin/main instead of switching a checkout to main. Step 8 no longer assumes the base clone was left on main. check-this-repo's safe-to-fix re-run and skill-lifecycle step 8 use --snapshot-only too.
  • --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, and host-setup/README.md describe 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, because Path.is_dir() changed behavior in 3.14.
  • Mutation checks: reverting each guard fails its tests.
  • Full suite (1792 tests), ruff, mypy, prose lint, the eol gate, spec/validate.py, build_dist.py --check, markdownlint, editorconfig-checker, and cspell all pass.
  • Four local-strict-review passes 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

ptr727 and others added 4 commits September 28, 2026 15:28
`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>
Copilot AI balanced review requested due to automatic review settings September 29, 2026 00:06
@coderabbitai

coderabbitai Bot commented Sep 29, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Repository: ptr727/ProjectTemplate/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: d54d4041-9c24-41fd-bdd9-0463cb589f8d


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Sep 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.11321% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 55.66%. Comparing base (99fa0ce) to head (bd59805).

Files with missing lines Patch % Lines
scripts/skills_install.py 98.11% 1 Missing ⚠️
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     
Flag Coverage Δ
python-3.13 55.66% <98.11%> (+0.36%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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-only mode refreshes only the Codex/opencode copy and stamp without touching the Claude registration; live_channel() and is_bootstrap_tree() are hardened to judge unreadable/gone paths without crashing.
  • merge-and-release step 7/8, check-this-repo, and skill-lifecycle are 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.

@ptr727
ptr727 merged commit c0467a5 into develop Sep 29, 2026
11 checks passed
@ptr727
ptr727 deleted the feature/skills-refresh-snapshot-only branch September 29, 2026 00:14
ptr727 added a commit that referenced this pull request Sep 29, 2026
…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)
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.

2 participants