universal-plugin 0.12.2 → 0.14.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 +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/dist/cli.mjs +5197 -4028
- package/package.json +2 -1
- package/plugin.json +30 -1
- package/readme.md +7 -6
- package/references/plugin-design.md +21 -9
- package/schema/extension.schema.json +31 -0
- package/skills/adopt-upx/SKILL.md +4 -2
- package/skills/adopt-upx/scripts/rewrite-upx.mjs +92 -129
- package/skills/build-plugin/README.md +1 -1
- package/skills/build-plugin/SKILL.md +17 -8
- package/skills/build-plugin/scripts/build.mjs +51 -10
- package/skills/doctor-universal-plugin/SKILL.md +53 -23
- package/skills/doctor-universal-plugin/scripts/doctor.mjs +249 -365
- package/skills/init-universal-plugin/SKILL.md +13 -2
- package/skills/init-universal-plugin/references/create.md +9 -6
- package/skills/init-universal-plugin/references/standard.md +1 -1
- package/skills/init-universal-plugin/references/vendors/copilot-cli.md +2 -2
- package/skills/init-universal-plugin/scripts/init.mjs +51 -10
- package/skills/marketplace/references/init.md +1 -1
- package/skills/marketplace/scripts/add.mjs +51 -10
- package/skills/marketplace/scripts/install-docs.mjs +100 -96
- package/skills/marketplace/scripts/marketplace.mjs +51 -10
- package/skills/marketplace/scripts/validate.mjs +51 -10
- package/skills/migrate-plugin/SKILL.md +1 -1
- package/skills/remove-plugin/SKILL.md +1 -1
- package/skills/upgrade-plugin/SKILL.md +2 -0
- package/skills/version/README.md +24 -18
- package/skills/version/SKILL.md +80 -47
- package/skills/version/scripts/version.mjs +51 -10
|
@@ -19,8 +19,9 @@ and that judgment belongs to the skill that owns the write.
|
|
|
19
19
|
node scripts/doctor.mjs
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
Resolve that path against this skill's own directory. It
|
|
23
|
-
|
|
22
|
+
Resolve that path against this skill's own directory. It asks the project's installed CLI
|
|
23
|
+
(`pnpm exec universal-plugin`), else the CLI pinned to this skill's version (`npx`), about the
|
|
24
|
+
current working directory; add `--root <path>` to diagnose elsewhere.
|
|
24
25
|
Add `--marketplace-root <path>` (repeatable) to also check a **separately-cloned** shared marketplace
|
|
25
26
|
repository (e.g. a local clone of `cyberuni/marketplace`) — see
|
|
26
27
|
[Catalogs are checked at the repository root](#catalogs-are-checked-at-the-repository-root).
|
|
@@ -70,27 +71,32 @@ Each `code` below is what the script emits.
|
|
|
70
71
|
|
|
71
72
|
| Finding | What it means | Repair |
|
|
72
73
|
| --- | --- | --- |
|
|
73
|
-
| `no-manifest` | no root `plugin.json` — this is not a plugin yet | `/universal-plugin:init-universal-plugin` |
|
|
74
|
-
| `legacy-manifest` | root `plugin.json` with neither `$schema` nor `extensions` — a single-vendor manifest on the canonical path | `/universal-plugin:init-universal-plugin
|
|
75
|
-
| `vendor-only` | a vendor manifest with no canonical manifest above it | `/universal-plugin:init-universal-plugin
|
|
76
|
-
| `unbuilt` | a declared vendor whose output path holds no file — that runtime sees no plugin | `/universal-plugin:build-plugin` |
|
|
77
|
-
| `stale` | a derived manifest older than `plugin.json`; for a derived directory (`com.github.copilot/`), its newest file is what is compared | `/universal-plugin:build-plugin` |
|
|
74
|
+
| `no-manifest` | no root `plugin.json` — this is not a plugin yet | `/universal-plugin:init-universal-plugin` (pnpm install: `pnpm-universal-plugin-init-universal-plugin`) |
|
|
75
|
+
| `legacy-manifest` | root `plugin.json` with neither `$schema` nor `extensions` — a single-vendor manifest on the canonical path | `/universal-plugin:init-universal-plugin` (pnpm install: `pnpm-universal-plugin-init-universal-plugin`), adopt route |
|
|
76
|
+
| `vendor-only` | a vendor manifest with no canonical manifest above it | `/universal-plugin:init-universal-plugin` (pnpm install: `pnpm-universal-plugin-init-universal-plugin`), adopt route |
|
|
77
|
+
| `unbuilt` | a declared vendor whose output path holds no file — that runtime sees no plugin | `/universal-plugin:build-plugin` (pnpm install: `pnpm-universal-plugin-build-plugin`) |
|
|
78
|
+
| `stale` | a derived manifest older than `plugin.json`; for a derived directory (`com.github.copilot/`), its newest file is what is compared | `/universal-plugin:build-plugin` (pnpm install: `pnpm-universal-plugin-build-plugin`) |
|
|
78
79
|
| `hand-edited` | a derived manifest that `build` would rewrite — the edit is already lost, it just has not been overwritten yet | move the field to the canonical manifest or to `harnesses.<vendor>`, then rebuild |
|
|
79
80
|
| `unknown-vendor` | a `vendors` entry no build target matches; reported as `skipped` plus a warning | fix the id in `plugin.json` |
|
|
80
81
|
| `unsupported-component` | a component path on the shared extension names a component one targeted vendor has none of (`agents` for Codex, `rules` for Claude Code, …); the build leaves it out of that vendor's manifest | declare the path under `harnesses.<vendor>` for the vendors that read it, or leave it — nothing is lost |
|
|
81
|
-
| `
|
|
82
|
+
| `stale-script` | a compiled skill script (`scripts` in the extension) is missing, or no longer matches what its source compiles to. A script that differs only in its embedded version is `version-drift` instead, never both | `/universal-plugin:build-plugin` (pnpm install: `pnpm-universal-plugin-build-plugin`), then commit the compiled script |
|
|
83
|
+
| `script-compile-failed` | a declared script entry could not be compiled into one self-contained file — usually an import that does not resolve from the plugin root | fix the entry, then `/universal-plugin:build-plugin` (pnpm install: `pnpm-universal-plugin-build-plugin`) |
|
|
84
|
+
| `script-over-budget` | a compiled skill script is over the 150 KB budget | have the skill call the installed CLI instead: `pnpm exec <bin>` with a pinned `npx` fallback |
|
|
85
|
+
| `skill-link-escapes` | a relative Markdown link in a skill climbs out of the skill folder (`../../readme.md`). pnpm links or copies each skill folder on its own, and a plugin cache keeps only what ships, so the link resolves to nothing there | copy the file into the skill and link it relatively, or link it by URL |
|
|
86
|
+
| `undeliverable-override` | `harnesses["copilot-cli"]` sets fields that reach nothing | `/universal-plugin:init-universal-plugin` (pnpm install: `pnpm-universal-plugin-init-universal-plugin`), update route — move them to a vendor that has a derived manifest, or drop them |
|
|
82
87
|
| `codex-fields-missing` | Codex is targeted without `version` or `description`; the build fails and writes **nothing at all**, including for the other vendors | add both to the canonical top level |
|
|
83
|
-
| `version-drift` | the
|
|
84
|
-
| `
|
|
85
|
-
| `
|
|
86
|
-
| `
|
|
87
|
-
| `
|
|
88
|
-
| `
|
|
88
|
+
| `version-drift` | one file carries a different version from the release's number — the canonical manifest, a derived vendor manifest, a catalog entry, a skill pin, a marked `mcpServers` entry, or the version a compiled skill script embeds; one finding per file, named by path | `/universal-plugin:version` (pnpm install: `pnpm-universal-plugin-version`) (for a package-sourced drift, `universal-plugin plugin version --from-package`); then [offer the CI check](#offer-the-check-to-ci) |
|
|
89
|
+
| `unstamped` | a place holds `0.0.0-development`, semantic-release's placeholder. The release has not stamped it yet, so it is not drift (severity low) | in `prepareCmd`, `plugin version ${nextRelease.version}`, and commit the stamped files back with `@semantic-release/git`; see `/universal-plugin:version` (pnpm install: `pnpm-universal-plugin-version`) |
|
|
90
|
+
| `unreleased-content` | shipped content was committed after the commit that set the current version — a consumer keyed on that version never re-extracts it | `/universal-plugin:version` (pnpm install: `pnpm-universal-plugin-version`) |
|
|
91
|
+
| `copilot-root-components` | agents, commands, rules, hooks, or LSP servers sit at the plugin root with no copy under `com.github.copilot/` — Copilot CLI reads them only from there in spec mode, so it loads none of them, silently | `/universal-plugin:build-plugin` (pnpm install: `pnpm-universal-plugin-build-plugin`) |
|
|
92
|
+
| `stale-github-plugin` | a leftover `.github/plugin/plugin.json` from an older build — shadowed by root and no longer generated | `/universal-plugin:remove-plugin` (pnpm install: `pnpm-universal-plugin-remove-plugin`) |
|
|
93
|
+
| `shadowing-manifest` | a `.plugin/plugin.json` exists — it outranks root in Copilot CLI's search order and silently shadows the canonical manifest | `/universal-plugin:remove-plugin` (pnpm install: `pnpm-universal-plugin-remove-plugin`) |
|
|
94
|
+
| `no-vendors` | no vendor is declared, so the build writes nothing and no runtime reads the plugin. When the repository carries `vendorExtensions` or a `.plugin/plugin.json`, the build stops rather than reporting an empty result, and the detail says so — read it beside `legacy-manifest` and `shadowing-manifest`, which name the signals | `/universal-plugin:init-universal-plugin` (pnpm install: `pnpm-universal-plugin-init-universal-plugin`), adopt route when `vendorExtensions` or `.plugin/plugin.json` is present, else update route |
|
|
89
95
|
| `package-path-missing` | `packagePath` names a directory with no readable `package.json` | fix `packagePath`, or create the package |
|
|
90
96
|
| `package-path-unknown` | the CLI could not report `packagePath` (a version too old to read it), so `version-drift` and `unreleased-content` were skipped rather than guessed | upgrade universal-plugin |
|
|
91
97
|
| `misplaced-package-path` | `plugin.json` declares `packagePath` under `extensions["org.cyberuni.universal-plugin"]`, where the CLI never reads it — the plugin is silently treated as not shipping to npm | move it to `.agents/universal-plugin.json`, relative to the plugin root |
|
|
92
98
|
| `unparsable-manifest` | root `plugin.json` is not valid JSON | fix the syntax error |
|
|
93
|
-
| `invalid-catalog` | a marketplace catalog — at the repository root, or at a `--marketplace-root` clone — is not a shape its runtime loads — it is found, read, and refused at install time, in the user's terminal | `/universal-plugin:marketplace` |
|
|
99
|
+
| `invalid-catalog` | a marketplace catalog — at the repository root, or at a `--marketplace-root` clone — is not a shape its runtime loads — it is found, read, and refused at install time, in the user's terminal | `/universal-plugin:marketplace` (pnpm install: `pnpm-universal-plugin-marketplace`) |
|
|
94
100
|
| `marketplace-root-missing` | a `--marketplace-root` path does not exist, so it could not be checked at all | clone the marketplace repository, or fix the path |
|
|
95
101
|
|
|
96
102
|
## Catalogs are checked at the repository root
|
|
@@ -99,7 +105,7 @@ The marketplace catalogs sit above the plugin in a monorepo, so the catalog chec
|
|
|
99
105
|
repository root rather than `--root`. It reports only a catalog that would be **refused**: a missing
|
|
100
106
|
one is not a fault, and nothing here has an opinion on which catalogs a repository ought to carry.
|
|
101
107
|
|
|
102
|
-
The detail names the key at fault, so hand it to `/universal-plugin:marketplace` as it stands. An
|
|
108
|
+
The detail names the key at fault, so hand it to `/universal-plugin:marketplace` (pnpm install: `pnpm-universal-plugin-marketplace`) as it stands. An
|
|
103
109
|
entry's fields are derived from the plugin's `plugin.json`, and the catalog's own `name` and `owner`
|
|
104
110
|
are authored in the catalog — which half is at fault decides where the repair goes.
|
|
105
111
|
|
|
@@ -137,13 +143,37 @@ user can run, or ask before running it yourself.
|
|
|
137
143
|
|
|
138
144
|
## Version drift
|
|
139
145
|
|
|
140
|
-
|
|
141
|
-
`packagePath` the CLI reports (`config get --key packagePath`), resolved from the plugin root.
|
|
142
|
-
them
|
|
146
|
+
A version lives in five places. Two are authored: the canonical `plugin.json`, and the `package.json`
|
|
147
|
+
at the `packagePath` the CLI reports (`config get --key packagePath`), resolved from the plugin root.
|
|
148
|
+
The rest are stamped from them by `plugin version`: the vendor manifests, this plugin's entry in each
|
|
149
|
+
repository catalog, the `npx`/`upx <package>@<version>` pins in the skills, and each `mcpServers`
|
|
150
|
+
entry marked `pinToPluginVersion`.
|
|
143
151
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
152
|
+
The script asks `universal-plugin publish check-version` for the comparison and emits one
|
|
153
|
+
`version-drift` per file that disagrees. The reference is the release's number: the `package.json`
|
|
154
|
+
when `packagePath` is declared, else `plugin.json`. Pins are compared only when there is a package to
|
|
155
|
+
pin, and a pin-exempt skill or a pin that is not a version (`<version>`, `latest`) is skipped. A place
|
|
156
|
+
holding `0.0.0-development` is reported as `unstamped`, not as `version-drift`.
|
|
157
|
+
|
|
158
|
+
Files diverge when someone ran `npm version`, or when a release tool (changesets, release-please,
|
|
159
|
+
semantic-release) moved `package.json` and nothing stamped the number on. All of it is
|
|
160
|
+
`/universal-plugin:version` (pnpm install: `pnpm-universal-plugin-version`)'s to fix — never patch one file by hand to match another.
|
|
161
|
+
|
|
162
|
+
### Offer the check to CI
|
|
163
|
+
|
|
164
|
+
`doctor` is advisory and always exits 0. `publish check-version` is the same comparison, read-only,
|
|
165
|
+
and exits 1 on drift, so a repository can fail the release PR instead of publishing a plugin that
|
|
166
|
+
claims the old version. Once the version findings are reported, check whether the repository
|
|
167
|
+
already runs it: search its `package.json` scripts and `.github/workflows/` for `check-version`. If
|
|
168
|
+
it does not, offer to add it — ask first, because both are the user's files:
|
|
169
|
+
|
|
170
|
+
- a `verify` (or `check`) script step: `universal-plugin publish check-version --root <plugin-root>`;
|
|
171
|
+
- or a CI step after install on pull requests, for the release PR a changesets, release-please, or
|
|
172
|
+
semantic-release bot opens.
|
|
173
|
+
|
|
174
|
+
Use the locked `universal-plugin` from the repository's devDependencies when it has one; otherwise
|
|
175
|
+
`npx universal-plugin@0.14.0`, pinned. This check matters most where the release tool picks the
|
|
176
|
+
number, because nothing else runs between that bump and publish.
|
|
147
177
|
|
|
148
178
|
## Unreleased content
|
|
149
179
|
|
|
@@ -161,7 +191,7 @@ Two cases are deliberately silent. A plugin that declares `packagePath` is skipp
|
|
|
161
191
|
release picks the number ([ADR-0010](https://github.com/cyberuni/universal-plugin/blob/main/packages/universal-plugin/.agents/spec/design/decisions/0010-version-policy.md) §2) and content waiting ahead of the last released version is the
|
|
162
192
|
normal state of a branch. A tree with no git history is skipped rather than guessed at.
|
|
163
193
|
|
|
164
|
-
The repair is the bump, and it belongs to `/universal-plugin:version
|
|
194
|
+
The repair is the bump, and it belongs to `/universal-plugin:version` (pnpm install: `pnpm-universal-plugin-version`). Judge first whether the change
|
|
165
195
|
is meant to ship — content that is still being worked on is not a finding to act on.
|
|
166
196
|
|
|
167
197
|
## Rules
|