plugins 1.2.10-canary.5 → 1.3.1-snapshot.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/README.md +22 -22
- package/dist/index.js +52 -17
- package/package.json +17 -2
package/README.md
CHANGED
|
@@ -42,31 +42,31 @@ npx plugins targets
|
|
|
42
42
|
|
|
43
43
|
## Commands
|
|
44
44
|
|
|
45
|
-
| Command
|
|
46
|
-
|
|
47
|
-
| `plugins add <source>`
|
|
48
|
-
| `plugins discover <source>` | Inspect plugins without installing (dry run)
|
|
49
|
-
| `plugins targets`
|
|
45
|
+
| Command | Description |
|
|
46
|
+
| --------------------------- | ----------------------------------------------------- |
|
|
47
|
+
| `plugins add <source>` | Discover and install plugins from a source |
|
|
48
|
+
| `plugins discover <source>` | Inspect plugins without installing (dry run) |
|
|
49
|
+
| `plugins targets` | List available agent tools and their detection status |
|
|
50
50
|
|
|
51
51
|
If no subcommand is given, `plugins <source>` defaults to `add`.
|
|
52
52
|
|
|
53
53
|
## Flags
|
|
54
54
|
|
|
55
|
-
| Flag
|
|
56
|
-
|
|
57
|
-
| `--target` | `-t`
|
|
58
|
-
| `--scope`
|
|
59
|
-
| `--yes`
|
|
60
|
-
| `--help`
|
|
55
|
+
| Flag | Short | Default | Description |
|
|
56
|
+
| ---------- | ----- | ----------- | ---------------------------------------------------------- |
|
|
57
|
+
| `--target` | `-t` | auto-detect | Install to a specific agent tool (`claude-code`, `cursor`) |
|
|
58
|
+
| `--scope` | `-s` | `user` | Installation scope: `user`, `project`, or `local` |
|
|
59
|
+
| `--yes` | `-y` | `false` | Skip the confirmation prompt |
|
|
60
|
+
| `--help` | `-h` | | Show usage information |
|
|
61
61
|
|
|
62
62
|
## Supported targets
|
|
63
63
|
|
|
64
64
|
The CLI auto-detects which agent tools are installed and installs to all of them.
|
|
65
65
|
|
|
66
|
-
| Target
|
|
67
|
-
|
|
68
|
-
| [Claude Code](https://code.claude.com) | `claude` binary on PATH
|
|
69
|
-
| [Cursor](https://cursor.com)
|
|
66
|
+
| Target | Detection |
|
|
67
|
+
| -------------------------------------- | ------------------------------------ |
|
|
68
|
+
| [Claude Code](https://code.claude.com) | `claude` binary on PATH |
|
|
69
|
+
| [Cursor](https://cursor.com) | `cursor` + `claude` binaries on PATH |
|
|
70
70
|
|
|
71
71
|
## How it works
|
|
72
72
|
|
|
@@ -90,12 +90,12 @@ The CLI translates the vendor-neutral `.plugin/` format into target-specific for
|
|
|
90
90
|
|
|
91
91
|
## Environment variables
|
|
92
92
|
|
|
93
|
-
| Variable
|
|
94
|
-
|
|
95
|
-
| `DISABLE_TELEMETRY` | Disable anonymous install telemetry
|
|
96
|
-
| `DO_NOT_TRACK`
|
|
97
|
-
| `NO_COLOR`
|
|
98
|
-
| `FORCE_COLOR`
|
|
93
|
+
| Variable | Purpose |
|
|
94
|
+
| ------------------- | -------------------------------------------------------------------------------- |
|
|
95
|
+
| `DISABLE_TELEMETRY` | Disable anonymous install telemetry |
|
|
96
|
+
| `DO_NOT_TRACK` | Disable anonymous install telemetry ([standard](https://consoledonottrack.com/)) |
|
|
97
|
+
| `NO_COLOR` | Disable color output |
|
|
98
|
+
| `FORCE_COLOR` | Force color output |
|
|
99
99
|
|
|
100
100
|
## Development
|
|
101
101
|
|
|
@@ -109,4 +109,4 @@ Zero runtime dependencies. Built with [tsup](https://tsup.egoist.dev/) as a sing
|
|
|
109
109
|
|
|
110
110
|
## License
|
|
111
111
|
|
|
112
|
-
[Apache 2.0](
|
|
112
|
+
[Apache 2.0](./LICENSE)
|
package/dist/index.js
CHANGED
|
@@ -488,6 +488,9 @@ function error(title, details) {
|
|
|
488
488
|
}
|
|
489
489
|
}
|
|
490
490
|
}
|
|
491
|
+
function warn(message) {
|
|
492
|
+
barLine(`${c.yellow(S.warning)} ${c.yellow(message)}`);
|
|
493
|
+
}
|
|
491
494
|
async function multiSelect(title, options, maxVisible = 8) {
|
|
492
495
|
if (!process.stdin.isTTY) {
|
|
493
496
|
return options.map((o) => o.value);
|
|
@@ -770,7 +773,10 @@ async function installToPluginCache(plugins, scope, repoPath, source) {
|
|
|
770
773
|
marketplaceSource = { source: "github", repo: githubRepo };
|
|
771
774
|
} else if (isRemoteSource(source)) {
|
|
772
775
|
const gitUrl = normalizeGitUrl(source);
|
|
773
|
-
marketplaceSource = {
|
|
776
|
+
marketplaceSource = {
|
|
777
|
+
source: "git",
|
|
778
|
+
url: gitUrl.endsWith(".git") ? gitUrl : gitUrl + ".git"
|
|
779
|
+
};
|
|
774
780
|
} else {
|
|
775
781
|
marketplaceSource = { source: "directory", path: repoPath };
|
|
776
782
|
}
|
|
@@ -784,7 +790,10 @@ async function installToPluginCache(plugins, scope, repoPath, source) {
|
|
|
784
790
|
}
|
|
785
791
|
barEmpty();
|
|
786
792
|
const installedPath = join3(pluginsDir, "installed_plugins.json");
|
|
787
|
-
let installedData = {
|
|
793
|
+
let installedData = {
|
|
794
|
+
version: 2,
|
|
795
|
+
plugins: {}
|
|
796
|
+
};
|
|
788
797
|
if (existsSync2(installedPath)) {
|
|
789
798
|
try {
|
|
790
799
|
installedData = JSON.parse(await readFile2(installedPath, "utf-8"));
|
|
@@ -793,7 +802,11 @@ async function installToPluginCache(plugins, scope, repoPath, source) {
|
|
|
793
802
|
}
|
|
794
803
|
let gitSha;
|
|
795
804
|
try {
|
|
796
|
-
gitSha = execSync2("git rev-parse HEAD", {
|
|
805
|
+
gitSha = execSync2("git rev-parse HEAD", {
|
|
806
|
+
cwd: repoPath,
|
|
807
|
+
encoding: "utf-8",
|
|
808
|
+
stdio: "pipe"
|
|
809
|
+
}).trim();
|
|
797
810
|
} catch {
|
|
798
811
|
}
|
|
799
812
|
for (const plugin of plugins) {
|
|
@@ -822,20 +835,29 @@ async function installToPluginCache(plugins, scope, repoPath, source) {
|
|
|
822
835
|
barDebug(c.dim("Updated installed_plugins.json"));
|
|
823
836
|
const settingsPath = join3(home, ".claude", "settings.json");
|
|
824
837
|
let settings = {};
|
|
838
|
+
let settingsCorrupted = false;
|
|
825
839
|
if (existsSync2(settingsPath)) {
|
|
826
840
|
try {
|
|
827
841
|
settings = JSON.parse(await readFile2(settingsPath, "utf-8"));
|
|
828
842
|
} catch {
|
|
843
|
+
settingsCorrupted = true;
|
|
829
844
|
}
|
|
830
845
|
}
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
846
|
+
if (settingsCorrupted) {
|
|
847
|
+
warn(
|
|
848
|
+
"Could not parse ~/.claude/settings.json \u2014 skipping enabledPlugins update to avoid overwriting existing settings."
|
|
849
|
+
);
|
|
850
|
+
barLine(c.dim("You may need to manually enable the plugins in Claude Code settings."));
|
|
851
|
+
} else {
|
|
852
|
+
const enabled = settings.enabledPlugins ?? {};
|
|
853
|
+
for (const plugin of plugins) {
|
|
854
|
+
const pluginKey = `${plugin.name}@${marketplaceName}`;
|
|
855
|
+
enabled[pluginKey] = true;
|
|
856
|
+
}
|
|
857
|
+
settings.enabledPlugins = enabled;
|
|
858
|
+
await writeFile(settingsPath, JSON.stringify(settings, null, 2));
|
|
859
|
+
barDebug(c.dim("Updated settings.json enabledPlugins"));
|
|
835
860
|
}
|
|
836
|
-
settings.enabledPlugins = enabled;
|
|
837
|
-
await writeFile(settingsPath, JSON.stringify(settings, null, 2));
|
|
838
|
-
barDebug(c.dim("Updated settings.json enabledPlugins"));
|
|
839
861
|
cachePopulated = true;
|
|
840
862
|
}
|
|
841
863
|
async function installToCursorExtensions(plugins, scope, repoPath, source) {
|
|
@@ -857,7 +879,11 @@ async function installToCursorExtensions(plugins, scope, repoPath, source) {
|
|
|
857
879
|
}
|
|
858
880
|
let gitSha;
|
|
859
881
|
try {
|
|
860
|
-
gitSha = execSync2("git rev-parse HEAD", {
|
|
882
|
+
gitSha = execSync2("git rev-parse HEAD", {
|
|
883
|
+
cwd: repoPath,
|
|
884
|
+
encoding: "utf-8",
|
|
885
|
+
stdio: "pipe"
|
|
886
|
+
}).trim();
|
|
861
887
|
} catch {
|
|
862
888
|
}
|
|
863
889
|
for (const plugin of plugins) {
|
|
@@ -871,9 +897,7 @@ async function installToCursorExtensions(plugins, scope, repoPath, source) {
|
|
|
871
897
|
await cp(plugin.path, destDir, { recursive: true });
|
|
872
898
|
barDebug(c.dim(`Copied to ${destDir}`));
|
|
873
899
|
const identifier = `${marketplaceName}.${plugin.name}`;
|
|
874
|
-
extensions = extensions.filter(
|
|
875
|
-
(e) => e?.identifier?.id !== identifier
|
|
876
|
-
);
|
|
900
|
+
extensions = extensions.filter((e) => e?.identifier?.id !== identifier);
|
|
877
901
|
const uriPath = "/" + destDir.replace(/\\/g, "/");
|
|
878
902
|
extensions.push({
|
|
879
903
|
identifier: { id: identifier },
|
|
@@ -907,7 +931,11 @@ async function installToCodex(plugins, scope, repoPath, source) {
|
|
|
907
931
|
}
|
|
908
932
|
let gitSha;
|
|
909
933
|
try {
|
|
910
|
-
gitSha = execSync2("git rev-parse HEAD", {
|
|
934
|
+
gitSha = execSync2("git rev-parse HEAD", {
|
|
935
|
+
cwd: repoPath,
|
|
936
|
+
encoding: "utf-8",
|
|
937
|
+
stdio: "pipe"
|
|
938
|
+
}).trim();
|
|
911
939
|
} catch {
|
|
912
940
|
}
|
|
913
941
|
const versionKey = gitSha ?? "local";
|
|
@@ -1021,7 +1049,12 @@ async function enrichForCodex(plugin) {
|
|
|
1021
1049
|
};
|
|
1022
1050
|
if (manifest.homepage) iface.websiteURL = manifest.homepage;
|
|
1023
1051
|
else if (manifest.repository) iface.websiteURL = manifest.repository;
|
|
1024
|
-
const assetCandidates = [
|
|
1052
|
+
const assetCandidates = [
|
|
1053
|
+
"assets/app-icon.png",
|
|
1054
|
+
"assets/icon.png",
|
|
1055
|
+
"assets/logo.png",
|
|
1056
|
+
"assets/logo.svg"
|
|
1057
|
+
];
|
|
1025
1058
|
for (const candidate of assetCandidates) {
|
|
1026
1059
|
if (existsSync2(join3(plugin.path, candidate))) {
|
|
1027
1060
|
iface.logo = `./${candidate}`;
|
|
@@ -1121,7 +1154,9 @@ async function translateEnvVars(pluginPath, pluginName, envVar) {
|
|
|
1121
1154
|
if (changed) {
|
|
1122
1155
|
await writeFile(filePath, content);
|
|
1123
1156
|
barDebug(
|
|
1124
|
-
c.dim(
|
|
1157
|
+
c.dim(
|
|
1158
|
+
`${pluginName}: translated plugin root \u2192 \${${envVar}} in ${filePath.split("/").pop()}`
|
|
1159
|
+
)
|
|
1125
1160
|
);
|
|
1126
1161
|
}
|
|
1127
1162
|
}
|
package/package.json
CHANGED
|
@@ -1,20 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plugins",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1-snapshot.0",
|
|
4
4
|
"description": "Install open-plugin format plugins into agent tools",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"packageManager": "pnpm@10.28.1",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=18"
|
|
9
|
+
},
|
|
6
10
|
"bin": {
|
|
7
11
|
"plugins": "dist/index.js"
|
|
8
12
|
},
|
|
9
13
|
"files": [
|
|
10
14
|
"dist"
|
|
11
15
|
],
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/vercel-labs/plugins.git"
|
|
19
|
+
},
|
|
20
|
+
"homepage": "https://github.com/vercel-labs/plugins#readme",
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/vercel-labs/plugins/issues"
|
|
23
|
+
},
|
|
12
24
|
"scripts": {
|
|
13
25
|
"build": "tsup",
|
|
14
26
|
"start": "node dist/index.js",
|
|
15
|
-
"test": "tsx --test test/*.test.ts"
|
|
27
|
+
"test": "tsx --test test/*.test.ts",
|
|
28
|
+
"format:check": "prettier --check \"index.ts\" \"lib/**/*.ts\" \"test/**/*.ts\"",
|
|
29
|
+
"publish:snapshot": "npm version prerelease --preid=snapshot --no-git-tag-version && npm publish --tag snapshot"
|
|
16
30
|
},
|
|
17
31
|
"devDependencies": {
|
|
32
|
+
"prettier": "^3",
|
|
18
33
|
"tsx": "^4.20.6",
|
|
19
34
|
"tsup": "^8",
|
|
20
35
|
"typescript": "^5"
|