universal-plugin 0.2.1 → 0.3.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.
- package/.claude-plugin/plugin.json +15 -0
- package/.codex-plugin/plugin.json +14 -0
- package/.cursor-plugin/plugin.json +14 -0
- package/agents/agentskills-specialist.md +132 -0
- package/bin/upx.mjs +6 -0
- package/dist/cli.mjs +1330 -255
- package/dist/run.mjs +271 -0
- package/governances/plugin-design.md +22 -17
- package/governances/slash-invocation.md +30 -0
- package/package.json +14 -5
- package/plugin.json +18 -0
- package/readme.md +37 -3
- package/skills/adopt-upx/README.md +38 -0
- package/skills/adopt-upx/SKILL.md +120 -0
- package/skills/adopt-upx/scripts/rewrite-upx.mjs +168 -0
- package/skills/migrate-plugin/SKILL.md +106 -0
- package/skills/migrate-plugin/evals/evals.json +11 -0
- package/skills/migrate-plugin/evals/trigger-queries.json +35 -0
- package/skills/plugin/README.md +37 -0
- package/skills/plugin/SKILL.md +105 -0
- package/skills/plugin/assets/templates/agent.md +7 -0
- package/skills/plugin/assets/templates/command.md +9 -0
- package/skills/plugin/assets/templates/hooks.json +9 -0
- package/skills/plugin/assets/templates/plugin.json +19 -0
- package/skills/plugin/assets/templates/setup-command.md +15 -0
- package/skills/plugin/assets/templates/skill.md +15 -0
- package/skills/plugin/references/adopt.md +114 -0
- package/skills/plugin/references/create.md +163 -0
- package/skills/plugin/references/delete.md +23 -0
- package/skills/plugin/references/inspect.md +21 -0
- package/skills/plugin/references/update.md +26 -0
- package/skills/plugin/references/version.md +97 -0
- package/skills/publish-plugin/SKILL.md +246 -0
- package/skills/publish-plugin/evals/evals.json +23 -0
- package/skills/publish-plugin/references/vendor-requirements.md +38 -0
- package/skills/upgrade-plugin/README.md +23 -0
- package/skills/upgrade-plugin/SKILL.md +86 -0
- package/LICENSE +0 -21
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Adopt the open standard
|
|
2
|
+
|
|
3
|
+
Convert something that is *already* a plugin — or already ships skills — onto the canonical
|
|
4
|
+
Agent Plugins Specification manifest, without changing what it does.
|
|
5
|
+
|
|
6
|
+
Two starting shapes land here:
|
|
7
|
+
|
|
8
|
+
- **A vendor-specific plugin** — it has one or more hand-written vendor manifests
|
|
9
|
+
(`.claude-plugin/plugin.json`, `.cursor-plugin/plugin.json`, …) and no canonical root
|
|
10
|
+
`plugin.json`.
|
|
11
|
+
- **Bare public skills** — it ships `skills/<name>/SKILL.md` to users but has no plugin manifest of
|
|
12
|
+
any kind.
|
|
13
|
+
|
|
14
|
+
Adoption is **lossless by contract**: every vendor that worked before must still work after. Step 6
|
|
15
|
+
is the check that proves it — do not skip it.
|
|
16
|
+
|
|
17
|
+
## Step 0 — Confirm the user wants this
|
|
18
|
+
|
|
19
|
+
Adoption rewrites the project's manifest layout and turns hand-written vendor manifests into
|
|
20
|
+
generated artifacts. Say that plainly and get agreement before touching files. If the user declines,
|
|
21
|
+
route back to whatever they originally asked for.
|
|
22
|
+
|
|
23
|
+
Also confirm the working tree is clean (`git status`). The Step 6 diff is worthless if uncommitted
|
|
24
|
+
changes are mixed in.
|
|
25
|
+
|
|
26
|
+
## Step 1 — Inventory what exists
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
ls -d .claude-plugin .cursor-plugin .codex-plugin .github/plugin .plugin 2>/dev/null
|
|
30
|
+
test -f plugin.json && cat plugin.json
|
|
31
|
+
find . -name SKILL.md -not -path '*/node_modules/*' -not -path './.git/*'
|
|
32
|
+
ls .mcp.json .lsp.json hooks/ commands/ agents/ rules/ output-styles/ 2>/dev/null
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Record, for each vendor manifest found: its path, and every field it sets. You are about to
|
|
36
|
+
reproduce all of it.
|
|
37
|
+
|
|
38
|
+
**If a root `plugin.json` already exists**, read it before assuming anything. It is either the
|
|
39
|
+
canonical manifest (has `$schema` pointing at `agent-plugins.org` and an `extensions` object — in
|
|
40
|
+
which case there is nothing to adopt; route to `update.md` or `inspect.md` instead), or a legacy
|
|
41
|
+
Copilot CLI manifest that now collides with the canonical path and must be folded in.
|
|
42
|
+
|
|
43
|
+
## Step 2 — Sort every field into shared vs vendor-specific
|
|
44
|
+
|
|
45
|
+
Build two buckets from the manifests you inventoried:
|
|
46
|
+
|
|
47
|
+
- **Shared metadata** — `name`, `version`, `description`, `author`, `homepage`, `repository`,
|
|
48
|
+
`license`, `keywords`, and the component paths. These go at the canonical top level.
|
|
49
|
+
- **Vendor-specific** — anything only one runtime understands (Cursor's `publisher`/`category`/
|
|
50
|
+
`tags`, Codex's `interface`, Copilot's `category`/`tags`). These go under
|
|
51
|
+
`extensions["org.cyberuni.universal-plugin"].harnesses.<vendor>`.
|
|
52
|
+
|
|
53
|
+
Where two vendor manifests disagree on a shared field, **ask the user** which value is canonical
|
|
54
|
+
rather than picking one. A silent choice here is a silent behavior change for one of their runtimes.
|
|
55
|
+
|
|
56
|
+
## Step 3 — Write the canonical manifest
|
|
57
|
+
|
|
58
|
+
Scaffold it, naming exactly the vendors you found in Step 1:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npx universal-plugin plugin init --name <name> --vendor claude-code --vendor cursor
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
> `plugin init` writes a **minimal** manifest — `$schema`, `name`, and the `vendors` list. It does
|
|
65
|
+
> not read your existing vendor manifests. Carry the Step 2 buckets in by hand afterwards.
|
|
66
|
+
|
|
67
|
+
Then fill in the shared metadata and `harnesses` as laid out in
|
|
68
|
+
[`create.md`](./create.md) Step 5. Point the component paths at the directories that already exist —
|
|
69
|
+
adoption must not move files.
|
|
70
|
+
|
|
71
|
+
For the bare-public-skills case there is no metadata to carry over; supply `name`, `description`,
|
|
72
|
+
and `version`, set `"skills": "./skills/"`, and choose vendors with the user (see
|
|
73
|
+
[`create.md`](./create.md) Step 2).
|
|
74
|
+
|
|
75
|
+
## Step 4 — Decide what happens to the old manifests
|
|
76
|
+
|
|
77
|
+
The vendor manifests are now **build outputs**. They stay at the same paths, but they are
|
|
78
|
+
regenerated rather than edited.
|
|
79
|
+
|
|
80
|
+
- Commit them as-is first, so Step 6 has a baseline to diff against.
|
|
81
|
+
- Tell the user they are generated from here on, and that hand-edits will be overwritten by
|
|
82
|
+
`plugin build`.
|
|
83
|
+
- If the project has a legacy root `plugin.json` for Copilot CLI, that path is now the canonical
|
|
84
|
+
manifest — its derived Copilot output moves elsewhere. Check the vendor output table in
|
|
85
|
+
[`create.md`](./create.md) Step 2 for the current path.
|
|
86
|
+
|
|
87
|
+
## Step 5 — Build
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npx universal-plugin plugin build
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Step 6 — Prove it was lossless
|
|
94
|
+
|
|
95
|
+
This is the point of the whole procedure.
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
git diff -- .claude-plugin .cursor-plugin .codex-plugin .github/plugin
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Read every line of that diff. Expect only formatting and key-order churn.
|
|
102
|
+
|
|
103
|
+
**Any field that disappeared is a regression**, not a cleanup. Trace it back: either it belongs in
|
|
104
|
+
the shared metadata, or it belongs in that vendor's `harnesses` entry, or it is a field the build
|
|
105
|
+
does not yet support — in which case stop and tell the user rather than shipping a quiet
|
|
106
|
+
capability loss.
|
|
107
|
+
|
|
108
|
+
Then confirm the plugin still loads. See [`create.md`](./create.md) Step 8 for local install.
|
|
109
|
+
|
|
110
|
+
## Step 7 — Hand off
|
|
111
|
+
|
|
112
|
+
- Audit the skills: [`create.md`](./create.md) Step 6.
|
|
113
|
+
- Shipping it on npm? → `migrate-plugin`.
|
|
114
|
+
- Listing it in the marketplace? → `publish-plugin`.
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Create a universal plugin
|
|
2
|
+
|
|
3
|
+
Scaffold a new plugin from a single canonical `plugin.json` and build one manifest per chosen
|
|
4
|
+
vendor.
|
|
5
|
+
|
|
6
|
+
## Step 1 — Gather plugin identity
|
|
7
|
+
|
|
8
|
+
Ask if not provided. All fields map to the canonical root `plugin.json`.
|
|
9
|
+
|
|
10
|
+
| Field | Required | Notes |
|
|
11
|
+
|-------|----------|-------|
|
|
12
|
+
| `name` | Yes | kebab-case, 1–64 chars, `a-z 0-9 - .` only |
|
|
13
|
+
| `description` | Recommended | one sentence; Codex requires this |
|
|
14
|
+
| `version` | If publishing | semver; Codex requires this |
|
|
15
|
+
| `author.name` | Recommended | person or org name |
|
|
16
|
+
| `homepage` | Optional | docs or landing page URL |
|
|
17
|
+
| `repository` | Optional | source repo URL |
|
|
18
|
+
| `license` | Optional | SPDX identifier e.g. `MIT` |
|
|
19
|
+
| `keywords` | Optional | discovery tags; array of strings |
|
|
20
|
+
|
|
21
|
+
## Step 2 — Choose vendor targets
|
|
22
|
+
|
|
23
|
+
Ask the user which runtimes to support. Each chosen vendor becomes a key in
|
|
24
|
+
`extensions["org.cyberuni.universal-plugin"].harnesses` — that is what drives the `build` output.
|
|
25
|
+
Add the vendor's id to `extensions["org.cyberuni.universal-plugin"].vendors` too, so `build` knows
|
|
26
|
+
to generate its manifest.
|
|
27
|
+
|
|
28
|
+
| Vendor ID | Manifest read from | Hook event case | Required fields beyond `name` |
|
|
29
|
+
|-----------|--------------------|-----------------|-------------------------------|
|
|
30
|
+
| `claude-code` | `.claude-plugin/plugin.json` *(derived)* | PascalCase | none |
|
|
31
|
+
| `cursor` | `.cursor-plugin/plugin.json` *(derived)* | camelCase | none |
|
|
32
|
+
| `codex` | `.codex-plugin/plugin.json` *(derived)* | PascalCase | `version`, `description` |
|
|
33
|
+
| `copilot-cli` | root `plugin.json` — **the canonical manifest itself** | camelCase | none |
|
|
34
|
+
|
|
35
|
+
**Copilot CLI derives nothing.** It searches `.plugin/plugin.json` → `plugin.json` →
|
|
36
|
+
`.github/plugin/plugin.json` → `.claude-plugin/plugin.json` and takes the *first* match, so root
|
|
37
|
+
always wins; and it has read Open Plugin Spec v1 manifests since v1.0.74. `plugin build` reports it
|
|
38
|
+
with status `canonical` and writes no file. A `harnesses["copilot-cli"]` override cannot be
|
|
39
|
+
delivered — the canonical schema is closed to vendor-only fields — and the build warns if you set
|
|
40
|
+
one.
|
|
41
|
+
|
|
42
|
+
Universal minimum (no vendor manifest needed): `skills/<name>/SKILL.md` + `.mcp.json`.
|
|
43
|
+
|
|
44
|
+
Default to all four if the user is unsure.
|
|
45
|
+
|
|
46
|
+
## Step 3 — Choose components
|
|
47
|
+
|
|
48
|
+
Infer from context; ask only if ambiguous. Apply rules from the `plugin-design` governance loaded
|
|
49
|
+
in the gateway's Prerequisites.
|
|
50
|
+
|
|
51
|
+
| Component | Field | Directory | Cross-vendor? |
|
|
52
|
+
|-----------|-------|-----------|--------------|
|
|
53
|
+
| Skills | `skills` | `skills/<name>/SKILL.md` | Yes — all |
|
|
54
|
+
| Commands | `commands` | `commands/<name>.md` | Claude Code, Cursor, Copilot CLI |
|
|
55
|
+
| Agents | `agents` | `agents/<name>.md` | Claude Code, Cursor, Copilot CLI |
|
|
56
|
+
| MCP servers | `mcpServers` | `.mcp.json` | Yes — all |
|
|
57
|
+
| Hooks | `hooks` | `hooks/hooks.json` | Partial — event names translated on build |
|
|
58
|
+
| Rules | `rules` | `rules/<name>.mdc` | Cursor-only |
|
|
59
|
+
| LSP servers | `lspServers` | `.lsp.json` | Claude Code, Cursor |
|
|
60
|
+
| Output styles | `outputStyles` | `output-styles/` | Claude Code only |
|
|
61
|
+
|
|
62
|
+
## Step 4 — Scaffold files
|
|
63
|
+
|
|
64
|
+
Read the templates from `../assets/templates/` and fill in the placeholders:
|
|
65
|
+
|
|
66
|
+
| File to create | Template |
|
|
67
|
+
|----------------|----------|
|
|
68
|
+
| `plugin.json` | `assets/templates/plugin.json` |
|
|
69
|
+
| `skills/<name>/SKILL.md` | `assets/templates/skill.md` |
|
|
70
|
+
| `commands/<name>.md` | `assets/templates/command.md` |
|
|
71
|
+
| `agents/<name>.md` | `assets/templates/agent.md` |
|
|
72
|
+
| `hooks/hooks.json` | `assets/templates/hooks.json` |
|
|
73
|
+
| `commands/setup.md` (when `rules/` included) | `assets/templates/setup-command.md` |
|
|
74
|
+
|
|
75
|
+
Directory layout:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
<plugin-name>/
|
|
79
|
+
├── plugin.json ← canonical definition (source of truth)
|
|
80
|
+
├── skills/<name>/SKILL.md
|
|
81
|
+
├── commands/
|
|
82
|
+
├── agents/
|
|
83
|
+
├── rules/ (only if always-on Cursor guidance requested)
|
|
84
|
+
├── hooks/hooks.json
|
|
85
|
+
├── .mcp.json
|
|
86
|
+
└── README.md
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Step 5 — Populate extensions["org.cyberuni.universal-plugin"]
|
|
90
|
+
|
|
91
|
+
In root `plugin.json`, under `extensions["org.cyberuni.universal-plugin"]`, add the chosen vendors
|
|
92
|
+
to `vendors` and add a `harnesses` object with one entry per chosen vendor. An empty `{}` opts into
|
|
93
|
+
that vendor's output with no vendor-specific fields.
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
|
|
98
|
+
"name": "<plugin-name>",
|
|
99
|
+
"version": "1.0.0",
|
|
100
|
+
"description": "<description>",
|
|
101
|
+
"author": { "name": "<author>" },
|
|
102
|
+
"extensions": {
|
|
103
|
+
"org.cyberuni.universal-plugin": {
|
|
104
|
+
"vendors": ["claude-code", "cursor", "codex", "copilot-cli"],
|
|
105
|
+
"skills": "./skills/",
|
|
106
|
+
"harnesses": {
|
|
107
|
+
"claude-code": {},
|
|
108
|
+
"cursor": {
|
|
109
|
+
"publisher": "<org>",
|
|
110
|
+
"category": "<category>",
|
|
111
|
+
"tags": ["<tag>"]
|
|
112
|
+
},
|
|
113
|
+
"codex": {
|
|
114
|
+
"interface": {
|
|
115
|
+
"displayName": "<Human Name>",
|
|
116
|
+
"category": "<category>"
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
"copilot-cli": {
|
|
120
|
+
"category": "<category>",
|
|
121
|
+
"tags": ["<tag>"]
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
See spec §3.3 for the full list of vendor-specific fields:
|
|
130
|
+
https://github.com/cyberuni/universal-plugin/blob/main/packages/universal-plugin/.agents/spec/spec.md
|
|
131
|
+
|
|
132
|
+
## Step 6 — Audit skills
|
|
133
|
+
|
|
134
|
+
Audit each skill via the aced **improve-skill** skill's mechanical `validate.mts` engine:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
node "<path to aced improve-skill>/scripts/validate.mts" --path skills/<skill-name>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Fix any CRITICAL findings. Then invoke the **audit-skill** skill for full review.
|
|
141
|
+
|
|
142
|
+
## Step 7 — Build vendor manifests
|
|
143
|
+
|
|
144
|
+
> **Note:** The `build` CLI is not yet available. Use the manual steps below.
|
|
145
|
+
|
|
146
|
+
For each vendor in `extensions["org.cyberuni.universal-plugin"].vendors`:
|
|
147
|
+
|
|
148
|
+
1. Copy canonical fields from root `plugin.json`
|
|
149
|
+
2. Merge vendor-specific fields from `extensions["org.cyberuni.universal-plugin"].harnesses.<vendor>`
|
|
150
|
+
3. Drop fields not supported by that vendor (see spec §6.1)
|
|
151
|
+
4. Translate hook event names (see spec §4.2)
|
|
152
|
+
5. Translate `${PLUGIN_ROOT}` and `${PLUGIN_DATA}` env vars (see spec §5)
|
|
153
|
+
6. Write to the vendor output path (see the Step 2 table)
|
|
154
|
+
|
|
155
|
+
See spec §7 for full build rules:
|
|
156
|
+
https://github.com/cyberuni/universal-plugin/blob/main/packages/universal-plugin/.agents/spec/spec.md
|
|
157
|
+
|
|
158
|
+
## Step 8 — Install locally for testing
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
ln -sf "$(pwd)" ~/.claude/plugins/local/<plugin-name> # Claude Code
|
|
162
|
+
ln -sf "$(pwd)" ~/.cursor/plugins/local/<plugin-name> # Cursor → Developer: Reload Window
|
|
163
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Delete a universal plugin
|
|
2
|
+
|
|
3
|
+
## Remove generated manifests only (keep source)
|
|
4
|
+
|
|
5
|
+
Delete each vendor's output file. Generated manifests are build artifacts — safe to delete and
|
|
6
|
+
regenerate via [`create.md`](./create.md) Step 7.
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
rm -f .claude-plugin/plugin.json
|
|
10
|
+
rm -f .cursor-plugin/plugin.json
|
|
11
|
+
rm -f .codex-plugin/plugin.json
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
> **Never delete root `plugin.json`.** It is the canonical source of truth, not a build artifact —
|
|
15
|
+
> and it is also what Copilot CLI reads, so removing it takes out both the source and the Copilot
|
|
16
|
+
> target. `copilot-cli` has no generated manifest to clean.
|
|
17
|
+
|
|
18
|
+
If the project has a stale `.github/plugin/plugin.json` from an older build, it is safe to delete —
|
|
19
|
+
that path is shadowed by root and is no longer generated.
|
|
20
|
+
|
|
21
|
+
## Remove the whole plugin
|
|
22
|
+
|
|
23
|
+
Delete the plugin root directory. Confirm with the user before proceeding — this is irreversible.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Inspect a universal plugin
|
|
2
|
+
|
|
3
|
+
Show the current state of a plugin.
|
|
4
|
+
|
|
5
|
+
1. Read root `plugin.json` — show `name`, `version`, declared vendors
|
|
6
|
+
(`extensions["org.cyberuni.universal-plugin"].vendors`).
|
|
7
|
+
2. For each vendor, check whether the generated manifest exists at its output path.
|
|
8
|
+
3. Report status: which vendors are built, which are missing or stale.
|
|
9
|
+
|
|
10
|
+
Example output:
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
Plugin: my-plugin v1.0.0
|
|
14
|
+
Vendors declared: claude-code, cursor, codex, copilot-cli
|
|
15
|
+
claude-code .claude-plugin/plugin.json ✓ present
|
|
16
|
+
cursor .cursor-plugin/plugin.json ✓ present
|
|
17
|
+
codex .codex-plugin/plugin.json ✗ missing — run build
|
|
18
|
+
copilot-cli plugin.json ✗ missing — run build
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Vendor output paths are listed in [`create.md`](./create.md) Step 2.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Update a universal plugin
|
|
2
|
+
|
|
3
|
+
Change which vendors or components an existing plugin declares. Every path ends with a rebuild —
|
|
4
|
+
see [`create.md`](./create.md) Step 7.
|
|
5
|
+
|
|
6
|
+
## Add a vendor
|
|
7
|
+
|
|
8
|
+
1. Add the vendor id to `extensions["org.cyberuni.universal-plugin"].vendors` in root
|
|
9
|
+
`plugin.json`, and add its key to `extensions["org.cyberuni.universal-plugin"].harnesses`.
|
|
10
|
+
2. Populate vendor-specific fields (see spec §3.3).
|
|
11
|
+
3. If the vendor requires extra fields (`codex`: `version`, `description`), ensure they are in the
|
|
12
|
+
canonical section.
|
|
13
|
+
4. Rebuild for the new vendor.
|
|
14
|
+
|
|
15
|
+
## Remove a vendor
|
|
16
|
+
|
|
17
|
+
1. Remove the vendor id from `extensions["org.cyberuni.universal-plugin"].vendors` and its key from
|
|
18
|
+
`harnesses`.
|
|
19
|
+
2. Delete the generated manifest at its output path.
|
|
20
|
+
|
|
21
|
+
## Add or remove a component
|
|
22
|
+
|
|
23
|
+
1. Add/remove the component field under `extensions["org.cyberuni.universal-plugin"]` in root
|
|
24
|
+
`plugin.json` (e.g. `"commands": "./commands/"`).
|
|
25
|
+
2. Scaffold or delete the corresponding files.
|
|
26
|
+
3. Rebuild to regenerate all vendor manifests.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Move a universal plugin's version
|
|
2
|
+
|
|
3
|
+
Bump or set the version a plugin releases under, keeping every file that carries one in sync.
|
|
4
|
+
|
|
5
|
+
A plugin's version lives in up to five places, but only **two are authored** — the canonical root
|
|
6
|
+
`plugin.json` and, when the project declares a `packagePath`, that `package.json`. The per-vendor
|
|
7
|
+
manifests, the local marketplace catalogs, and the `npx`/`upx` pins inside `skills/**/SKILL.md` are
|
|
8
|
+
all **derived**. So never hand-edit a version: editing one file leaves the other authored file and
|
|
9
|
+
every derived artifact stale, and a consumer's plugin cache is keyed by version, so a content change
|
|
10
|
+
without a matching bump is invisible to them.
|
|
11
|
+
|
|
12
|
+
## Step 0 — Does this repo use changesets?
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
test -d .changeset && echo "changesets"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**If it does**, the version number is decided by changesets, not by you. Add a changeset and let the
|
|
19
|
+
release run — the repo's `version` script should already call `publish sync-version`, which carries
|
|
20
|
+
the released number from `package.json` into the canonical manifest:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npx universal-plugin publish sync-version
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Do **not** run `plugin version` in a changesets repo — it would decide a number changesets is about
|
|
27
|
+
to decide again.
|
|
28
|
+
|
|
29
|
+
**If it does not**, `plugin version` is the whole release-number step. Continue below.
|
|
30
|
+
|
|
31
|
+
## Step 1 — Move the version
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npx universal-plugin plugin version <bump>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`<bump>` is either a semver release type or an explicit version:
|
|
38
|
+
|
|
39
|
+
| `<bump>` | From `1.2.3` you get |
|
|
40
|
+
|---|---|
|
|
41
|
+
| `patch` | `1.2.4` |
|
|
42
|
+
| `minor` | `1.3.0` |
|
|
43
|
+
| `major` | `2.0.0` |
|
|
44
|
+
| `prerelease --preid beta` | `1.2.4-beta.0` |
|
|
45
|
+
| `2.0.0-rc.1` (explicit) | `2.0.0-rc.1` |
|
|
46
|
+
|
|
47
|
+
Useful flags:
|
|
48
|
+
|
|
49
|
+
| Flag | Effect |
|
|
50
|
+
|---|---|
|
|
51
|
+
| `--preid <id>` | Prerelease identifier for the `pre*` release types |
|
|
52
|
+
| `--dry-run` | Print the plan, write nothing — run this first when unsure |
|
|
53
|
+
| `--force` | Allow a target that does not advance on the current version |
|
|
54
|
+
| `--no-build` | Skip re-deriving the vendor manifests (you will run `plugin build` yourself) |
|
|
55
|
+
| `--format json` | Machine-readable result: `from`, `to`, `written` |
|
|
56
|
+
|
|
57
|
+
**Which release type?** That is the user's call, not the command's and not yours to guess — a
|
|
58
|
+
version is a promise to consumers about what broke. If the user has not said, ask, and offer the
|
|
59
|
+
semver reading of the change: breaking → `major`, new behavior → `minor`, fix only → `patch` (on a
|
|
60
|
+
`0.x` plugin, breaking → `minor` and everything else → `patch`).
|
|
61
|
+
|
|
62
|
+
## Step 2 — Confirm what moved
|
|
63
|
+
|
|
64
|
+
The command reports every file it wrote and every manifest it re-derived. Expect the canonical
|
|
65
|
+
manifest, the `packagePath` `package.json` if one is declared, and one derived manifest per declared
|
|
66
|
+
harness:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npx universal-plugin plugin version patch --format json
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
If the plugin declares no harnesses, only the authored files are written — that is correct, not a
|
|
73
|
+
failure.
|
|
74
|
+
|
|
75
|
+
## Guards
|
|
76
|
+
|
|
77
|
+
Every guard resolves before the first write, so a failed run leaves the tree untouched.
|
|
78
|
+
|
|
79
|
+
| Message names | What it means | Do this |
|
|
80
|
+
|---|---|---|
|
|
81
|
+
| a missing `plugin.json` | not at a plugin root, or the plugin was never scaffolded | `cd` to the plugin root, or see [`create.md`](./create.md) |
|
|
82
|
+
| no version to bump from | the manifest has never carried a `version` | pass an explicit version (`plugin version 0.1.0`) to set the first one |
|
|
83
|
+
| an unknown version or release type | the argument is neither a release type nor valid semver | use one of the values in the table above |
|
|
84
|
+
| a target that does not advance | the requested version is not greater than the current one | pick a higher version, or pass `--force` if the user genuinely wants to move backward |
|
|
85
|
+
| a missing `package.json` at `packagePath` | `.agents/universal-plugin.json` names a package directory that does not exist | fix `packagePath`, or create the package |
|
|
86
|
+
|
|
87
|
+
## Do not
|
|
88
|
+
|
|
89
|
+
- **Hand-edit a `version` field.** Two authored files and every derived artifact fall out of sync.
|
|
90
|
+
- **Write a derived manifest.** `.claude-plugin/plugin.json` and its siblings belong to
|
|
91
|
+
`plugin build`; the bump already re-derived them.
|
|
92
|
+
- **Run `npm version`.** It knows only `package.json` and leaves the canonical manifest — the actual
|
|
93
|
+
source of truth — stale.
|
|
94
|
+
|
|
95
|
+
## References
|
|
96
|
+
|
|
97
|
+
- Spec: https://github.com/cyberuni/universal-plugin/blob/main/packages/universal-plugin/.agents/spec/plugin/version/README.md
|