dsh-agent-plugins-market 0.6.0 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +143 -169
- package/README.zh.md +136 -170
- package/client/client.js +8202 -684
- package/client/client.js.map +1 -1
- package/lib/application/catalog.js +236 -47
- package/lib/application/details.js +19 -10
- package/lib/application/panel-resources.js +95 -0
- package/lib/application/project-agent-roles.js +39 -0
- package/lib/catalog/codex-mcp.js +114 -0
- package/lib/catalog/component-files.js +151 -0
- package/lib/catalog/manifests.js +105 -44
- package/lib/catalog/native-project.js +44 -23
- package/lib/catalog/paths.js +6 -6
- package/lib/catalog/project-config.js +96 -0
- package/lib/catalog/project-hooks.js +108 -0
- package/lib/catalog/scan-pipeline.js +6 -1
- package/lib/catalog/scan-resolvers.js +70 -26
- package/lib/catalog/source-catalog.js +16 -3
- package/lib/catalog/suite-components.js +125 -0
- package/lib/catalog/surfaces.js +60 -46
- package/lib/catalog/validate.js +16 -11
- package/lib/contracts/market.js +16 -1
- package/lib/index.js +187 -35
- package/lib/model/layouts.js +49 -0
- package/lib/routes.js +106 -6
- package/lib/runtime/agent-role-router.js +226 -0
- package/lib/runtime/commands-mounts.js +27 -67
- package/lib/runtime/feedback-tool.js +181 -0
- package/lib/runtime/hooks-mounts.js +66 -13
- package/lib/runtime/host-locale.js +23 -7
- package/lib/runtime/legacy-root-migration.js +12 -0
- package/lib/runtime/lsp-direct-config.js +6 -3
- package/lib/runtime/lsp-mounts.js +38 -24
- package/lib/runtime/lsp-server-state.js +19 -0
- package/lib/runtime/lsp-status.js +3 -2
- package/lib/runtime/mcp-backend.js +6 -2
- package/lib/runtime/mcp-client/config.js +6 -0
- package/lib/runtime/mcp-client/connection.js +8 -2
- package/lib/runtime/mcp-client/tools.js +6 -3
- package/lib/runtime/mcp-config.js +26 -13
- package/lib/runtime/mcp-direct-config.js +56 -0
- package/lib/runtime/mcp-mounts.js +25 -9
- package/lib/runtime/mcp-overrides.js +11 -5
- package/lib/runtime/mcp-status.js +10 -7
- package/lib/runtime/model-catalog.js +48 -0
- package/lib/runtime/project-runtime.js +136 -0
- package/lib/runtime/reconciler.js +38 -28
- package/lib/runtime/server-config.js +75 -0
- package/lib/runtime/skills-provider.js +31 -77
- package/lib/runtime/storage-migration.js +169 -0
- package/lib/runtime/subagent-catalog.js +129 -0
- package/lib/runtime/user-commands.js +86 -0
- package/lib/runtime/user-panels.js +176 -0
- package/lib/runtime/user-store.js +142 -0
- package/lib/types/application/catalog.d.ts +39 -9
- package/lib/types/application/panel-resources.d.ts +13 -0
- package/lib/types/application/project-agent-roles.d.ts +3 -0
- package/lib/types/application/queries.d.ts +17 -1
- package/lib/types/catalog/codex-mcp.d.ts +4 -0
- package/lib/types/catalog/component-files.d.ts +17 -0
- package/lib/types/catalog/manifests.d.ts +14 -9
- package/lib/types/catalog/native-project.d.ts +2 -5
- package/lib/types/catalog/paths.d.ts +4 -4
- package/lib/types/catalog/project-config.d.ts +6 -0
- package/lib/types/catalog/project-hooks.d.ts +10 -0
- package/lib/types/catalog/scan-pipeline.d.ts +2 -0
- package/lib/types/catalog/scan-resolvers.d.ts +4 -3
- package/lib/types/catalog/source-catalog.d.ts +1 -1
- package/lib/types/catalog/suite-components.d.ts +5 -0
- package/lib/types/catalog/surfaces.d.ts +2 -2
- package/lib/types/catalog/validate.d.ts +2 -0
- package/lib/types/contracts/market.d.ts +60 -0
- package/lib/types/contracts/mcp-status.d.ts +5 -1
- package/lib/types/index.d.ts +2 -2
- package/lib/types/model/layouts.d.ts +102 -0
- package/lib/types/model/types.d.ts +51 -6
- package/lib/types/routes.d.ts +6 -1
- package/lib/types/runtime/agent-role-router.d.ts +95 -0
- package/lib/types/runtime/commands-mounts.d.ts +16 -7
- package/lib/types/runtime/feedback-tool.d.ts +49 -0
- package/lib/types/runtime/hooks-mounts.d.ts +4 -0
- package/lib/types/runtime/host-locale.d.ts +1 -1
- package/lib/types/runtime/legacy-root-migration.d.ts +2 -0
- package/lib/types/runtime/lsp-mounts.d.ts +4 -0
- package/lib/types/runtime/lsp-server-state.d.ts +3 -0
- package/lib/types/runtime/lsp-status.d.ts +1 -0
- package/lib/types/runtime/mcp-backend.d.ts +9 -1
- package/lib/types/runtime/mcp-client/config.d.ts +4 -3
- package/lib/types/runtime/mcp-client/tools.d.ts +3 -0
- package/lib/types/runtime/mcp-config.d.ts +11 -5
- package/lib/types/runtime/mcp-direct-config.d.ts +7 -0
- package/lib/types/runtime/mcp-mounts.d.ts +2 -1
- package/lib/types/runtime/mcp-overrides.d.ts +2 -0
- package/lib/types/runtime/mcp-status.d.ts +1 -1
- package/lib/types/runtime/model-catalog.d.ts +7 -0
- package/lib/types/runtime/project-runtime.d.ts +32 -0
- package/lib/types/runtime/reconciler.d.ts +2 -0
- package/lib/types/runtime/server-config.d.ts +10 -0
- package/lib/types/runtime/skills-provider.d.ts +1 -5
- package/lib/types/runtime/storage-migration.d.ts +15 -0
- package/lib/types/runtime/subagent-catalog.d.ts +52 -0
- package/lib/types/runtime/user-commands.d.ts +24 -0
- package/lib/types/runtime/user-panels.d.ts +91 -0
- package/lib/types/runtime/user-store.d.ts +51 -0
- package/package.json +10 -3
- package/schemas/README.md +69 -7
- package/schemas/agent-plugins/spec.md +48 -0
- package/schemas/claude-code/marketplace.schema.json +143 -0
- package/schemas/claude-code/plugin.schema.json +105 -0
- package/schemas/claude-code/spec.md +108 -0
- package/schemas/codex/marketplace.schema.json +78 -0
- package/schemas/codex/plugin.schema.json +77 -0
- package/schemas/codex/spec.md +91 -0
- package/schemas/cursor/marketplace.schema.json +82 -0
- package/schemas/cursor/plugin.schema.json +58 -0
- package/schemas/cursor/spec.md +92 -0
- package/schemas/github-copilot/marketplace.schema.json +107 -0
- package/schemas/github-copilot/plugin.schema.json +89 -0
- package/schemas/github-copilot/spec.md +105 -0
- package/schemas/kimi/marketplace.schema.json +38 -0
- package/schemas/kimi/plugin.schema.json +84 -0
- package/schemas/kimi/spec.md +94 -0
- package/schemas/qoder/marketplace.schema.json +115 -0
- package/schemas/qoder/plugin.schema.json +127 -0
- package/schemas/qoder/spec.md +111 -0
- package/schemas/skill-collection/spec.md +29 -0
- package/schemas/universal/marketplace.schema.json +98 -0
- package/schemas/universal/plugin.schema.json +49 -0
- package/schemas/universal/spec.md +53 -0
- package/schemas/zcode/marketplace.schema.json +161 -0
- package/schemas/zcode/plugin.schema.json +89 -0
- package/schemas/zcode/spec.md +102 -0
- package/lib/catalog/legacy-root-migration.js +0 -51
- package/lib/types/catalog/legacy-root-migration.d.ts +0 -14
package/schemas/README.md
CHANGED
|
@@ -1,11 +1,73 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Plugin manifest and marketplace specifications
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This directory is the specification library for the plugin layouts this manager reads. It holds two kinds of files:
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- license: the Agent Plugins specification repository's license
|
|
5
|
+
1. **Vendored upstream schemas** in [`1.0.0/`](1.0.0/) — pinned copies of the official agent-plugins.org v1.0.0 schemas. These are bundled into the published package and loaded at runtime by [`src/catalog/validate.ts`](../src/catalog/validate.ts), because the specification requires clients to validate plugin packages without retrieving schemas at load time (§7.2.1: "Clients MUST NOT retrieve a schema while loading a plugin").
|
|
6
|
+
2. **Reference contracts** in `<dialect>/` — an authored JSON Schema pair plus a `spec.md` for each layout the manager recognizes. **These are documentation, not runtime validators**: the scanner still applies the strategy-chain rules in `src/catalog/`. They exist so a dialect's field set, file locations, and evidence are pinned in one place.
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
Every authored schema records its provenance in a `$comment`, and every dialect's `spec.md` records the sources, the verification date, and the unresolved gaps.
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
## Layout
|
|
11
|
+
|
|
12
|
+
```text
|
|
13
|
+
schemas/
|
|
14
|
+
├── 1.0.0/ # vendored agent-plugins.org v1.0.0 (runtime-loaded)
|
|
15
|
+
│ ├── plugin.schema.json
|
|
16
|
+
│ └── mcp.schema.json
|
|
17
|
+
├── agent-plugins/spec.md # the published cross-vendor standard (schemas live in 1.0.0/)
|
|
18
|
+
├── skill-collection/spec.md # manifest-less layout; nothing to validate
|
|
19
|
+
└── <dialect>/
|
|
20
|
+
├── plugin.schema.json
|
|
21
|
+
├── marketplace.schema.json
|
|
22
|
+
└── spec.md
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Dialect index
|
|
26
|
+
|
|
27
|
+
This table records **upstream client conventions**, including their own fallback orders; it does not define this plugin's discovery priority. DSH uses one shared layout order for suite manifests and Marketplace catalogs, shown in the [README priority table](../README.md#layout-detection-precedence) ([中文](../README.zh.md#布局识别优先级)). Catalogs without a dedicated layout use root `marketplace.json` as the final fallback.
|
|
28
|
+
|
|
29
|
+
| Dialect | Upstream plugin manifest conventions | Upstream marketplace conventions | Upstream schema |
|
|
30
|
+
| --- | --- | --- | --- |
|
|
31
|
+
| [Claude Code](claude-code/spec.md) | `.claude-plugin/plugin.json` (optional) | `.claude-plugin/marketplace.json`, or any `marketplace.json` added by path/URL | None; the URL the official catalog declares returns 404 |
|
|
32
|
+
| [Codex](codex/spec.md) | `plugin.json` (agent-plugins `$schema`) → `.codex-plugin/` → `.claude-plugin/` → `.cursor-plugin/` | `.agents/plugins/marketplace.json` → `.agents/plugins/api_marketplace.json` → `.claude-plugin/` → `.cursor-plugin/` | agent-plugins v1.0.0 for root `plugin.json`; none otherwise |
|
|
33
|
+
| [Cursor](cursor/spec.md) | `.cursor-plugin/plugin.json`, or root `plugin.json` (agent-plugins) | `.cursor-plugin/marketplace.json` | None for `.cursor-plugin/`; agent-plugins v1.0.0 for root |
|
|
34
|
+
| [Kimi (kimi-code)](kimi/spec.md) | `kimi.plugin.json` → `.kimi-plugin/plugin.json` | `KIMI_CODE_PLUGIN_MARKETPLACE_URL`, default `https://code.kimi.com/kimi-code/plugins/marketplace.json` | None reachable; the declared URI serves HTML |
|
|
35
|
+
| [Kimi (kimi-cli, legacy)](kimi/spec.md#kimi-cli-legacy-a-different-format) | `plugin.json` with a `tools` array | None | None |
|
|
36
|
+
| [Universal `.plugin/`](universal/spec.md) | `.plugin/plugin.json` | `.plugin/marketplace.json` | None — an observed convention, not a specification |
|
|
37
|
+
| [agent-plugins.org v1](agent-plugins/spec.md) | `plugin.json` (required) | Vendor-specific; not part of the standard | **Vendored 1.0.0** |
|
|
38
|
+
| [Skill collection](skill-collection/spec.md) | None | None | n/a |
|
|
39
|
+
| [ZCode](zcode/spec.md) | `.zcode-plugin/plugin.json` → `.claude-plugin/` → `.codex-plugin/` | `.claude-plugin/marketplace.json` → `marketplace.json` | None |
|
|
40
|
+
| [Qoder CLI](qoder/spec.md) | `.qoder-plugin/plugin.json` → `.claude-plugin/plugin.json` | `.qoder-plugin/marketplace.json` → `.claude-plugin/` → `marketplace.json` | None |
|
|
41
|
+
| [GitHub Copilot CLI](github-copilot/spec.md) | `.plugin/plugin.json` → `plugin.json` → `.github/plugin/plugin.json` → `.claude-plugin/` | `marketplace.json` → `.plugin/` → `.github/plugin/` → `.claude-plugin/` | None; agent-plugins optional via `$schema` |
|
|
42
|
+
|
|
43
|
+
## Cross-dialect conventions
|
|
44
|
+
|
|
45
|
+
These are the points where the layouts actually differ; they cause the most silent failures.
|
|
46
|
+
|
|
47
|
+
| Dialect | MCP configuration | Hooks |
|
|
48
|
+
| -------------------- | ------------------------------------------------------------------------------------- | ---------------------------------- |
|
|
49
|
+
| Claude Code | `.mcp.json`; inline `mcpServers` is additive | `hooks/hooks.json` or inline |
|
|
50
|
+
| Codex | legacy: `.mcp.json` (validator rejects `mcp.json`); agent-plugins dialect: `mcp.json` | manifest `hooks` or `hooks/` |
|
|
51
|
+
| Cursor | `mcp.json` (dot-file only via an explicit `mcpServers` field) | `hooks/hooks.json` or inline |
|
|
52
|
+
| Kimi (kimi-code) | inline `mcpServers` only | inline `hooks` array |
|
|
53
|
+
| Universal `.plugin/` | `.mcp.json`, `.github/mcp.json` | `hooks.json` or `hooks/hooks.json` |
|
|
54
|
+
| agent-plugins.org v1 | `mcp.json`, required and closed; inline is forbidden | Not defined |
|
|
55
|
+
| ZCode | `.mcp.json` only | `hooks/hooks.json` |
|
|
56
|
+
| Qoder CLI | `.mcp.json` → `mcp.json` (never merged) | `hooks/hooks.json` |
|
|
57
|
+
| GitHub Copilot CLI | `.mcp.json`, `.github/mcp.json` | `hooks.json` or `hooks/hooks.json` |
|
|
58
|
+
|
|
59
|
+
Claude Code and Copilot (including the Universal convention) define usable LSP declarations. Qoder/ZCode record the field without native execution. Cursor, Codex, Kimi and agent-plugins do not define a native LSP surface; this manager's shared LSP extension must not be confused with an upstream feature.
|
|
60
|
+
|
|
61
|
+
## Executable coverage
|
|
62
|
+
|
|
63
|
+
All ten active layouts are covered by [offline README repository tests](../tests/real-layouts.test.ts). Fixtures retain original Git blobs, commit IDs, hashes and licenses. Competing manifests are removed at every suite root in isolated cases, and the scanner reports the productive marketplace rather than inferring it from file presence. [Component contract tests](../tests/component-declarations.test.ts) cover path/array/inline forms and validation failures. See the [coverage audit](../docs/layout-coverage.md) for the exact boundary between layout compatibility and vendor-native runtime behavior.
|
|
64
|
+
|
|
65
|
+
## Provenance and update policy
|
|
66
|
+
|
|
67
|
+
- `1.0.0/*.schema.json` are vendored. Replace both files from [`agentplugins/agent-plugins-spec`](https://github.com/agentplugins/agent-plugins-spec) at the pinned spec version and bump the spec-version references in `src/catalog/validate.ts`. Never edit them by hand.
|
|
68
|
+
- `<dialect>/*.schema.json` and `spec.md` are authored here. They are **not** upstream copies and carry no upstream compatibility guarantee. When a cited source changes, re-verify and update the schema, the `spec.md`, and the `$comment` provenance line together.
|
|
69
|
+
- `agent-plugins/spec.md` documents the published standard but deliberately keeps its schemas in `1.0.0/` so there is exactly one copy in the tree.
|
|
70
|
+
|
|
71
|
+
## Validation
|
|
72
|
+
|
|
73
|
+
`tests/schemas.test.ts` compiles every schema with Ajv 2020-12, asserts `$id` uniqueness, pins the vendored ids to the runtime constants in `src/catalog/validate.ts`, and requires each dialect to keep a `spec.md` and a paired marketplace schema. Run `pnpm run test` after touching this directory; run `pnpm run format:check` for formatting.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Agent Plugins (agent-plugins.org) v1 specification
|
|
2
|
+
|
|
3
|
+
The only published cross-vendor plugin format in this directory. Unlike the other dialects, its schemas are **vendored upstream** and loaded at runtime by this plugin.
|
|
4
|
+
|
|
5
|
+
- **Schemas:** [../1.0.0/plugin.schema.json](../1.0.0/plugin.schema.json), [../1.0.0/mcp.schema.json](../1.0.0/mcp.schema.json)
|
|
6
|
+
- **Specification:** https://agent-plugins.org/specification
|
|
7
|
+
- **Repository:** [`agentplugins/agent-plugins-spec`](https://github.com/agentplugins/agent-plugins-spec) (`spec/1.0.0.md`, `schemas/1.0.0/`)
|
|
8
|
+
- **Status:** 1.0.0 published; 1.1.0 is a working draft whose plugin schema is currently byte-identical to 1.0.0.
|
|
9
|
+
- **Runtime use:** `src/catalog/validate.ts` loads both 1.0.0 schemas through Ajv, and `src/catalog/manifests.ts` selects this dialect only when a root `plugin.json` declares a recognized `$schema`.
|
|
10
|
+
|
|
11
|
+
## Manifest location
|
|
12
|
+
|
|
13
|
+
Normative (§5.1): clients MUST check for a manifest at `plugin.json` in the plugin root. The core specification defines exactly one portable manifest per plugin, and no other file can replace, supplement, or override its core fields. The specification text contains no reference to `.plugin/`, `.codex-plugin/`, `.claude-plugin/`, `.cursor-plugin/`, or `.kimi-plugin/`.
|
|
14
|
+
|
|
15
|
+
## Plugin manifest fields
|
|
16
|
+
|
|
17
|
+
Closed schema: `additionalProperties: false`, `required: ["$schema", "name"]`, and no `default` keyword anywhere.
|
|
18
|
+
|
|
19
|
+
| Field | Type | Required | Constraints |
|
|
20
|
+
| --- | --- | --- | --- |
|
|
21
|
+
| `$schema` | string | yes | `const: https://agent-plugins.org/schemas/1.0.0/plugin.schema.json` |
|
|
22
|
+
| `name` | string | yes | 1–64 chars, `^(?!.*(?:--\|\.\.))[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?$` |
|
|
23
|
+
| `version` | string | no | SemVer recommended, not enforced. |
|
|
24
|
+
| `description` | string | no | |
|
|
25
|
+
| `author` | `{name?, email?, url?}` | no | Closed object; fields unvalidated. |
|
|
26
|
+
| `homepage`, `repository` | string | no | Not URL-validated. |
|
|
27
|
+
| `license` | string | no | SPDX recommended, not enforced. |
|
|
28
|
+
| `keywords` | string[] | no | No `minItems`/`uniqueItems`. |
|
|
29
|
+
| `extensions` | object of object | no | Client-specific data keyed by reverse-domain namespace; the specification assigns no semantics to namespace contents. |
|
|
30
|
+
|
|
31
|
+
## Fixed component locations
|
|
32
|
+
|
|
33
|
+
Clients MUST discover each supported component type from its fixed location, and `plugin.json` cannot override those locations or carry inline component configuration.
|
|
34
|
+
|
|
35
|
+
| Component | Location | Pattern |
|
|
36
|
+
| ----------- | ---------- | ---------------------------------------------- |
|
|
37
|
+
| Skills | `skills/` | Immediate subdirectories containing `SKILL.md` |
|
|
38
|
+
| MCP servers | `mcp.json` | JSON configuration |
|
|
39
|
+
|
|
40
|
+
v1 defines exactly these two component types. Commands, hooks, agents, rules, and LSP servers are explicitly outside the format "until their formats converge". MCP configuration MUST NOT be declared inline in `plugin.json`. The `mcp.json` schema is closed and requires `$schema` and `mcpServers` with no other top-level fields; every server requires `type` and must match exactly one closed variant.
|
|
41
|
+
|
|
42
|
+
## Governance and adoption
|
|
43
|
+
|
|
44
|
+
The technical steering committee is Amazon, Cursor, Microsoft, OpenAI, and Vercel (lead), with a rule that no single vendor may control a majority of core maintainer seats. Adopters list Agent Skills and MCP: VS Code, Cursor, GitHub Copilot, ChatGPT and Codex, Kiro, Hermes Agent, OpenClaw, Grok Bot, and NanoClaw. **Claude Code and Vercel are absent from that list**, and Vercel's own `vercel-plugin` repository is non-conformant (no root `plugin.json`, no `$schema`, ships `commands/`/`agents/`/`hooks/`, and puts MCP at `.mcp.json` instead of `mcp.json`). The OpenHands SDK vendors the schema and implements the format but keeps it out of its active format list pending its `mcp.json` loader.
|
|
45
|
+
|
|
46
|
+
## Update procedure
|
|
47
|
+
|
|
48
|
+
Replace both files from the upstream repository at the pinned spec version and bump the spec-version references in `src/catalog/validate.ts`. Do not edit the vendored files by hand.
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://sivan757.github.io/dsh-agent-plugins-market/schemas/claude-code/marketplace.schema.json",
|
|
4
|
+
"title": "Claude Code Marketplace Manifest",
|
|
5
|
+
"description": "Marketplace catalog read by Claude Code at .claude-plugin/marketplace.json, or from any marketplace.json file added by direct path or URL. Authored from the official plugin marketplace reference and the official claude-plugins-official catalog; Anthropic publishes no JSON Schema.",
|
|
6
|
+
"$comment": "Provenance: authored (not upstream-vendored) 2026-09-08. Sources: https://code.claude.com/docs/en/plugin-marketplaces ; anthropics/claude-plugins-official/.claude-plugin/marketplace.json (291 entries). forceRemoveDeletedPlugins appears only in the community schemastore schema and in no current official doc. Entry source variants observed in the official catalog: url 153, git-subdir 85, relative path 53.",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"properties": {
|
|
9
|
+
"$schema": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"description": "Ignored at load. The official catalog declares https://anthropic.com/claude-code/marketplace.schema.json, which currently returns 404."
|
|
12
|
+
},
|
|
13
|
+
"name": { "type": "string", "description": "Kebab-case marketplace identifier. Registration is per name per user; a reserved-name list applies." },
|
|
14
|
+
"owner": {
|
|
15
|
+
"type": "object",
|
|
16
|
+
"properties": {
|
|
17
|
+
"name": { "type": "string" },
|
|
18
|
+
"email": { "type": "string" },
|
|
19
|
+
"url": { "type": "string" }
|
|
20
|
+
},
|
|
21
|
+
"required": ["name"],
|
|
22
|
+
"additionalProperties": true
|
|
23
|
+
},
|
|
24
|
+
"plugins": { "type": "array", "items": { "$ref": "#/$defs/entry" } },
|
|
25
|
+
"description": { "type": "string", "description": "Also accepted under metadata for backward compatibility." },
|
|
26
|
+
"version": { "type": "string", "description": "Also accepted under metadata for backward compatibility." },
|
|
27
|
+
"metadata": {
|
|
28
|
+
"type": "object",
|
|
29
|
+
"properties": {
|
|
30
|
+
"pluginRoot": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"description": "Directory under which bare source names resolve; must be a relative path inside the marketplace and is ignored for ./ sources."
|
|
33
|
+
},
|
|
34
|
+
"description": { "type": "string" },
|
|
35
|
+
"version": { "type": "string" }
|
|
36
|
+
},
|
|
37
|
+
"additionalProperties": true
|
|
38
|
+
},
|
|
39
|
+
"allowCrossMarketplaceDependenciesOn": {
|
|
40
|
+
"type": "array",
|
|
41
|
+
"items": { "type": "string" },
|
|
42
|
+
"description": "Marketplace names whose plugins may be auto-installed as dependencies. Only the root marketplace's allowlist applies; there is no transitive trust."
|
|
43
|
+
},
|
|
44
|
+
"renames": {
|
|
45
|
+
"type": "object",
|
|
46
|
+
"description": "Old plugin name to new name, or null when removed. Chains are followed; cycles are rejected by `claude plugin validate`.",
|
|
47
|
+
"additionalProperties": { "type": ["string", "null"] }
|
|
48
|
+
},
|
|
49
|
+
"forceRemoveDeletedPlugins": { "type": "boolean", "description": "Community-schema field with no current official documentation; treat as unverified." }
|
|
50
|
+
},
|
|
51
|
+
"required": ["name", "owner", "plugins"],
|
|
52
|
+
"additionalProperties": true,
|
|
53
|
+
"$defs": {
|
|
54
|
+
"entry": {
|
|
55
|
+
"type": "object",
|
|
56
|
+
"properties": {
|
|
57
|
+
"name": { "type": "string", "description": "Kebab-case plugin identifier used by enabledPlugins and /plugin." },
|
|
58
|
+
"source": { "$ref": "#/$defs/source" },
|
|
59
|
+
"displayName": { "type": "string" },
|
|
60
|
+
"description": { "type": "string" },
|
|
61
|
+
"version": { "type": "string", "description": "Pins the plugin. The plugin.json version wins when both are set; ignored for command sources." },
|
|
62
|
+
"author": {
|
|
63
|
+
"type": "object",
|
|
64
|
+
"properties": { "name": { "type": "string" }, "email": { "type": "string" }, "url": { "type": "string" } },
|
|
65
|
+
"required": ["name"],
|
|
66
|
+
"additionalProperties": true
|
|
67
|
+
},
|
|
68
|
+
"homepage": { "type": "string" },
|
|
69
|
+
"repository": { "type": "string" },
|
|
70
|
+
"license": { "type": "string" },
|
|
71
|
+
"keywords": { "type": "array", "items": { "type": "string" } },
|
|
72
|
+
"metadata": { "type": "object" },
|
|
73
|
+
"category": { "type": "string" },
|
|
74
|
+
"tags": { "type": "array", "items": { "type": "string" } },
|
|
75
|
+
"strict": {
|
|
76
|
+
"type": "boolean",
|
|
77
|
+
"default": true,
|
|
78
|
+
"description": "true: plugin.json is authoritative and this entry supplements it. false: this entry is the whole definition; a conflicting plugin.json fails to load."
|
|
79
|
+
},
|
|
80
|
+
"relevance": { "type": "object", "description": "Suggestion signals; only honored for admin-allowlisted marketplaces." },
|
|
81
|
+
"defaultEnabled": { "type": "boolean", "default": true, "description": "Takes precedence over the manifest value." },
|
|
82
|
+
"headers": { "type": "object", "additionalProperties": { "type": "string" }, "description": "HTTP headers for this entry's archive download." },
|
|
83
|
+
"headersHelper": { "type": "string", "description": "Command printing header JSON; the entry must also set strict: false." },
|
|
84
|
+
"skills": { "anyOf": [{ "type": "string" }, { "type": "array" }] },
|
|
85
|
+
"commands": { "anyOf": [{ "type": "string" }, { "type": "array" }] },
|
|
86
|
+
"agents": { "anyOf": [{ "type": "string" }, { "type": "array" }] },
|
|
87
|
+
"hooks": { "anyOf": [{ "type": "string" }, { "type": "object" }] },
|
|
88
|
+
"mcpServers": { "anyOf": [{ "type": "string" }, { "type": "object" }] },
|
|
89
|
+
"lspServers": { "anyOf": [{ "type": "string" }, { "type": "object" }] }
|
|
90
|
+
},
|
|
91
|
+
"required": ["name", "source"],
|
|
92
|
+
"additionalProperties": true
|
|
93
|
+
},
|
|
94
|
+
"source": {
|
|
95
|
+
"description": "Where to fetch the plugin. When both ref and sha are set on a git source, sha is the effective pin.",
|
|
96
|
+
"anyOf": [
|
|
97
|
+
{ "type": "string", "description": "Relative path beginning with ./, or a bare name resolved under metadata.pluginRoot." },
|
|
98
|
+
{
|
|
99
|
+
"type": "object",
|
|
100
|
+
"properties": { "source": { "const": "github" }, "repo": { "type": "string" }, "ref": { "type": "string" }, "sha": { "type": "string", "pattern": "^[a-f0-9]{40}$" } },
|
|
101
|
+
"required": ["source", "repo"],
|
|
102
|
+
"additionalProperties": true
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"type": "object",
|
|
106
|
+
"properties": { "source": { "const": "url" }, "url": { "type": "string" }, "ref": { "type": "string" }, "sha": { "type": "string", "pattern": "^[a-f0-9]{40}$" } },
|
|
107
|
+
"required": ["source", "url"],
|
|
108
|
+
"additionalProperties": true
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"type": "object",
|
|
112
|
+
"properties": {
|
|
113
|
+
"source": { "const": "git-subdir" },
|
|
114
|
+
"url": { "type": "string" },
|
|
115
|
+
"path": { "type": "string" },
|
|
116
|
+
"ref": { "type": "string" },
|
|
117
|
+
"sha": { "type": "string", "pattern": "^[a-f0-9]{40}$" }
|
|
118
|
+
},
|
|
119
|
+
"required": ["source", "url", "path"],
|
|
120
|
+
"additionalProperties": true
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"type": "object",
|
|
124
|
+
"properties": { "source": { "const": "npm" }, "package": { "type": "string" }, "version": { "type": "string" }, "registry": { "type": "string" } },
|
|
125
|
+
"required": ["source", "package"],
|
|
126
|
+
"additionalProperties": true
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"type": "object",
|
|
130
|
+
"properties": { "source": { "const": "archive" }, "url": { "type": "string" }, "sha256": { "type": "string" } },
|
|
131
|
+
"required": ["source", "url"],
|
|
132
|
+
"additionalProperties": true
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"type": "object",
|
|
136
|
+
"properties": { "source": { "const": "command" }, "command": { "type": "string" }, "timeout": { "type": "number" }, "mode": { "enum": ["copy", "link"] } },
|
|
137
|
+
"required": ["source", "command"],
|
|
138
|
+
"additionalProperties": true
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://sivan757.github.io/dsh-agent-plugins-market/schemas/claude-code/plugin.schema.json",
|
|
4
|
+
"title": "Claude Code Plugin Manifest",
|
|
5
|
+
"description": "Plugin manifest accepted by Claude Code at .claude-plugin/plugin.json. The manifest is optional: when omitted the client discovers components from default locations and derives the name from the directory. Authored from the official plugin reference; Anthropic publishes no JSON Schema (the $schema URL the official marketplace itself uses returns 404).",
|
|
6
|
+
"$comment": "Provenance: authored (not upstream-vendored) 2026-09-08. Source: https://code.claude.com/docs/en/plugins-reference. Unrecognized top-level fields are ignored with a warning (--strict turns them into errors), so this schema is open. Paths are relative to the plugin root and must begin with ./ (skills also accepts \".\"). Claude Code is not listed among agent-plugins.org compatible clients.",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"properties": {
|
|
9
|
+
"$schema": { "type": "string", "description": "Editor autocomplete only; ignored at load. The docs cite https://json.schemastore.org/claude-code-plugin-manifest.json." },
|
|
10
|
+
"name": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"description": "Kebab-case unique identifier; namespaces the plugin's components as <plugin>:<component>."
|
|
13
|
+
},
|
|
14
|
+
"displayName": { "type": "string", "description": "Human-readable UI name; falls back to name and is never used for lookup." },
|
|
15
|
+
"version": { "type": "string", "description": "Semantic version. When both the manifest and a marketplace entry declare a version, the manifest wins without warning." },
|
|
16
|
+
"description": { "type": "string" },
|
|
17
|
+
"author": {
|
|
18
|
+
"type": "object",
|
|
19
|
+
"properties": {
|
|
20
|
+
"name": { "type": "string" },
|
|
21
|
+
"email": { "type": "string" },
|
|
22
|
+
"url": { "type": "string" }
|
|
23
|
+
},
|
|
24
|
+
"additionalProperties": true
|
|
25
|
+
},
|
|
26
|
+
"homepage": { "type": "string" },
|
|
27
|
+
"repository": { "type": "string" },
|
|
28
|
+
"license": { "type": "string" },
|
|
29
|
+
"keywords": { "type": "array", "items": { "type": "string" }, "description": "A wrong type is a load error." },
|
|
30
|
+
"metadata": { "type": "object", "description": "Free-form; Claude Code does not read it." },
|
|
31
|
+
"defaultEnabled": { "type": "boolean", "default": true, "description": "Ship the plugin disabled. A marketplace entry value takes precedence." },
|
|
32
|
+
"skills": { "$ref": "#/$defs/pathList", "description": "Adds to the default skills/ scan." },
|
|
33
|
+
"commands": { "$ref": "#/$defs/pathList", "description": "Replaces the default commands/ directory." },
|
|
34
|
+
"agents": { "$ref": "#/$defs/pathList", "description": "Replaces the default agents/ directory." },
|
|
35
|
+
"workflows": { "$ref": "#/$defs/pathList", "description": "Replaces the default workflows/ directory." },
|
|
36
|
+
"outputStyles": { "$ref": "#/$defs/pathList", "description": "Replaces the default output-styles/ directory." },
|
|
37
|
+
"hooks": { "$ref": "#/$defs/configOrPath", "description": "Path(s) to a hooks configuration file or inline config. Default hooks/hooks.json." },
|
|
38
|
+
"mcpServers": { "$ref": "#/$defs/configOrPath", "description": "Path(s) to an MCP configuration file or inline config. Default .mcp.json; inline servers are additive." },
|
|
39
|
+
"lspServers": { "$ref": "#/$defs/configOrPath", "description": "Path(s) to an LSP configuration file or inline config. Default .lsp.json." },
|
|
40
|
+
"experimental": {
|
|
41
|
+
"type": "object",
|
|
42
|
+
"description": "Newer home for themes and monitors; the top-level spellings still work but warn.",
|
|
43
|
+
"properties": {
|
|
44
|
+
"themes": { "$ref": "#/$defs/pathList" },
|
|
45
|
+
"monitors": { "$ref": "#/$defs/pathList" }
|
|
46
|
+
},
|
|
47
|
+
"additionalProperties": true
|
|
48
|
+
},
|
|
49
|
+
"themes": { "$ref": "#/$defs/pathList", "description": "Deprecated top-level spelling of experimental.themes." },
|
|
50
|
+
"monitors": { "$ref": "#/$defs/pathList", "description": "Deprecated top-level spelling of experimental.monitors." },
|
|
51
|
+
"userConfig": {
|
|
52
|
+
"type": "object",
|
|
53
|
+
"description": "Options prompted when the plugin is enabled. Referenced as ${user_config.<key>}; exported as CLAUDE_PLUGIN_OPTION_<KEY>. Shell-form hooks, monitor commands, and MCP headersHelper reject the substitution.",
|
|
54
|
+
"additionalProperties": { "$ref": "#/$defs/userConfigOption" }
|
|
55
|
+
},
|
|
56
|
+
"channels": { "type": "array", "description": "Message-channel declarations; each entry's server must match a key in mcpServers." },
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"type": "array",
|
|
59
|
+
"description": "Plugins this one depends on.",
|
|
60
|
+
"items": {
|
|
61
|
+
"anyOf": [
|
|
62
|
+
{ "type": "string" },
|
|
63
|
+
{
|
|
64
|
+
"type": "object",
|
|
65
|
+
"properties": { "name": { "type": "string" }, "version": { "type": "string" } },
|
|
66
|
+
"required": ["name"],
|
|
67
|
+
"additionalProperties": true
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"settings": { "type": "object", "description": "Default settings. The settings.json file takes priority over this field." }
|
|
73
|
+
},
|
|
74
|
+
"required": ["name"],
|
|
75
|
+
"additionalProperties": true,
|
|
76
|
+
"$defs": {
|
|
77
|
+
"pathList": {
|
|
78
|
+
"description": "A plugin-relative path or an array of them; each must begin with ./.",
|
|
79
|
+
"anyOf": [
|
|
80
|
+
{ "type": "string", "pattern": "^\\." },
|
|
81
|
+
{ "type": "array", "items": { "type": "string", "pattern": "^\\." } }
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
"configOrPath": {
|
|
85
|
+
"description": "A plugin-relative path, an array of paths, or inline configuration.",
|
|
86
|
+
"anyOf": [{ "type": "string", "pattern": "^\\." }, { "type": "array" }, { "type": "object" }]
|
|
87
|
+
},
|
|
88
|
+
"userConfigOption": {
|
|
89
|
+
"type": "object",
|
|
90
|
+
"properties": {
|
|
91
|
+
"type": { "enum": ["string", "number", "boolean", "directory", "file"] },
|
|
92
|
+
"title": { "type": "string" },
|
|
93
|
+
"description": { "type": "string" },
|
|
94
|
+
"sensitive": { "type": "boolean" },
|
|
95
|
+
"required": { "type": "boolean" },
|
|
96
|
+
"default": {},
|
|
97
|
+
"multiple": { "type": "boolean", "description": "String type only." },
|
|
98
|
+
"min": { "type": "number", "description": "Number type only." },
|
|
99
|
+
"max": { "type": "number", "description": "Number type only." }
|
|
100
|
+
},
|
|
101
|
+
"required": ["type", "title", "description"],
|
|
102
|
+
"additionalProperties": true
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Claude Code plugin and marketplace specification
|
|
2
|
+
|
|
3
|
+
Reference contract for Claude Code plugin repositories. Machine-readable companions: [plugin.schema.json](plugin.schema.json) and [marketplace.schema.json](marketplace.schema.json).
|
|
4
|
+
|
|
5
|
+
- **Verified:** 2026-09-08.
|
|
6
|
+
- **Evidence:** official reference pages [`plugins-reference`](https://code.claude.com/docs/en/plugins-reference) and [`plugin-marketplaces`](https://code.claude.com/docs/en/plugin-marketplaces); the official catalog [`anthropics/claude-plugins-official`](https://github.com/anthropics/claude-plugins-official) (291 entries).
|
|
7
|
+
- **Upstream JSON Schema:** none. The `$schema` URL the official catalog itself declares, `https://anthropic.com/claude-code/marketplace.schema.json`, returns 404. The SchemaStore schemas are community-maintained and stale (generated 2026-04-23, missing `displayName`, `metadata`, `defaultEnabled`, `experimental`, `workflows`, and `renames`).
|
|
8
|
+
- **Spec status:** Claude Code is not listed among agent-plugins.org compatible clients.
|
|
9
|
+
|
|
10
|
+
## Manifest locations and precedence
|
|
11
|
+
|
|
12
|
+
| Artifact | Location |
|
|
13
|
+
| --- | --- |
|
|
14
|
+
| Plugin manifest | `.claude-plugin/plugin.json`; optional — without it components are auto-discovered and the name comes from the directory |
|
|
15
|
+
| Marketplace manifest | `.claude-plugin/marketplace.json`, or any `marketplace.json` added by direct path or URL |
|
|
16
|
+
| Skills | `skills/` (manifest `skills` **adds** to this scan) |
|
|
17
|
+
| Commands / agents / workflows / output styles / themes / monitors | `commands/`, `agents/`, `workflows/`, `output-styles/`, `themes/`, `monitors/monitors.json` (manifest fields **replace** these) |
|
|
18
|
+
| Hooks | `hooks/hooks.json` or inline |
|
|
19
|
+
| MCP | `.mcp.json` or inline `mcpServers` (additive) |
|
|
20
|
+
| LSP | `.lsp.json` or inline `lspServers` |
|
|
21
|
+
| Executables / settings | `bin/`, `settings.json` (only `agent` and `subagentStatusLine` keys) |
|
|
22
|
+
|
|
23
|
+
Only `plugin.json` may live inside `.claude-plugin/`; every component directory belongs at the plugin root. A root `SKILL.md` with no `skills/` directory and no `skills` field loads as a single-skill plugin. A root `CLAUDE.md` is not loaded as context.
|
|
24
|
+
|
|
25
|
+
## Plugin manifest (`plugin.json`)
|
|
26
|
+
|
|
27
|
+
Required: `name`. All paths are relative to the plugin root and must begin with `./` (`skills` also accepts `"."`); traversal outside the plugin is rejected.
|
|
28
|
+
|
|
29
|
+
| Field | Type | Notes |
|
|
30
|
+
| --- | --- | --- |
|
|
31
|
+
| `name` | string | Kebab-case id; namespaces components as `<plugin>:<component>`. |
|
|
32
|
+
| `displayName` | string | UI label; falls back to `name`. |
|
|
33
|
+
| `version` | string | Pins updates. The manifest value wins over a marketplace entry without warning. |
|
|
34
|
+
| `description`, `homepage`, `repository`, `license` | string | |
|
|
35
|
+
| `author` | `{name, email, url}` | |
|
|
36
|
+
| `keywords` | string[] | A wrong type is a load error. |
|
|
37
|
+
| `metadata` | object | Free-form; not read by the client. |
|
|
38
|
+
| `defaultEnabled` | boolean | Default `true`; a marketplace entry value takes precedence. |
|
|
39
|
+
| `$schema` | string | Editor autocomplete only. |
|
|
40
|
+
| `skills`, `commands`, `agents`, `workflows`, `outputStyles` | string \| string[] | See precedence above. |
|
|
41
|
+
| `hooks`, `mcpServers`, `lspServers` | string \| string[] \| object | Path(s) or inline configuration. |
|
|
42
|
+
| `experimental` | `{themes?, monitors?}` | The top-level `themes`/`monitors` spellings still work but warn. |
|
|
43
|
+
| `userConfig` | object | Options prompted at enable time; each requires `type`, `title`, `description`, plus optional `sensitive`, `required`, `default`, `multiple` (string), `min`/`max` (number). |
|
|
44
|
+
| `channels` | array | Message-channel declarations; each `server` must match a key in `mcpServers`. |
|
|
45
|
+
| `dependencies` | (string \| `{name, version?}`)[] | |
|
|
46
|
+
| `settings` | object | `settings.json` takes priority over this field. |
|
|
47
|
+
|
|
48
|
+
Unrecognized top-level fields are ignored with a warning (`--strict` makes them errors), deliberately so a manifest can double as a VS Code or Cursor extension manifest, a `package.json`, or an MCPB/DXT bundle manifest.
|
|
49
|
+
|
|
50
|
+
## Marketplace manifest (`marketplace.json`)
|
|
51
|
+
|
|
52
|
+
Required: `name`, `owner`, `plugins`.
|
|
53
|
+
|
|
54
|
+
| Field | Type | Notes |
|
|
55
|
+
| ------------------------------------- | ---------------------- | --------------------------------------------------------------------- |
|
|
56
|
+
| `name` | string | Kebab-case; one registration per name per user; reserved names apply. |
|
|
57
|
+
| `owner` | `{name, email?, url?}` | |
|
|
58
|
+
| `plugins` | array | |
|
|
59
|
+
| `description`, `version` | string | Also accepted under `metadata` for backward compatibility. |
|
|
60
|
+
| `metadata.pluginRoot` | string | Directory for bare `source` names; ignored for `./` sources. |
|
|
61
|
+
| `allowCrossMarketplaceDependenciesOn` | string[] | Only the root marketplace's allowlist applies; no transitive trust. |
|
|
62
|
+
| `renames` | `{old: new \| null}` | Chains are followed; cycles are rejected by `claude plugin validate`. |
|
|
63
|
+
| `forceRemoveDeletedPlugins` | boolean | Community-schema field with no current official documentation. |
|
|
64
|
+
|
|
65
|
+
Plugin entries require `name` and `source`; optional fields include `displayName`, `description`, `version`, `author`, `homepage`, `repository`, `license`, `keywords`, `metadata`, `category`, `tags`, `strict` (default `true`), `relevance`, `defaultEnabled`, `headers`, `headersHelper`, `skills`, `commands`, `agents`, `hooks`, `mcpServers`, and `lspServers`. With `strict: true` the plugin manifest is authoritative and the entry supplements it; with `strict: false` the entry is the whole definition, and a conflicting component-declaring manifest fails to load.
|
|
66
|
+
|
|
67
|
+
## Plugin sources
|
|
68
|
+
|
|
69
|
+
| Variant | Shape | Notes |
|
|
70
|
+
| ------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
71
|
+
| relative path | string | `./…`, or a bare name under `metadata.pluginRoot`; resolved against the marketplace root, not `.claude-plugin/`. |
|
|
72
|
+
| `github` | `{source, repo, ref?, sha?}` | `owner/repo`. |
|
|
73
|
+
| `url` | `{source, url, ref?, sha?}` | Any git URL, including SSH. |
|
|
74
|
+
| `git-subdir` | `{source, url, path, ref?, sha?}` | Sparse partial clone. |
|
|
75
|
+
| `npm` | `{source, package, version?, registry?}` | |
|
|
76
|
+
| `archive` | `{source, url, sha256?}` | HTTPS zip, at most 256 MiB. |
|
|
77
|
+
| `command` | `{source, command, timeout?, mode?}` | Prints one absolute path; `mode` is `copy` (default) or `link`. |
|
|
78
|
+
|
|
79
|
+
When both `ref` and `sha` are set, `sha` is the effective pin. In the official catalog the observed distribution is `url` 153, `git-subdir` 85, relative path 53.
|
|
80
|
+
|
|
81
|
+
## Version and enablement resolution
|
|
82
|
+
|
|
83
|
+
1. Version: `plugin.json` → marketplace entry → git commit SHA → archive `sha256` prefix → `unknown`.
|
|
84
|
+
2. `defaultEnabled`: marketplace entry > manifest; a user's `enabledPlugins` setting beats both.
|
|
85
|
+
3. `--plugin-dir` local plugins take precedence over a marketplace install for that session.
|
|
86
|
+
|
|
87
|
+
## Directory layout
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
enterprise-plugin/
|
|
91
|
+
├── .claude-plugin/plugin.json # optional manifest
|
|
92
|
+
├── skills/ commands/ agents/ workflows/ output-styles/
|
|
93
|
+
├── themes/ monitors/monitors.json
|
|
94
|
+
├── hooks/hooks.json
|
|
95
|
+
├── bin/ # executables added to PATH
|
|
96
|
+
├── settings.json
|
|
97
|
+
├── .mcp.json
|
|
98
|
+
└── .lsp.json
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Placeholders: `${CLAUDE_PLUGIN_ROOT}`, `${CLAUDE_PLUGIN_DATA}` (`~/.claude/plugins/data/{id}/`), `${CLAUDE_PROJECT_DIR}`, `${user_config.KEY}` (rejected in shell-form hooks, monitor commands, and MCP `headersHelper`).
|
|
102
|
+
|
|
103
|
+
## Evidence gaps
|
|
104
|
+
|
|
105
|
+
1. Hook, MCP, and LSP merge semantics are described only as "own merge rules"; only MCP's additivity with `.mcp.json` is documented.
|
|
106
|
+
2. `.lsp.json` versus inline `lspServers` precedence is unstated.
|
|
107
|
+
3. Whether a root `marketplace.json` can coexist with `.claude-plugin/marketplace.json`, and which wins, is undocumented.
|
|
108
|
+
4. `forceRemoveDeletedPlugins` has no current official documentation.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://sivan757.github.io/dsh-agent-plugins-market/schemas/codex/marketplace.schema.json",
|
|
4
|
+
"title": "Codex Marketplace Manifest",
|
|
5
|
+
"description": "Marketplace catalog read by Codex at .agents/plugins/marketplace.json, .agents/plugins/api_marketplace.json, .claude-plugin/marketplace.json, or .cursor-plugin/marketplace.json (first match wins). Authored from the OpenAI Codex source; OpenAI publishes no JSON Schema for this manifest.",
|
|
6
|
+
"$comment": "Provenance: authored (not upstream-vendored) 2026-09-08. Sources: openai/codex codex-rs/core-plugins/src/marketplace.rs (MARKETPLACE_MANIFEST_RELATIVE_PATHS, raw structs), marketplace_tests.rs fixtures, installed_marketplaces.rs, marketplace_add/source.rs, and the bundled plugin-creator skill. There is no github source variant: the tagged enum has only Local, Url, GitSubdir, and Npm. Entry order is render order.",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"properties": {
|
|
9
|
+
"name": { "type": "string", "pattern": "^[A-Za-z0-9_-]+$", "description": "Marketplace identifier." },
|
|
10
|
+
"interface": {
|
|
11
|
+
"type": "object",
|
|
12
|
+
"properties": { "displayName": { "type": "string" } },
|
|
13
|
+
"additionalProperties": true
|
|
14
|
+
},
|
|
15
|
+
"plugins": { "type": "array", "items": { "$ref": "#/$defs/entry" }, "description": "Ordered plugin entries; the order is the render order." }
|
|
16
|
+
},
|
|
17
|
+
"required": ["name", "plugins"],
|
|
18
|
+
"additionalProperties": true,
|
|
19
|
+
"$defs": {
|
|
20
|
+
"entry": {
|
|
21
|
+
"type": "object",
|
|
22
|
+
"description": "Any plugin-manifest field may be inlined here as a flattened fallback used when the plugin source cannot be read.",
|
|
23
|
+
"properties": {
|
|
24
|
+
"name": { "type": "string", "description": "Must match the folder name and the plugin.json name." },
|
|
25
|
+
"source": { "$ref": "#/$defs/source" },
|
|
26
|
+
"category": { "type": "string" },
|
|
27
|
+
"policy": { "$ref": "#/$defs/policy" }
|
|
28
|
+
},
|
|
29
|
+
"required": ["name", "source"],
|
|
30
|
+
"additionalProperties": true
|
|
31
|
+
},
|
|
32
|
+
"policy": {
|
|
33
|
+
"type": "object",
|
|
34
|
+
"properties": {
|
|
35
|
+
"installation": { "enum": ["NOT_AVAILABLE", "AVAILABLE", "INSTALLED_BY_DEFAULT"], "default": "AVAILABLE" },
|
|
36
|
+
"authentication": { "enum": ["ON_INSTALL", "ON_USE"], "default": "ON_INSTALL" },
|
|
37
|
+
"products": { "type": "array", "items": { "type": "string" }, "description": "Product gating override; an empty array denies every product." }
|
|
38
|
+
},
|
|
39
|
+
"additionalProperties": true
|
|
40
|
+
},
|
|
41
|
+
"source": {
|
|
42
|
+
"description": "Where to fetch the plugin. A bare string is treated as a local relative path. The github variant is not supported.",
|
|
43
|
+
"anyOf": [
|
|
44
|
+
{ "type": "string" },
|
|
45
|
+
{
|
|
46
|
+
"type": "object",
|
|
47
|
+
"properties": { "source": { "const": "local" }, "path": { "type": "string" } },
|
|
48
|
+
"required": ["source", "path"],
|
|
49
|
+
"additionalProperties": true
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"type": "object",
|
|
53
|
+
"properties": { "source": { "const": "url" }, "url": { "type": "string" }, "path": { "type": "string" }, "ref": { "type": "string" }, "sha": { "type": "string" } },
|
|
54
|
+
"required": ["source", "url"],
|
|
55
|
+
"additionalProperties": true
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"type": "object",
|
|
59
|
+
"properties": {
|
|
60
|
+
"source": { "const": "git-subdir" },
|
|
61
|
+
"url": { "type": "string" },
|
|
62
|
+
"path": { "type": "string" },
|
|
63
|
+
"ref": { "type": "string" },
|
|
64
|
+
"sha": { "type": "string" }
|
|
65
|
+
},
|
|
66
|
+
"required": ["source", "url", "path"],
|
|
67
|
+
"additionalProperties": true
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"type": "object",
|
|
71
|
+
"properties": { "source": { "const": "npm" }, "package": { "type": "string" }, "version": { "type": "string" }, "registry": { "type": "string" } },
|
|
72
|
+
"required": ["source", "package"],
|
|
73
|
+
"additionalProperties": true
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|