Repository navigation
feat: vendoring — freeze LCD into a project, update it safely (0.20.0) - #20
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCp4cMxLbQXy83ZZv9RDXp
…) + frozen /lcd-update Vendors skills, commands and agents under lcd- names, the engine under .claude/lcd/, hooks and path-based permissions merged into .claude/settings.json. A sha256 MANIFEST guards updates: locally edited or deleted managed files block the update unless --force. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCp4cMxLbQXy83ZZv9RDXp
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCp4cMxLbQXy83ZZv9RDXp
…links A committed MANIFEST is contributor-controlled: entries must match .claude/<path> with no '..', and no path component (settings.json, .claude/skills, …) may be a symlink, so update/install can't delete or write outside the project. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCp4cMxLbQXy83ZZv9RDXp
…ate script copies Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCp4cMxLbQXy83ZZv9RDXp
This was referenced Oct 24, 2026
…c-convention seed, lcd:* and docs/ - install crashed under macOS /bin/bash 3.2 (unguarded empty array under set -u); the test now runs the script with /bin/bash - settings merge removes LCD hook entries, not whole groups: a user hook sharing a group with an LCD hook survives install and update - .claude/rules/ac-convention.md is a seed written only when absent and never in the MANIFEST, so onboard's non-default-root rewrite no longer blocks every update - lcd:* rewritten too; docs/ vendored so plugin-root doc links resolve; a test checks every vendored .claude/... reference exists - --force test asserts restore + overwrite; AGENTS.md, refused-install snapshot and removed-skill-dir cleanup now asserted Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCp4cMxLbQXy83ZZv9RDXp
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCp4cMxLbQXy83ZZv9RDXp
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.
Why
On a contributor-open project, contributors who never installed LCD don't get its triage, hooks or AC tests. This freezes LCD into the project's own
.claude/, so cloning the repo is enough.What
bin/lcd-vendor.sh install|update|check [--dry-run] [--force] <project>, run from a plugin checkout.lcd-<name>. Project skills can't use thelcd:namespace,:is reserved in agent names, and baredoctor/resumewould shadow built-ins..claude/lcd/{bin,rules,templates}."$CLAUDE_PROJECT_DIR"/.claude/lcd/bin/…) and path-based permissions are merged into.claude/settings.json, keeping every other key..claude/rules/ac-convention.mdis installed only if the project has none..claude/lcd/MANIFESTrecords the sha256 of every managed file. An update that would overwrite a locally edited or deleted file refuses and names it;--forceaccepts.--dry-runprints from → to, added/changed/removed files and the CHANGELOG sections in between.checkexits 0 only when the copy is current and nothing drifted./lcd-update [vX.Y.Z | path](vendored copies only) fetches the target tag or uses a local clone, previews, asks, applies with the target's own script, runs doctor, and offers to refresh the CI-gate script copies..claude/with no.., and no managed path component may be a symlink. A committed MANIFEST is contributor-controlled.Verification
tests/test-vendor.shcovers AC-1..AC-6 (CLI), including traversal and symlink refusal. Suite 14/14;claude plugin validatepasses.lcd@lcddisabled:lcd-*skills/commands and 4 agents are listed.Notes
Bash(.claude/lcd/bin/…:*)).settings.jsonis committed and shared, so absolute paths would break for everyone else. The trust level is the same as the plugin's name-based rules.lcd:reconskill and thelcd:lcd-reconagent both becomelcd-recon. Skills and agents are separate namespaces, so this should be harmless, but it's untested.bin/)" notes remain next to commands that are already rewritten to.claude/lcd/bin/….Follow-ups (not in this PR)
tool_input.file_path, soNotebookEdit(notebook_path) is allowed unchecked...segments aren't normalised before matching.rules/lcd.mdand theac-convention.mdheader say the rule auto-loads from the plugin. Plugins have norules/component, so it doesn't. Doctor's non-default-root check rests on the same claim.🤖 Generated with Claude Code
https://claude.ai/code/session_01VCp4cMxLbQXy83ZZv9RDXp