universal-plugin 0.12.2 → 0.13.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 +5139 -4032
- 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/SKILL.md +17 -8
- package/skills/build-plugin/scripts/build.mjs +51 -10
- package/skills/doctor-universal-plugin/SKILL.md +40 -10
- 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 +8 -5
- 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/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/upgrade-plugin/SKILL.md +2 -0
- package/skills/version/README.md +24 -18
- package/skills/version/SKILL.md +79 -46
- package/skills/version/scripts/version.mjs +51 -10
package/skills/version/README.md
CHANGED
|
@@ -1,36 +1,42 @@
|
|
|
1
1
|
# version skill
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Stamp the version a plugin releases under into every file that carries one.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Derive versus stamp
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
`plugin build` derives the vendor manifests from `plugin.json` and never decides a version.
|
|
8
|
+
`plugin version` stamps: one call writes the number into the canonical `plugin.json`, the
|
|
9
|
+
`packagePath` `package.json`, every `npx`/`upx <pkg>@<version>` pin in the skills, `.plugin/pins.json`,
|
|
10
|
+
and each `mcpServers` entry marked `pinToPluginVersion`, then re-derives through `plugin build`.
|
|
10
11
|
|
|
11
|
-
That is why nothing here is hand-edited
|
|
12
|
-
|
|
13
|
-
a matching bump is invisible to them.
|
|
12
|
+
That is why nothing here is hand-edited. A consumer's plugin cache is keyed by version, so a content
|
|
13
|
+
change without a matching bump is invisible to them.
|
|
14
14
|
|
|
15
|
-
##
|
|
15
|
+
## Three sources for the number
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
| Source | Call | Used by |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| Author bump | `plugin version minor` | Plain repositories |
|
|
20
|
+
| Explicit number | `plugin version 1.4.0` | semantic-release (`@semantic-release/exec` `prepareCmd`) |
|
|
21
|
+
| The package's `package.json` | `plugin version --from-package` | changesets, release-please |
|
|
18
22
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
manifest and re-derives the vendor manifests. With `--no-build`, `plugin build` is the next step.
|
|
22
|
-
- **Without** — `plugin version <bump>` is the whole step. `scripts/version.mjs` runs it from the CLI
|
|
23
|
-
shipped beside the skill, so nothing is downloaded.
|
|
23
|
+
With `packagePath` declared, a release type is refused: bump the package with the release tool, then
|
|
24
|
+
run `--from-package`. The skill checks for `.changeset/` and `packagePath` before it picks a call.
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
semantic-release stamps files that exist only in the npm package unless `@semantic-release/git`
|
|
27
|
+
commits them back. Git-sourced installs read `plugin.json` from the repository, so they need that
|
|
28
|
+
commit-back.
|
|
29
|
+
|
|
30
|
+
`plugin bundle` and `publish sync-version` are deprecated aliases and are removed in the next minor
|
|
31
|
+
release.
|
|
27
32
|
|
|
28
33
|
## The part that is not automatable
|
|
29
34
|
|
|
30
35
|
Which release type to use is a promise to consumers about what broke. The skill offers the semver
|
|
31
|
-
reading
|
|
36
|
+
reading (breaking → major, new behavior → minor, fix only → patch, adjusted for `0.x`) and asks
|
|
32
37
|
rather than guessing.
|
|
33
38
|
|
|
34
39
|
## References
|
|
35
40
|
|
|
41
|
+
- [ADR-0010](https://github.com/cyberuni/universal-plugin/blob/main/packages/universal-plugin/.agents/spec/design/decisions/0010-version-policy.md)
|
|
36
42
|
- [`plugin version` spec](https://github.com/cyberuni/universal-plugin/blob/main/packages/universal-plugin/.agents/spec/plugin/version/README.md)
|
package/skills/version/SKILL.md
CHANGED
|
@@ -1,54 +1,82 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: version
|
|
3
|
-
description: Use this skill to move a universal agent plugin's version — bump it, set an explicit one, cut a release number, or reconcile a version that drifted between the canonical plugin.json and its npm package.json. Handles
|
|
3
|
+
description: Use this skill to move a universal agent plugin's version — bump it, set an explicit one, cut a release number, or reconcile a version that drifted between the canonical plugin.json and its npm package.json. Handles every release model: a plain repository, where the author picks the number, and a release tool (changesets, release-please, semantic-release) that decides it and hands it to plugin version to stamp everywhere. Trigger on "bump the plugin version", "release a new version of this plugin", "set the plugin version to 1.0.0", "cut a patch release", or "the manifest and package.json versions disagree".
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Move a plugin's version
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Stamp the version a plugin releases under into every file that carries one.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
`plugin
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
without a matching bump is invisible to them.
|
|
10
|
+
The seam is **derive versus stamp**. `plugin build` derives the vendor manifests from `plugin.json`
|
|
11
|
+
and never decides a version. `plugin version` is the one command that decides where a number goes: a
|
|
12
|
+
single call writes it into every place, then re-derives through `plugin build`. So never hand-edit a
|
|
13
|
+
version. Editing one file leaves the rest stale, and a consumer's plugin cache is keyed by version, so
|
|
14
|
+
a content change without a matching bump is invisible to them.
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
One call writes:
|
|
17
|
+
|
|
18
|
+
- the canonical `plugin.json`, and the `packagePath` `package.json` when you pass a release type or an
|
|
19
|
+
explicit number;
|
|
20
|
+
- every `npx`/`upx <pkg>@<version>` pin in the text files under the skills directory (SKILL.md, other
|
|
21
|
+
Markdown, json/yaml, and `.js`/`.mjs`/`.cjs`/`.ts`/`.mts`/`.cts`/`.sh`/`.py` scripts). The plugin's
|
|
22
|
+
own package moves to the new version, other pnpm-workspace CLIs to their workspace versions, and
|
|
23
|
+
external packages are left alone. A skill with `metadata.pin-exempt: true` is skipped;
|
|
24
|
+
- `.plugin/pins.json`;
|
|
25
|
+
- the version each compiled skill script (`scripts` in the extension) embeds in its header — only the
|
|
26
|
+
header moves;
|
|
27
|
+
- each authored `mcpServers` entry marked `pinToPluginVersion: true`, inline or in the mcp file. The
|
|
28
|
+
marker stays.
|
|
29
|
+
|
|
30
|
+
## Step 1 — Pick the source of the number
|
|
31
|
+
|
|
32
|
+
Ask who decides the number. There are three sources, and the release model picks one:
|
|
33
|
+
|
|
34
|
+
| Source | Call | Used by |
|
|
35
|
+
|---|---|---|
|
|
36
|
+
| Author bump | `plugin version minor` | Plain repositories, with no `packagePath` |
|
|
37
|
+
| Explicit number | `plugin version 1.4.0` | semantic-release |
|
|
38
|
+
| The package's `package.json` | `plugin version --from-package` | changesets, release-please |
|
|
18
39
|
|
|
19
40
|
```bash
|
|
20
41
|
test -d .changeset && echo "changesets"
|
|
42
|
+
cat .agents/universal-plugin.json # is packagePath declared?
|
|
21
43
|
```
|
|
22
44
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
45
|
+
With `packagePath` declared, a release type (`patch`, `minor`, `major`, `pre*`) is **refused**: the
|
|
46
|
+
package owns the number. Bump the package with the release tool, then run `--from-package`. An
|
|
47
|
+
explicit number and `--from-package` stay allowed. `--from-package` reads `<packagePath>/package.json`,
|
|
48
|
+
or the plugin root's `package.json` when no `packagePath` is declared, and refuses `0.0.0-development`.
|
|
27
49
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
50
|
+
Wire a release tool once; after that the release runs the stamp for you:
|
|
51
|
+
|
|
52
|
+
- **changesets.** Root `version` script: `changeset version && universal-plugin plugin version --from-package --root <plugin>`.
|
|
53
|
+
`init-universal-plugin --npm` writes it.
|
|
54
|
+
- **release-please.** Run `universal-plugin plugin version --from-package` after the release PR
|
|
55
|
+
bumps the package.
|
|
56
|
+
- **semantic-release.** Add `@semantic-release/exec` with
|
|
57
|
+
`prepareCmd: "universal-plugin plugin version ${nextRelease.version}"`.
|
|
31
58
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
plugin cache never re-extracts.
|
|
59
|
+
In a changesets repository, add a changeset and let the release run. Do not run `plugin version minor`
|
|
60
|
+
there: it would decide a number changesets is about to decide again.
|
|
35
61
|
|
|
36
|
-
|
|
37
|
-
to decide again.
|
|
62
|
+
### semantic-release must commit the stamp back
|
|
38
63
|
|
|
39
|
-
|
|
64
|
+
The stamped files exist only in the npm package unless `@semantic-release/git` commits them back.
|
|
65
|
+
Git-sourced installs (Copilot CLI, GitHub-hosted marketplaces) read `plugin.json` from the repository,
|
|
66
|
+
so for those channels the commit-back is required. Without it they are unsupported. Set `assets` to
|
|
67
|
+
`plugin.json`, the vendor manifests, `skills/**`, `.plugin/pins.json`, and the mcp file.
|
|
40
68
|
|
|
41
|
-
## Step
|
|
69
|
+
## Step 2 — Run it
|
|
42
70
|
|
|
43
71
|
```bash
|
|
44
|
-
node scripts/version.mjs <bump>
|
|
72
|
+
node scripts/version.mjs <bump-or-number>
|
|
73
|
+
node scripts/version.mjs --from-package
|
|
45
74
|
```
|
|
46
75
|
|
|
47
|
-
Resolve that path against this skill's own directory; it runs the
|
|
48
|
-
|
|
49
|
-
never prompts, so it is safe to run unattended once the
|
|
50
|
-
|
|
51
|
-
`<bump>` is either a semver release type or an explicit version:
|
|
76
|
+
Resolve that path against this skill's own directory; it runs the project's installed CLI
|
|
77
|
+
(`pnpm exec universal-plugin`), else `npx universal-plugin@0.13.0` pinned to this skill's version.
|
|
78
|
+
`universal-plugin plugin version` on the `PATH` is the fallback. The command never prompts, so it is safe to run unattended once the
|
|
79
|
+
source is decided.
|
|
52
80
|
|
|
53
81
|
| `<bump>` | From `1.2.3` you get |
|
|
54
82
|
|---|---|
|
|
@@ -58,29 +86,29 @@ never prompts, so it is safe to run unattended once the release type is decided.
|
|
|
58
86
|
| `prerelease --preid beta` | `1.2.4-beta.0` |
|
|
59
87
|
| `2.0.0-rc.1` (explicit) | `2.0.0-rc.1` |
|
|
60
88
|
|
|
61
|
-
Useful flags:
|
|
62
|
-
|
|
63
89
|
| Flag | Effect |
|
|
64
90
|
|---|---|
|
|
91
|
+
| `--from-package` | Take the version the package's `package.json` already holds |
|
|
65
92
|
| `--preid <id>` | Prerelease identifier for the `pre*` release types |
|
|
66
|
-
| `--dry-run` | Print the plan, write nothing
|
|
93
|
+
| `--dry-run` | Print the plan, write nothing. Run this first when unsure |
|
|
67
94
|
| `--force` | Allow a target that does not advance on the current version |
|
|
68
|
-
| `--no-build` | Skip re-deriving the vendor manifests (
|
|
69
|
-
| `--format json` | Machine-readable result
|
|
95
|
+
| `--no-build` | Skip re-deriving the vendor manifests (run `plugin build` yourself) |
|
|
96
|
+
| `--format json` | Machine-readable result |
|
|
97
|
+
| `--root <path>` | Plugin root directory |
|
|
70
98
|
|
|
71
|
-
**Which release type?**
|
|
72
|
-
version is a promise to consumers about what broke. If the user has not said, ask, and
|
|
73
|
-
semver reading of the change: breaking → `major`, new behavior → `minor`, fix only →
|
|
74
|
-
`0.x` plugin, breaking → `minor` and everything else → `patch`).
|
|
99
|
+
**Which release type?** In a plain repository that is the user's call, not the command's and not yours
|
|
100
|
+
to guess. A version is a promise to consumers about what broke. If the user has not said, ask, and
|
|
101
|
+
offer the semver reading of the change: breaking → `major`, new behavior → `minor`, fix only →
|
|
102
|
+
`patch` (on a `0.x` plugin, breaking → `minor` and everything else → `patch`).
|
|
75
103
|
|
|
76
|
-
## Step
|
|
104
|
+
## Step 3 — Confirm what moved
|
|
77
105
|
|
|
78
106
|
The command reports every file it wrote and every manifest it re-derived. Expect the canonical
|
|
79
|
-
manifest, the `packagePath` `package.json`
|
|
80
|
-
harness:
|
|
107
|
+
manifest, the `packagePath` `package.json` for a release type or explicit number, the pinned skill
|
|
108
|
+
files, `.plugin/pins.json`, and one derived manifest per declared harness:
|
|
81
109
|
|
|
82
110
|
```bash
|
|
83
|
-
node scripts/version.mjs
|
|
111
|
+
node scripts/version.mjs --from-package --format json
|
|
84
112
|
```
|
|
85
113
|
|
|
86
114
|
Default stdout is TOON, which is the machine contract this CLI documents; `--format json` is there
|
|
@@ -99,15 +127,19 @@ Every guard resolves before the first write, so a failed run leaves the tree unt
|
|
|
99
127
|
| 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 |
|
|
100
128
|
| 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 |
|
|
101
129
|
| 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 |
|
|
130
|
+
| a release type under `packagePath` | the package owns the number | bump the package with the release tool, then `plugin version --from-package` |
|
|
131
|
+
| `0.0.0-development` from `--from-package` | semantic-release's placeholder, not a release | pass the explicit number instead |
|
|
102
132
|
| a missing `package.json` at `packagePath` | `.agents/universal-plugin.json` names a package directory that does not exist | fix `packagePath`, or create the package |
|
|
103
133
|
|
|
104
134
|
## Do not
|
|
105
135
|
|
|
106
|
-
- **Hand-edit a `version` field.**
|
|
136
|
+
- **Hand-edit a `version` field.** The other places fall out of sync.
|
|
107
137
|
- **Write a derived manifest.** `.claude-plugin/plugin.json` and its siblings belong to
|
|
108
138
|
`plugin build`; the bump already re-derived them.
|
|
109
|
-
- **Run `npm version`.** It knows only `package.json` and leaves the canonical manifest
|
|
110
|
-
|
|
139
|
+
- **Run `npm version`.** It knows only `package.json` and leaves the canonical manifest and the
|
|
140
|
+
skill pins stale.
|
|
141
|
+
- **Use the deprecated commands.** `plugin bundle` and `publish sync-version` print a warning and are
|
|
142
|
+
removed in the next minor release. `sync-version` now runs `plugin version --from-package`.
|
|
111
143
|
|
|
112
144
|
## Related skills
|
|
113
145
|
|
|
@@ -115,11 +147,12 @@ Every guard resolves before the first write, so a failed run leaves the tree unt
|
|
|
115
147
|
|------|-------|
|
|
116
148
|
| Create, adopt, or change what the plugin declares | `init-universal-plugin` |
|
|
117
149
|
| Re-derive the vendor manifests by hand | `build-plugin` |
|
|
118
|
-
| Check whether
|
|
150
|
+
| Check whether every place agrees (`unstamped`, `version-drift`) | `doctor-universal-plugin` |
|
|
119
151
|
| Add a changeset for the change being released | `add-changeset` |
|
|
120
152
|
| Refresh the repository's own marketplace catalogs after a bump | `marketplace` |
|
|
121
153
|
| List the released plugin in the shared marketplace | `publish-plugin` |
|
|
122
154
|
|
|
123
155
|
## References
|
|
124
156
|
|
|
157
|
+
- [ADR-0010](https://github.com/cyberuni/universal-plugin/blob/main/packages/universal-plugin/.agents/spec/design/decisions/0010-version-policy.md), the derive/stamp seam
|
|
125
158
|
- Spec: [`plugin/version/`](https://github.com/cyberuni/universal-plugin/blob/main/packages/universal-plugin/.agents/spec/plugin/version/README.md)
|
|
@@ -1,11 +1,52 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
//
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
// Compiled by `universal-plugin plugin build` from src/skill-scripts/run-cli.ts. Edit the source, not this file.
|
|
3
|
+
globalThis.__SKILL_SCRIPT__ = {"package":"universal-plugin","bin":"universal-plugin","version":"0.13.0","entry":"skills/version/scripts/version.mjs","commands":{"marketplace add":"skills/marketplace/scripts/add.mjs","marketplace init":"skills/marketplace/scripts/marketplace.mjs","marketplace validate":"skills/marketplace/scripts/validate.mjs","plugin build":"skills/build-plugin/scripts/build.mjs","plugin init":"skills/init-universal-plugin/scripts/init.mjs","plugin version":"skills/version/scripts/version.mjs"}};
|
|
4
|
+
import { spawnSync } from "node:child_process";
|
|
5
|
+
//#region src/compile/scripts.ts
|
|
6
|
+
/** The global the header assigns the script data to. Framework-neutral: a script's own code, or the
|
|
7
|
+
* library it inlines, reads it; universal-plugin depends on neither. */
|
|
8
|
+
const SCRIPT_GLOBAL = "__SKILL_SCRIPT__";
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/skill-scripts/cli-runner.ts
|
|
11
|
+
/** The data `plugin build` embedded in this compiled script. */
|
|
12
|
+
function skillScript() {
|
|
13
|
+
const data = globalThis[SCRIPT_GLOBAL];
|
|
14
|
+
if (data === void 0) throw new Error("this script runs only as compiled by `plugin build`");
|
|
15
|
+
return data;
|
|
16
|
+
}
|
|
17
|
+
/** Runs the universal-plugin CLI. A skill may be copied away from its package, so it never reaches
|
|
18
|
+
* for a CLI beside it: the project's installed CLI first, then the one pinned to this script's
|
|
19
|
+
* version, which `plugin version` stamps. */
|
|
20
|
+
function runCli(args, options = {}) {
|
|
21
|
+
const { bin, package: pkg, version } = skillScript();
|
|
22
|
+
const name = bin ?? "universal-plugin";
|
|
23
|
+
if (spawnSync("pnpm", [
|
|
24
|
+
"exec",
|
|
25
|
+
name,
|
|
26
|
+
"--version"
|
|
27
|
+
], { encoding: "utf8" }).status === 0) return spawnSync("pnpm", [
|
|
28
|
+
"exec",
|
|
29
|
+
name,
|
|
30
|
+
...args
|
|
31
|
+
], {
|
|
32
|
+
encoding: "utf8",
|
|
33
|
+
...options
|
|
34
|
+
});
|
|
35
|
+
const pinned = `${pkg ?? "universal-plugin"}@${version ?? "latest"}`;
|
|
36
|
+
return spawnSync("npx", [pinned, ...args], {
|
|
37
|
+
encoding: "utf8",
|
|
38
|
+
...options
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/skill-scripts/run-cli.ts
|
|
43
|
+
const script = skillScript();
|
|
44
|
+
const command = Object.entries(script.commands).find(([, entry]) => entry === script.entry)?.[0];
|
|
45
|
+
if (command === void 0) {
|
|
46
|
+
process.stderr.write(`${script.entry} declares no command in the scripts map\n`);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
const result = runCli([...command.split(" "), ...process.argv.slice(2)], { stdio: "inherit" });
|
|
50
|
+
process.exit(result.status ?? 1);
|
|
51
|
+
//#endregion
|
|
52
|
+
export {};
|