universal-plugin 0.11.2 → 0.11.3
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 +16 -4
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/readme.md +1 -1
- package/skills/doctor-universal-plugin/SKILL.md +5 -4
- package/skills/doctor-universal-plugin/scripts/doctor.mjs +10 -1
- package/skills/version/README.md +1 -1
- package/skills/version/SKILL.md +7 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "universal-plugin",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.3",
|
|
4
4
|
"description": "Research and design toolkit for building universal AI coding agent plugins that work across Claude Code, Cursor, Codex, and GitHub Copilot CLI.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "unional"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "universal-plugin",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.3",
|
|
4
4
|
"description": "Research and design toolkit for building universal AI coding agent plugins that work across Claude Code, Cursor, Codex, and GitHub Copilot CLI.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "unional"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "universal-plugin",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.3",
|
|
4
4
|
"description": "Research and design toolkit for building universal AI coding agent plugins that work across Claude Code, Cursor, Codex, and GitHub Copilot CLI.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "unional"
|
package/dist/cli.mjs
CHANGED
|
@@ -9557,13 +9557,25 @@ function syncVersion(root, syncFs) {
|
|
|
9557
9557
|
//#region src/publish/cli.ts
|
|
9558
9558
|
function publishCommand() {
|
|
9559
9559
|
const cmd = new Command("publish").description("Prepare plugin for publishing").helpCommand(false);
|
|
9560
|
-
cmd.command("sync-version").description("Sync version from packagePath/package.json (default: the plugin root) into plugin.json").addOption(ROOT_OPTION).action((opts) => {
|
|
9560
|
+
cmd.command("sync-version").description("Sync version from packagePath/package.json (default: the plugin root) into plugin.json").option("--no-build", "Skip re-deriving the vendor manifests").addOption(ROOT_OPTION).action((opts) => {
|
|
9561
9561
|
try {
|
|
9562
|
-
const
|
|
9563
|
-
|
|
9562
|
+
const root = resolveRoot(opts.root);
|
|
9563
|
+
const result = syncVersion(root, realSyncVersionFs);
|
|
9564
|
+
const derived = [];
|
|
9565
|
+
if (opts.build !== false) {
|
|
9566
|
+
const build = buildPlugin(root, {});
|
|
9567
|
+
for (const warning of build.warnings) process.stderr.write(`warn: ${warning}\n`);
|
|
9568
|
+
for (const written of build.written) derived.push(path.relative(root, written).split(path.sep).join("/"));
|
|
9569
|
+
}
|
|
9570
|
+
output({
|
|
9571
|
+
...result,
|
|
9572
|
+
derived
|
|
9573
|
+
}, {
|
|
9564
9574
|
version: result.version,
|
|
9565
|
-
manifest: result.manifestPath
|
|
9575
|
+
manifest: result.manifestPath,
|
|
9576
|
+
derived
|
|
9566
9577
|
});
|
|
9578
|
+
if (opts.build === false) process.stderr.write("→ universal-plugin plugin build\n");
|
|
9567
9579
|
} catch (err) {
|
|
9568
9580
|
process.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
|
|
9569
9581
|
process.exit(1);
|
package/package.json
CHANGED
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.11.
|
|
4
|
+
"version": "0.11.3",
|
|
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
|
@@ -69,7 +69,7 @@ npx universal-plugin sync apply <action-id>
|
|
|
69
69
|
### publish
|
|
70
70
|
|
|
71
71
|
```sh
|
|
72
|
-
npx universal-plugin publish sync-version # copy packagePath/package.json version into plugin.json
|
|
72
|
+
npx universal-plugin publish sync-version # copy packagePath/package.json version into plugin.json, then rebuild
|
|
73
73
|
```
|
|
74
74
|
|
|
75
75
|
This writes the canonical `plugin.json` only. Run `plugin build` afterwards, or the vendor manifests
|
|
@@ -73,8 +73,8 @@ Each `code` below is what the script emits.
|
|
|
73
73
|
| `no-manifest` | no root `plugin.json` — this is not a plugin yet | `/universal-plugin:init-universal-plugin` |
|
|
74
74
|
| `legacy-manifest` | root `plugin.json` with neither `$schema` nor `extensions` — a single-vendor manifest on the canonical path | `/universal-plugin:init-universal-plugin`, adopt route |
|
|
75
75
|
| `vendor-only` | a vendor manifest with no canonical manifest above it | `/universal-plugin:init-universal-plugin`, adopt route |
|
|
76
|
-
| `unbuilt` | a declared vendor whose output path holds no file — that runtime sees no plugin |
|
|
77
|
-
| `stale` | a derived manifest older than `plugin.json` |
|
|
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` |
|
|
78
78
|
| `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
79
|
| `unknown-vendor` | a `vendors` entry no build target matches; reported as `skipped` plus a warning | fix the id in `plugin.json` |
|
|
80
80
|
| `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 |
|
|
@@ -82,7 +82,7 @@ Each `code` below is what the script emits.
|
|
|
82
82
|
| `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
83
|
| `version-drift` | the `packagePath` `package.json` and the canonical manifest carry different versions | `/universal-plugin:version` |
|
|
84
84
|
| `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` |
|
|
85
|
-
| `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 |
|
|
85
|
+
| `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` |
|
|
86
86
|
| `stale-github-plugin` | a leftover `.github/plugin/plugin.json` from an older build — shadowed by root and no longer generated | `/universal-plugin:remove-plugin` |
|
|
87
87
|
| `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` |
|
|
88
88
|
| `no-vendors` | no vendor is declared, so the build writes nothing and no runtime reads the plugin. On a repository still on the pre-0.6 layout 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`, adopt route on the pre-0.6 layout, else update route |
|
|
@@ -126,7 +126,7 @@ the diff:
|
|
|
126
126
|
```bash
|
|
127
127
|
git status --short # must be clean first, or the diff proves nothing
|
|
128
128
|
npx universal-plugin plugin build
|
|
129
|
-
git diff -- .claude-plugin .cursor-plugin .codex-plugin
|
|
129
|
+
git diff -- .claude-plugin .cursor-plugin .codex-plugin com.github.copilot
|
|
130
130
|
```
|
|
131
131
|
|
|
132
132
|
An empty diff means the derived manifests match what the canonical manifest says. Any hunk is drift —
|
|
@@ -180,6 +180,7 @@ is meant to ship — content that is still being worked on is not a finding to a
|
|
|
180
180
|
| Task | Skill |
|
|
181
181
|
|------|-------|
|
|
182
182
|
| Create, adopt, or change what the plugin declares | `init-universal-plugin` |
|
|
183
|
+
| Rebuild the derived manifests (`unbuilt`, `stale`, `copilot-root-components`) | `build-plugin` |
|
|
183
184
|
| Move the plugin's version | `version` |
|
|
184
185
|
| Remove derived manifests, or the plugin itself | `remove-plugin` |
|
|
185
186
|
| Generate the repository's own marketplace catalogs | `marketplace` |
|
|
@@ -30,6 +30,15 @@ const readJson = (file) => {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
const mtime = (file) => (fs.existsSync(file) ? fs.statSync(file).mtimeMs : null)
|
|
33
|
+
// A derived directory (copilot-cli's com.github.copilot/) is as fresh as the newest file in it. The
|
|
34
|
+
// directory's own mtime moves only when an entry is added, removed or renamed, so a rebuild that
|
|
35
|
+
// rewrites its files in place leaves it as old as the first build (issue #144).
|
|
36
|
+
const contentMtime = (abs) => {
|
|
37
|
+
const stat = fs.statSync(abs)
|
|
38
|
+
if (!stat.isDirectory()) return stat.mtimeMs
|
|
39
|
+
const files = fs.readdirSync(abs).map((entry) => contentMtime(path.join(abs, entry)))
|
|
40
|
+
return files.length === 0 ? stat.mtimeMs : Math.max(...files)
|
|
41
|
+
}
|
|
33
42
|
|
|
34
43
|
const VENDOR_MANIFESTS = ['.claude-plugin/plugin.json', '.cursor-plugin/plugin.json', '.codex-plugin/plugin.json']
|
|
35
44
|
|
|
@@ -207,7 +216,7 @@ if (build === null) {
|
|
|
207
216
|
const abs = path.join(root, row.path)
|
|
208
217
|
const exists = fs.existsSync(abs)
|
|
209
218
|
// `canonical` means the vendor reads root plugin.json; no derived file is expected.
|
|
210
|
-
const stale = row.status === 'built' && exists && manifestMtime !== null &&
|
|
219
|
+
const stale = row.status === 'built' && exists && manifestMtime !== null && contentMtime(abs) < manifestMtime
|
|
211
220
|
vendors.push({ vendor: row.vendor, path: row.path, status: row.status, exists, stale })
|
|
212
221
|
|
|
213
222
|
if (row.status === 'built' && !exists) {
|
package/skills/version/README.md
CHANGED
|
@@ -18,7 +18,7 @@ The first question the skill asks is whether the repository uses changesets.
|
|
|
18
18
|
|
|
19
19
|
- **With changesets** — the number is decided by the release, not by this skill. Add a changeset, let
|
|
20
20
|
the release run, and `publish sync-version` carries the released number into the canonical
|
|
21
|
-
manifest.
|
|
21
|
+
manifest and re-derives the vendor manifests. With `--no-build`, `plugin build` is the next step.
|
|
22
22
|
- **Without** — `plugin version <bump>` is the whole step. `scripts/version.mjs` runs it from the CLI
|
|
23
23
|
shipped beside the skill, so nothing is downloaded.
|
|
24
24
|
|
package/skills/version/SKILL.md
CHANGED
|
@@ -22,12 +22,17 @@ test -d .changeset && echo "changesets"
|
|
|
22
22
|
|
|
23
23
|
**If it does**, the version number is decided by changesets, not by you. Add a changeset and let the
|
|
24
24
|
release run — the repo's `version` script should already call `publish sync-version`, which carries
|
|
25
|
-
the released number from `package.json` into the canonical manifest
|
|
25
|
+
the released number from `package.json` into the canonical manifest and re-derives the vendor
|
|
26
|
+
manifests, the same way `plugin version` does:
|
|
26
27
|
|
|
27
28
|
```bash
|
|
28
29
|
npx universal-plugin publish sync-version
|
|
29
30
|
```
|
|
30
31
|
|
|
32
|
+
If the script passes `--no-build`, it must run `plugin build` next (`/universal-plugin:build-plugin`);
|
|
33
|
+
otherwise the vendor manifests and `com.github.copilot/` keep the old version, and a consumer's
|
|
34
|
+
plugin cache never re-extracts.
|
|
35
|
+
|
|
31
36
|
Do **not** run `plugin version` in a changesets repo — it would decide a number changesets is about
|
|
32
37
|
to decide again.
|
|
33
38
|
|
|
@@ -109,6 +114,7 @@ Every guard resolves before the first write, so a failed run leaves the tree unt
|
|
|
109
114
|
| Task | Skill |
|
|
110
115
|
|------|-------|
|
|
111
116
|
| Create, adopt, or change what the plugin declares | `init-universal-plugin` |
|
|
117
|
+
| Re-derive the vendor manifests by hand | `build-plugin` |
|
|
112
118
|
| Check whether the two authored versions agree | `doctor` |
|
|
113
119
|
| Add a changeset for the change being released | `add-changeset` |
|
|
114
120
|
| Refresh the repository's own marketplace catalogs after a bump | `marketplace` |
|