Repository navigation
feat(plugin): ship the Claude plugin from a generated plugin/ folder - #1207
Merged
Merged
Conversation
The plugin marketplace validator flagged research's allowed-tools line (ALLOWED_TOOLS_BROAD for unscoped Bash, ALLOWED_TOOLS_UNSCOPED_WRITE for unscoped Write). No step in the skill needs unprompted execution, so the grant is removed and research uses the normal permission prompts like the other 28 skills.
scripts/regen-plugin-tree.sh projects skills/, hooks/, agents/ and workflows/ into plugin/ from git's file list, skipping developer-only tests/, *.bats and caches. It refuses symlinks, files over 256 KiB, non-image binaries and more than 512 files, and --check reports drift. regen-all.sh runs it in both modes.
The marketplace screened the whole repository because the plugin folder was the repo root: 2,764 files, most of them never loaded. plugin/ now holds only the loaded components (skills, agents, the policy hook dispatcher, workflows), the manifest moved to plugin/.claude-plugin/plugin.json, and a 1024 px listing icon. The marketplace entry points at ./plugin; install commands are unchanged. bin/factory and bin/ralph no longer ship: a plugin bin/ lands on the Bash PATH and blocks claude.ai and Cowork installs. Consumers repointed: version parity test, pre-commit version warning, ci-local-release, validate-doc-release, images/claude/verify.sh, validate-manifests, run-all, the Claude runtime smoke, two fixture tests, the manifest schema (icon), CODEOWNERS and two doc links. Codex is untouched.
GIT_ORIGIN was assigned and never read (shellcheck SC2034). The new plugin/ copy made shell.shellcheck-changed report it.
The pinned v2.13.1 (x/tools 0.49.0) cannot read go1.27 export data
("export data version 5 is greater than maximum supported version 4"),
so the go.lint gate failed on every PR after the toolchain bump in #1201.
v2.14.0 ships x/tools 0.50.0 and lints the tree clean (0 findings).
… fix/plugin-skill-allowed-tools
…into feat/plugin-subfolder-projection
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
The plugin marketplace validator (main @ f9c4b1c) raised 24 holds with one cause: the plugin folder was the repository root, so the screen walked 2,764 files (Go CLI, evals, docs, CI). Holds included BINARIES_NOT_INSPECTED (>512 files), UNREAD_ASSET_REFERENCED, MCP_FORWARDS_CREDENTIAL_ENV (release.yml), RUNTIME_FETCH_EXEC (README, CHANGELOG, .github, cli tests), ICON_MISSING and ARCHIVE_SYMLINK_SKIPPED. The plugin format has no file-exclusion mechanism; the portal's "Plugin path" field scans only the named folder.
Design
plugin/is the plugin folder;.claude-plugin/marketplace.jsonnow has"source": "./plugin".plugin/{skills,hooks,agents,workflows}/are generated byscripts/regen-plugin-tree.shfrom the canonical root trees, which stay put (scripts, tests andao skills linkkeep readingskills/).git ls-files(tracked + untracked-not-ignored) and skips developer-onlytests/,*.batsand Python caches.--checkreports drift and is wired intoscripts/regen-all.sh(both modes), soalways.regen-allgates it.plugin/:.claude-plugin/plugin.json(moved from root; release version lives here),.claude-plugin/icon.png(1024x1024, 286 KB, from docs/assets/logo.svg), and a shortREADME.mdwith no fetch-and-run commands or images.Result: 262 files, no symlinks; the only file over 256 KiB is the icon PNG.
Behavior change:
bin/no longer shipsThe manifest reference lists
bin/as a plugin component: its files go on the BashPATH, and claude.ai and Cowork do not install a plugin that has one. The root-folder plugin was therefore puttingbin/factoryandbin/ralphon users' PATH. They are operator tools (factoryreads a private~/.config/factory), so the projection leaves them out. Noted in CHANGELOG Unreleased.Consumers updated
cli/cmd/ao/version_manifest_parity_test.go: root marker is now.claude-plugin/marketplace.json; surface isplugin/.claude-plugin/plugin.json(a mutation to 9.9.9 fails the test)..githooks/pre-commit,scripts/ci-local-release.sh,tests/docs/validate-doc-release.sh,images/claude/verify.sh,scripts/validate-manifests.sh,tests/run-all.sh,tests/skills/test-runtime-claude-code-smoke.shtests/scripts/explicit-skill-requests.bats,tests/scripts/test-codex-plugin-metadata-schema.shschemas/plugin-manifest.v1.schema.json: addsicon(additionalProperties: false).github/CODEOWNERS(/plugin/), doc links indocs/MIGRATION.mdanddocs/contracts/multi-runtime-tier-charter.md, CHANGELOG (both copies)skills/doc/scripts/audit-oss-docs.sh: removed an unused variable (SC2034) thatshell.shellcheck-changedflagged on the new copyevals/skills-rpi/**copies.claude-plugin/(still present with marketplace.json;aonever reads plugin.json); historicaldocs/releases/**anddocs/plans/**.Installs after this
claude plugin marketplace add boshu2/agentopsthenclaude plugin install agentops@agentops-marketplaceare unchanged. A marketplace's relativesourceresolves from the marketplace root, so./pluginis valid. An existing install should pick up the new layout on its next marketplace update; that upgrade path was not exercised here.plugins/marketplace.json(path: "./") and root.codex-plugin/plugin.json(skills: "./skills"), neither of which this PR touches.Checks
bash scripts/regen-plugin-tree.sh && bash scripts/regen-plugin-tree.sh --check: regenerated 262 files, then "plugin/ is current". Failure paths also exercised: a hand-edited copy ->--checkrc=1 with a diff summary; a symlink inworkflows/-> refused; a 300 KB file -> refused.bash scripts/regen-all.sh --check: all 8 steps pass, including "Claude plugin folder".find plugin -type lempty;find plugin -type f | wc -l= 262;find plugin -type f -size +256k= onlyplugin/.claude-plugin/icon.png.claude plugin validate plugin: passed with 2 warnings (unquoted${CLAUDE_PLUGIN_ROOT}inhooks/hooks.json, pre-existing;--strictfails on them).claude plugin validate .: marketplace passed.shellcheck -S warningon the new script and every edited script: clean.cd cli && go build ./... && go vet ./... && go test ./cmd/ao/...: pass.tests/scripts/explicit-skill-requests.bats5/5;test-codex-plugin-metadata-schema.sh2/2; Claude runtime smoke 8/8;images/claude/verify.shOK;validate-manifests.shandvalidate-doc-release.shpass.ao gate check --full(ao built from this branch): 65/66 pass.go.lintfails oncmd/skill-frontmatter-json/main.go(untouched): the local golangci-lint cannot read Go 1.27.2 export data ("export data version 5 is greater than maximum supported version 4") after the toolchain bump in chore(deps): update go toolchain directive to v1.27.2 #1201. Unrelated to this change.CLAUDE_CONFIG_DIR: marketplace add from the worktree path, install,detailsshows 29 skills, 4 agents, 1 hook; the install cache holds exactly the 262 files ofplugin/, workflows included. Uninstalled afterwards.Not verified here
plugin..jsfiles still ship, so COMMAND_SCRIPT_NOT_FOLLOWED stays a reviewer hold by design.skills/skill-eval/SKILL.mdand two of its references link to repoevals/,scripts/anddocs/paths that are outside the plugin folder.