feat: add self-hosted registry server, plugin installs, and registry publish/login - #16
Merged
Merged
Conversation
…publish/login - New @agentpm/registry-server package: HTTP registry with SQLite-backed users/tokens/skills, scrypt auth, role-based access (admin/publisher/reader), public/private skill visibility, JSON skill archives, and an embedded web UI for browsing, curation, user and token management. - Skill archive format v1 in @agentpm/shared with strict validation and path traversal guards; pack/materialize helpers in @agentpm/fs. - Registry client: index entries may now carry an archive URL instead of a git repo, http(s) support for local registries, bearer tokens from stored credentials (agentpm registry login), env vars still supported. - Core: archive-backed installs materialize per-revision cache releases and support preview/update/remove like git-backed installs; registry-client module with login/logout/whoami/publish. - Claude Code plugin support: .claude-plugin/plugin.json and marketplace.json detection, new plugin entry kind, installs into <scope>/.agentpm/plugins with a maintained marketplace.json so Claude Code can consume it natively. - CLI: agentpm registry serve/login/logout/whoami/publish/user and agentpm guide (agent onboarding); provider-bridge test fixture now shims npx on POSIX. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014ewP1CuqqJWzTtnmuewCxH
- registry-guide: archive entries and the self-hosted registry server flows - new plugin-guide: detection, .agentpm/plugins marketplace model, publishing - README: self-hosted registry and Claude Code plugin sections, agentpm guide - summaries: registry, registry-server (new), runtime-architecture, shared - CLAUDE.md: registry/registry-server package descriptions Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014ewP1CuqqJWzTtnmuewCxH
…rom review Security: - Validate skill archive version (no path separators/'..') so a publisher cannot write outside the archive tree; add a containment check in the PUT handler as defense-in-depth. - Validate Claude Code plugin names to a single safe path segment so an untrusted repo's plugin.json cannot place the managed link outside .agentpm/plugins; clamp the adapter target as well. - Make login password verification async and add per-(ip,user) login throttling so scrypt cannot serialize/block the event loop or be brute-forced. - Strip the Authorization header on cross-origin registry redirects so the bearer token cannot leak to a redirected host/CDN. - Return 404 (not 403) when publishing over a private skill the caller cannot read, so it is not an existence oracle. Correctness: - update: reuse the install's cache key and register the materialized release, so revision-pinned installs (from sync) are no longer deleted by cache clean; recompute archive installs' source-relative path against the new release. - Resync the plugin marketplace manifest on update, not just install/remove. - doctor no longer reports archive-backed installs as missing local content. - catalogEntriesFromRegistry disambiguates archive ids by target/kind/path and raises a clear error on duplicate names instead of a raw SQLite crash. - Archive installs from a transient one-off --from source now reindex before the update preview, matching git installs' live update behavior. - Registry index archive URLs are root-absolute, so /v1/index.json resolves correctly; a --private server returns 401 to anonymous index reads. - Fix IPv6 display URL bracketing in the serve banner. CLI/UX: - Route service status messages to stderr so --json stdout stays parseable. - Guard human update/doctor output behind !--json and return planned doctor fixes in JSON mode without prompting (no TTV requirement). - Correct the agentpm guide / plugin-guide flags (update --yes, remove --json, per-scope plugin marketplace names); soften the "every command" claim. - registry commands emit dot-form actions with nested payloads; add errorGuidance for registry auth errors and a --kind publish flag; publish rejects folders with no SKILL.md/plugin.json unless --kind is given. - Mask the login password prompt; case-insensitive --target; Object.hasOwn for quickstart flow validation; validate agentpm.yaml targets is an array. Tests: path-traversal version, plugin-name traversal, index alias resolution, private 401, and archive-install doctor cleanliness. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014ewP1CuqqJWzTtnmuewCxH
Bump all workspace packages to 0.10.0 and record the release-facing changes (self-hosted registry server + web UI, Claude Code plugin installs, archive publish/subscribe, and the review-driven security/correctness fixes). Release impact: minor (new features, no breaking changes to existing flows). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014ewP1CuqqJWzTtnmuewCxH
Previously plugin detection/install was hard-coded to Claude Code. Codex has
its own plugin system, so this generalizes support to both hosts:
- Detect .codex-plugin/plugin.json (adapter codex) and .claude-plugin/plugin.json
(adapter claude), plus each host's marketplace manifest
(.agents/plugins/marketplace.json + api_marketplace.json for Codex;
.claude-plugin/marketplace.json for Claude). Marketplace sources accept
Claude's string form and Codex's { source: "local", path } object form.
- Install plugins into <scope>/.agentpm/plugins/<agent>/plugins/<name> and
maintain the agent's native marketplace manifest there, so `claude plugin
marketplace add` / `codex plugin marketplace add` consume the folder natively.
The Codex manifest uses the object source + policy shape; Claude uses the
string source shape.
- A repo carrying both manifests yields one plugin entry per agent (kept
distinct through listInstallableEntries dedup), selectable via --target.
- Install ids now include the adapter, so the same plugin/skill name can be
installed for two agents without the second overwriting the first record.
- registry publish detects .codex-plugin as well; update resyncs the correct
per-agent marketplace.
- CLI guide, README, plugin-guide, registry-guide, summaries, and CHANGELOG
updated; new Codex plugin fixture and test; Claude plugin tests updated for
the per-agent path.
Part of the unreleased 0.10.0 cycle. Verified with the full test suite (89) and
a live install producing a native Codex .agents/plugins/marketplace.json.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014ewP1CuqqJWzTtnmuewCxH
When an install name resolved to more than one entry (a skill and a plugin, or the same name for two agents), install silently picked the first by sort order. Now: - `agentpm install <name>` collects all matching entries; a single match installs directly, multiple distinct matches show an interactive picker labeled by kind and agent, and non-interactively it errors with the --kind/--target filters that select one. - New `--kind <skill|agent|subagent|plugin>` filter on install (alongside --target), threaded through the configured-source, --from, and detection resolution paths. - catalogEntriesFromInspection now keys ids on name+path+adapter+kind and stores metadata.kind, so a plugin carrying both a Claude and a Codex manifest (same name and path) no longer collides on the catalog primary key; catalogEntryKind reads kind from metadata/tags/archive. - errorGuidance points ambiguous-match errors at --kind/--target. - Docs (guide, plugin-guide, runtime summary, CHANGELOG) and a name-clash fixture with three tests (non-interactive error, --kind resolves both ways, interactive picker) added. Full suite: 92 green. Part of the unreleased 0.10.0 cycle. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014ewP1CuqqJWzTtnmuewCxH
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.
users/tokens/skills, scrypt auth, role-based access (admin/publisher/reader),
public/private skill visibility, JSON skill archives, and an embedded web UI
for browsing, curation, user and token management.
traversal guards; pack/materialize helpers in @agentpm/fs.
repo, http(s) support for local registries, bearer tokens from stored
credentials (agentpm registry login), env vars still supported.
support preview/update/remove like git-backed installs; registry-client
module with login/logout/whoami/publish.
detection, new plugin entry kind, installs into /.agentpm/plugins with
a maintained marketplace.json so Claude Code can consume it natively.
guide (agent onboarding); provider-bridge test fixture now shims npx on POSIX.
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_014ewP1CuqqJWzTtnmuewCxH