universal-plugin 0.9.0 → 0.11.0

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.
@@ -1,10 +1,8 @@
1
1
  {
2
2
  "claude-code": {
3
3
  "sessionStartEvent": "SessionStart",
4
- "globalManifest": "~/.claude/plugins/installed_plugins.json",
5
4
  "projectManifest": null,
6
5
  "hookGlob": "~/.claude/plugins/universal-plugin/hooks/hooks.json",
7
- "globalPluginDir": "~/.claude/plugins/",
8
6
  "pluginRootSuffix": ".claude-plugin/plugin.json",
9
7
  "localPluginDir": "~/.claude/skills/",
10
8
  "localPluginLink": true,
@@ -15,12 +13,9 @@
15
13
  },
16
14
  "cursor": {
17
15
  "sessionStartEvent": "sessionStart",
18
- "globalManifest": null,
19
16
  "projectManifest": null,
20
17
  "hookGlob": null,
21
- "globalPluginDir": null,
22
18
  "pluginRootSuffix": ".cursor-plugin/plugin.json",
23
- "localPluginDir": "~/.cursor/plugins/local/",
24
19
  "localPluginLink": false,
25
20
  "localReload": "run Developer: Reload Window in Cursor",
26
21
  "installCommand": null,
@@ -29,10 +24,8 @@
29
24
  },
30
25
  "codex": {
31
26
  "sessionStartEvent": "SessionStart",
32
- "globalManifest": null,
33
27
  "projectManifest": null,
34
28
  "hookGlob": null,
35
- "globalPluginDir": null,
36
29
  "pluginRootSuffix": ".codex-plugin/plugin.json",
37
30
  "localPluginDir": null,
38
31
  "localPluginLink": false,
@@ -43,10 +36,8 @@
43
36
  },
44
37
  "copilot-cli": {
45
38
  "sessionStartEvent": "sessionStart",
46
- "globalManifest": null,
47
39
  "projectManifest": null,
48
40
  "hookGlob": null,
49
- "globalPluginDir": null,
50
41
  "pluginRootSuffix": "plugin.json",
51
42
  "localPluginDir": null,
52
43
  "localPluginLink": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "universal-plugin",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "Universal AI agent plugin build tool",
5
5
  "keywords": [
6
6
  "agent-plugin",
@@ -28,8 +28,8 @@
28
28
  "LICENSE",
29
29
  "bin",
30
30
  "dist",
31
- "governances",
32
31
  "plugin.json",
32
+ "references",
33
33
  "schema",
34
34
  ".claude-plugin",
35
35
  ".cursor-plugin",
@@ -39,6 +39,7 @@
39
39
  "agents"
40
40
  ],
41
41
  "dependencies": {
42
+ "@cyberuni/agent-harness": "^0.1.0",
42
43
  "@repobuddy/upx": "^0.1.0",
43
44
  "@toon-format/toon": "^4.1.1",
44
45
  "commander": "^14.0.3",
@@ -63,13 +64,12 @@
63
64
  },
64
65
  "scripts": {
65
66
  "build": "tsdown",
66
- "check:governances": "tsx src/cli.ts plugin build --check --root .",
67
67
  "dev": "tsx src/cli.ts",
68
68
  "knip": "knip",
69
69
  "lint": "biome check .",
70
70
  "test": "pnpm build && vitest run src",
71
71
  "test:watch": "vitest",
72
72
  "typecheck": "tsc --noEmit",
73
- "verify": "pnpm typecheck && pnpm lint && pnpm test && pnpm check:governances"
73
+ "verify": "pnpm typecheck && pnpm lint && pnpm test"
74
74
  }
75
75
  }
package/plugin.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
3
3
  "name": "universal-plugin",
4
- "version": "0.9.0",
4
+ "version": "0.11.0",
5
5
  "description": "Research and design toolkit for building universal AI coding agent plugins that work across Claude Code, Cursor, Codex, and GitHub Copilot CLI.",
6
6
  "author": {
7
7
  "name": "unional"
package/readme.md CHANGED
@@ -79,11 +79,15 @@ keep their previous version.
79
79
 
80
80
  ```sh
81
81
  npx universal-plugin marketplace init --codex --root .
82
+ npx universal-plugin marketplace add npm:repobuddy --description "Repo automation"
82
83
  npx universal-plugin marketplace validate --root .
83
84
  ```
84
85
 
85
- `validate` checks each catalog against the schema its runtime loads and names the key at fault, so a
86
- catalog that would be refused at install time is caught in the repository.
86
+ `init` derives a catalog from the plugins a repository holds. `add` lists a plugin that lives
87
+ elsewhere — a path, a GitHub repo (`--subdir` for a monorepo, `--ref`/`--sha` to pin it), an npm
88
+ package, or another marketplace's entry — so a curating repository never needs a hand-written
89
+ catalog. `validate` checks each catalog against the schema its runtime loads and names the key at
90
+ fault, so a catalog that would be refused at install time is caught in the repository.
87
91
 
88
92
  Codex caches a local plugin install by its marketplace entry version. After you change packaged
89
93
  plugin files: update the canonical `plugin.json` version, regenerate the catalog (add `--force` to
@@ -102,14 +106,12 @@ npx universal-plugin config add --key sdd-plugins --entry '{"name":"aces","handl
102
106
  `add` appends the entry, or replaces the existing entry with the same `name`. Both commands print
103
107
  TOON by default; pass `--format json` for JSON.
104
108
 
105
- ### governance
109
+ ### Reference documents
106
110
 
107
- Version-pinned agent-tool contracts, read at runtime.
108
-
109
- ```sh
110
- npx universal-plugin governance list
111
- npx universal-plugin governance show plugin-design
112
- ```
111
+ This package ships its own documents (`plugin-design`, `slash-invocation`, `universal-plugin`) under
112
+ `references/`. Read one with `buddy-agent-harness reference show <name>` in any project that depends
113
+ on `universal-plugin`, or, from a skill, with the `load-reference` skill in the `buddy-agent-harness`
114
+ plugin.
113
115
 
114
116
  ### Housekeeping
115
117
 
@@ -330,10 +330,6 @@ Portability rules for skill bodies: keep each `SKILL.md` body under 6,000 chars;
330
330
 
331
331
  ## References
332
332
 
333
- ```bash
334
- npx universal-plugin@<version> governance show skill-design
335
- npx universal-plugin@<version> governance show skill-repo-structure
336
- npx universal-plugin@<version> governance show agent-tool-output
337
- ```
333
+ Load `skill-design`, `skill-repo-structure`, and `agent-tool-output` with the `load-reference` skill in the `buddy-agent-harness` plugin.
338
334
 
339
335
  Spec: https://github.com/cyberuni/universal-plugin/blob/main/packages/universal-plugin/.agents/spec/spec.md
@@ -0,0 +1,4 @@
1
+ # Universal Plugin Format
2
+
3
+ The rules for the universal plugin format live in `plugin-design`, which this package also ships.
4
+ Load `plugin-design` with the `load-reference` skill in the `buddy-agent-harness` plugin.
@@ -0,0 +1,29 @@
1
+ # build-plugin skill
2
+
3
+ Derive every vendor's form of a plugin from its one canonical `plugin.json`.
4
+
5
+ ## When to use
6
+
7
+ - "build the plugin", "run plugin build"
8
+ - "regenerate the vendor manifests", "sync the manifests after my change"
9
+
10
+ ## What it does
11
+
12
+ Runs `plugin build`, which writes the Claude Code, Cursor, and Codex manifests and Copilot CLI's
13
+ `com.github.copilot/` tree. It also refreshes this plugin's entry in the repository's marketplace
14
+ catalogs. The skill prefers the project's own build
15
+ script, otherwise runs `scripts/build.mjs`, which uses the CLI shipped beside the skill, so nothing
16
+ is downloaded.
17
+
18
+ The skill reads the result back to the user: which vendors were built, which catalogs changed, and
19
+ each warning about something a vendor cannot represent. A `built 0` result is handed to `doctor`
20
+ rather than reported as success.
21
+
22
+ ## Install
23
+
24
+ Ships with the `universal-plugin` plugin. It is invoked in Claude Code as
25
+ `/universal-plugin:build-plugin`.
26
+
27
+ ## References
28
+
29
+ - [`plugin build` spec](https://github.com/cyberuni/universal-plugin/blob/main/packages/universal-plugin/.agents/spec/plugin/build/README.md)
@@ -0,0 +1,137 @@
1
+ ---
2
+ name: build-plugin
3
+ description: Use this skill to build a universal agent plugin — regenerate the Claude Code, Cursor, and Codex manifests and the Copilot CLI component tree from the canonical plugin.json, after editing the manifest, a skill, an agent, a hook, or a command. It also refreshes this plugin's entry in the repository's marketplace catalogs. Trigger on "build the plugin", "regenerate the vendor manifests", "sync the manifests after my change", "run plugin build", or "update .claude-plugin/plugin.json".
4
+ ---
5
+
6
+ # Build a plugin
7
+
8
+ Derive every vendor's form of the plugin from the one canonical `plugin.json`.
9
+
10
+ The canonical root `plugin.json` is the only manifest anyone authors. Everything a runtime reads
11
+ beside it is **derived**, and this build is the one step that writes all of it:
12
+
13
+ | Derived artifact | Read by |
14
+ |---|---|
15
+ | `.claude-plugin/plugin.json`, `.cursor-plugin/plugin.json`, `.codex-plugin/plugin.json` | Claude Code, Cursor, Codex |
16
+ | `com.github.copilot/` (agents, commands, rules, hooks, LSP) | Copilot CLI in spec mode; the manifest itself is root `plugin.json` |
17
+ | this plugin's entry in each marketplace catalog the repository already carries | anyone installing from the repository |
18
+
19
+ So a change to the plugin is not done until it has been built. A runtime reads the derived files,
20
+ not the canonical manifest, and a derived file that predates the change still ships the old plugin.
21
+
22
+ ## Step 0: Is this the right skill?
23
+
24
+ | The ask is | Use instead |
25
+ |---|---|
26
+ | declare a new vendor, component, or field | `init-universal-plugin` edits `plugin.json`, then builds |
27
+ | move the version | `version`: it writes the number and builds |
28
+ | delete derived manifests, or drop a vendor | `remove-plugin` |
29
+ | "the build says built 0" or a runtime loads nothing | `doctor-universal-plugin` |
30
+
31
+ Everything else that ends in "regenerate what the runtimes read" is here.
32
+
33
+ ## Step 1: Find how the project builds
34
+
35
+ ```bash
36
+ grep -n "plugin build" package.json
37
+ ```
38
+
39
+ If a script already runs `plugin build`, run that script (for example `pnpm plugin:build`). It
40
+ carries the project's own `--root` and whatever it chains after the build, such as a formatter over
41
+ the written JSON. Otherwise run the launcher shipped beside this skill:
42
+
43
+ ```bash
44
+ node scripts/build.mjs --root <plugin-root>
45
+ ```
46
+
47
+ Resolve `scripts/build.mjs` against this skill's own directory. It runs the CLI that shipped beside
48
+ it, so nothing is downloaded and the build cannot resolve a different version from the one installed.
49
+ `npx universal-plugin plugin build` is the fallback. `--root` defaults to the working directory and
50
+ must name the directory that holds the canonical `plugin.json`.
51
+
52
+ The command never prompts, so it is safe to run unattended.
53
+
54
+ | Flag | Effect |
55
+ |---|---|
56
+ | `--dry-run` | Validate and report the plan, write nothing. Run this first when unsure what will change |
57
+ | `--vendor <id>` | Build one vendor (`claude-code`, `cursor`, `codex`, `copilot-cli`), and refresh only its catalog |
58
+ | `--verbose` | Print each field-level decision the derivation made |
59
+ | `--format json` | The same result as JSON, for scripts |
60
+
61
+ `--clean` also exists. It deletes derived manifests before rewriting them, so reach for it only
62
+ through `remove-plugin`.
63
+
64
+ ## Step 2: Read the result
65
+
66
+ Default stdout is TOON: one row per vendor (`vendor, path, status`), one row per catalog
67
+ (`path, status`), and a precomputed summary. Read the rows; do not re-derive them.
68
+
69
+ | Vendor status | Meaning |
70
+ |---|---|
71
+ | `built` | the derived manifest or component tree was written |
72
+ | `canonical` | Copilot CLI with nothing to derive: root `plugin.json` serves it directly |
73
+ | `skipped` / `failed` | the row says why; fix that and rebuild |
74
+
75
+ A catalog row reads `updated`, `unchanged`, or `planned` on `--dry-run`. A build **never creates** a
76
+ catalog, and it keeps an entry's non-local source, such as an npm package, while it re-derives the
77
+ version. To add a catalog or change a source, use `marketplace`.
78
+
79
+ Read stderr too. The build drops what a vendor cannot represent and warns instead of failing: a hook
80
+ handler type a vendor cannot run, a `harnesses.copilot-cli` override with no delivery path, an
81
+ invalid catalog. Each warning names something that will not reach a runtime. Tell the user each
82
+ one; do not bury it in a summary.
83
+
84
+ `built 0` with "nothing to build" is not success. The manifest declares no vendor, so hand it to
85
+ `doctor-universal-plugin`, which the stderr line names.
86
+
87
+ ## Step 3: Commit what was derived
88
+
89
+ Derived manifests are committed with the change that caused them, because a
90
+ git-sourced install reads them straight from the repository. Stage the source change and its
91
+ derived files together:
92
+
93
+ ```bash
94
+ git status --short
95
+ ```
96
+
97
+ Expect the vendor manifests, `com.github.copilot/`, and any refreshed catalog. A diff outside those paths did not come from the build.
98
+
99
+ ## Guards
100
+
101
+ Validation runs before the first write, so a failed build leaves the tree untouched.
102
+
103
+ | Message names | What it means | Do this |
104
+ |---|---|---|
105
+ | a missing `plugin.json` | `--root` is not the plugin root | point `--root` at the directory holding the canonical manifest |
106
+ | codex requires `description` / `version` | Codex rejects a manifest without them | add them to `plugin.json` through `init-universal-plugin`, or `version` for the number |
107
+ | a `--vendor` not among the targets | the manifest does not declare that vendor | declare it through `init-universal-plugin`, or drop the flag |
108
+ | `vendorExtensions` or `.plugin/plugin.json` | a pre-0.6 layout this CLI no longer reads | run `doctor-universal-plugin`, which names the migration |
109
+
110
+ ## Do not
111
+
112
+ - **Hand-edit a derived file.** The next build overwrites it. Change `plugin.json` or the component
113
+ source, then build.
114
+ - **Edit `plugin.json` to get a different derived manifest.** A per-vendor field belongs under
115
+ `extensions["org.cyberuni.universal-plugin"].harnesses.<vendor>`. That is a declaration, and
116
+ `init-universal-plugin` owns it.
117
+ - **Expect a build to pin skill `npx` references.** That is the release-time `plugin bundle`, not
118
+ this step.
119
+ - **Expect a build to copy governances into skills.** A skill loads a reference through the
120
+ `load-reference` skill in the `buddy-agent-harness` plugin; the build no longer copies them, and
121
+ `--check` is gone.
122
+
123
+ ## Related skills
124
+
125
+ | Task | Skill |
126
+ |------|-------|
127
+ | Change what the plugin declares | `init-universal-plugin` |
128
+ | Diagnose a build that derives nothing, or a runtime that loads nothing | `doctor-universal-plugin` |
129
+ | Move the version and rebuild in one step | `version` |
130
+ | Delete derived manifests or drop a vendor | `remove-plugin` |
131
+ | Create a catalog, or list a plugin with an npm source | `marketplace` |
132
+
133
+ ## References
134
+
135
+ - Spec: [`plugin/build/`](https://github.com/cyberuni/universal-plugin/blob/main/packages/universal-plugin/.agents/spec/plugin/build/README.md)
136
+ - [ADR-0014](https://github.com/cyberuni/universal-plugin/blob/main/packages/universal-plugin/.agents/spec/design/decisions/0014-build-refreshes-catalogs.md): the build refreshes catalogs it finds
137
+ - [ADR-0017](https://github.com/cyberuni/universal-plugin/blob/main/packages/universal-plugin/.agents/spec/design/decisions/0017-retire-governance-for-reference.md): the build no longer copies governances into skills
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ // Runs `universal-plugin plugin build` from the CLI that ships beside this skill, so the manifests a
3
+ // plugin ships are derived by the version the author installed, never by one `npx` resolves.
4
+ import { dirname, join } from 'node:path'
5
+ import { fileURLToPath } from 'node:url'
6
+
7
+ // <package>/skills/<skill>/scripts/build.mjs: four levels up is the package root.
8
+ const packageRoot = dirname(dirname(dirname(dirname(fileURLToPath(import.meta.url)))))
9
+
10
+ process.argv.splice(2, 0, 'plugin', 'build')
11
+ await import(join(packageRoot, 'bin', 'universal-plugin.mjs'))
@@ -152,7 +152,7 @@ pushed without a bump reaches nobody who already installed the plugin, and neith
152
152
  ([ADR-0010](../../.agents/spec/design/decisions/0010-version-policy.md) §6).
153
153
 
154
154
  The script compares the shipped paths — the canonical manifest, the skills directory, `agents/`,
155
- `governances/`, `mcp.json` — against the commit that set the version the manifest carries now, and
155
+ `governances/`, `references/`, `mcp.json` — against the commit that set the version the manifest carries now, and
156
156
  emits `unreleased-content` for anything committed since. Uncommitted work is not reported; it has not
157
157
  shipped.
158
158
 
@@ -365,7 +365,7 @@ function commitThatSetVersion(current) {
365
365
  * change twice. */
366
366
  function shippedPaths() {
367
367
  const skills = typeof ext?.skills === 'string' ? ext.skills : './skills/'
368
- const paths = ['plugin.json', skills, 'agents', 'governances', 'mcp.json']
368
+ const paths = ['plugin.json', skills, 'agents', 'governances', 'references', 'mcp.json']
369
369
  return paths.filter((rel) => fs.existsSync(path.join(root, rel)))
370
370
  }
371
371
 
@@ -38,11 +38,8 @@ This skill owns the **authoring** side: the plugin a project ships. Setting a re
38
38
 
39
39
  ## Prerequisites
40
40
 
41
- Load the component-selection governance before any work that adds or removes components:
42
-
43
- ```bash
44
- npx universal-plugin governance show plugin-design
45
- ```
41
+ Before any work that adds or removes components, load `plugin-design` with the `load-reference`
42
+ skill in the `buddy-agent-harness` plugin.
46
43
 
47
44
  It is the authoritative source for which component to reach for and which anti-patterns to avoid.
48
45
 
@@ -236,7 +233,7 @@ This skill is not a formatter. If the project has one, run it over the written f
236
233
 
237
234
  ## References
238
235
 
239
- - Governance: `npx universal-plugin governance show plugin-design`
236
+ - Reference: `plugin-design`, loaded with the `load-reference` skill in the `buddy-agent-harness` plugin
240
237
  - Spec: https://github.com/cyberuni/universal-plugin/blob/main/packages/universal-plugin/.agents/spec/spec.md
241
238
  - Manifest schema (Agent Plugins Specification v1.0.0): https://agent-plugins.org/schemas/1.0.0/plugin.schema.json
242
239
  - Extension schema (the body of `extensions["org.cyberuni.universal-plugin"]`), shipped in the package at
@@ -33,7 +33,7 @@ entry in both `vendors` and `harnesses` under
33
33
  ## Step 3 — Choose components
34
34
 
35
35
  Infer from context; ask only if ambiguous. [`standard.md`](./standard.md) has the component table and
36
- the layout they go in; `governance show plugin-design` decides which component a given need calls
36
+ the layout they go in; the `plugin-design` reference decides which component a given need calls
37
37
  for. The universal minimum is `skills/<name>/SKILL.md` plus `.mcp.json`.
38
38
 
39
39
  ## Step 4 — Scaffold
@@ -62,7 +62,7 @@ what each build gets. A vendor listed in `vendors` with no `harnesses` entry sti
62
62
  └── README.md
63
63
  ```
64
64
 
65
- `plugin init --scaffold` creates the standard `skills/`, `agents/`, `governances/`, and `commands/`
65
+ `plugin init --scaffold` creates the standard `skills/`, `agents/`, `references/`, and `commands/`
66
66
  directories. Create the rest only when the plugin has content for them.
67
67
 
68
68
  ## Components
@@ -80,7 +80,7 @@ directories. Create the rest only when the plugin has content for them.
80
80
 
81
81
  The universal minimum — reaching every runtime with no vendor manifest at all — is
82
82
  `skills/<name>/SKILL.md` plus `.mcp.json`. Reach for a narrower component only when the plugin needs
83
- what only that component does; `governance show plugin-design` is the authority on that choice.
83
+ what only that component does; the `plugin-design` reference is the authority on that choice.
84
84
 
85
85
  ## Constraints
86
86
 
@@ -34,7 +34,7 @@ into the shared `SKILL.md`.
34
34
 
35
35
  `rules/<name>.mdc` reaches Cursor and nothing else. Reach for a rule only when the plugin genuinely
36
36
  needs always-on guidance in Cursor; anything a task can load on demand belongs in a skill, where every
37
- runtime sees it. `governance show plugin-design` is the authority on that call.
37
+ runtime sees it. The `plugin-design` reference is the authority on that call.
38
38
 
39
39
  `.mdc` and `.md` are not interchangeable, and path-scoping has no equivalent in the other runtimes —
40
40
  never generate rules from a skill or a skill from a rule.
@@ -1,15 +1,26 @@
1
1
  # marketplace skill
2
2
 
3
- Make a repository installable on its own terms: generate the marketplace catalogs the runtimes read,
4
- then write the README section that tells users what to type.
3
+ Run a repository's own plugin marketplace: generate the catalogs the runtimes read, list plugins
4
+ that live elsewhere, and check that what is on disk is what each runtime will load.
5
5
 
6
- ## What it does
6
+ ## A gateway over three routes
7
7
 
8
- `marketplace init` discovers the plugins under `plugins/` and derives one catalog per selected
9
- runtime. This skill picks the targets with the user, runs the generation, validates every catalog
10
- against the schema its runtime loads, and offers the install documentation that goes with it.
8
+ `SKILL.md` holds no procedure. It classifies the request and loads one reference:
11
9
 
12
- Nothing is published. The catalogs sit in the repository until someone adds it as a marketplace.
10
+ | Route | Covers | Reference |
11
+ | --- | --- | --- |
12
+ | `init` | The repository holds the plugins. Derive a catalog from `plugins/`, then offer the README install section. | `references/init.md` |
13
+ | `add` | The plugin lives elsewhere — an npm package, a GitHub repo, or `<plugin>@<marketplace>`. | `references/add.md` |
14
+ | `validate` | Check the catalogs against the schema each runtime loads. Both other routes end here. | `references/validate.md` |
15
+
16
+ The split exists because the two writing routes answer different questions and share almost no
17
+ steps. A single document had to hedge every instruction with "unless the plugin is not in this
18
+ repository", and the `add` half did not exist at all.
19
+
20
+ `init` and `add` compose on one repository. A regeneration keeps the entries `add` wrote, because
21
+ discovery could never have produced them — and keeps a non-local source on a plugin it *does*
22
+ discover, so a plugin shipped through npm is not rewritten to a repository path holding gitignored
23
+ build output.
13
24
 
14
25
  ## Support is uneven, and the skill says so
15
26
 
@@ -25,6 +36,10 @@ evidence ID. That constraint exists because the obvious way to write an install
25
36
  one from another project's README, and two of the four commands in the README that prompted this
26
37
  skill are not in any vendor documentation.
27
38
 
39
+ The unevenness reaches `add` as well: only a repository path installs everywhere. An npm source
40
+ reaches Claude Code and Codex, and the other two are reported skipped rather than written a source
41
+ they refuse.
42
+
28
43
  ## The validation half
29
44
 
30
45
  `scripts/validate.mjs` checks each catalog against the shape its runtime actually loads and names the
@@ -45,6 +60,7 @@ document.
45
60
  ## References
46
61
 
47
62
  - [Research: local marketplaces](https://github.com/cyberuni/universal-plugin/blob/main/.research/local-marketplaces/conclusion.md)
63
+ - [`marketplace add` spec](https://github.com/cyberuni/universal-plugin/blob/main/packages/universal-plugin/.agents/spec/marketplace/add/README.md)
48
64
  - [`marketplace init` spec](https://github.com/cyberuni/universal-plugin/blob/main/packages/universal-plugin/.agents/spec/marketplace/init/README.md)
49
65
  - [`marketplace validate` spec](https://github.com/cyberuni/universal-plugin/blob/main/packages/universal-plugin/.agents/spec/marketplace/validate/README.md)
50
66
  - [Official Claude Code marketplace schema](https://json.schemastore.org/claude-code-marketplace.json)