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.
Files changed (3) hide show
  1. package/README.md +22 -22
  2. package/dist/index.js +52 -17
  3. 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 | 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 |
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 | 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 |
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 | Detection |
67
- |---|---|
68
- | [Claude Code](https://code.claude.com) | `claude` binary on PATH |
69
- | [Cursor](https://cursor.com) | `cursor` + `claude` binaries on PATH |
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 | 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 |
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](../../LICENSE)
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 = { source: "git", url: gitUrl.endsWith(".git") ? gitUrl : gitUrl + ".git" };
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 = { version: 2, plugins: {} };
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", { cwd: repoPath, encoding: "utf-8", stdio: "pipe" }).trim();
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
- const enabled = settings.enabledPlugins ?? {};
832
- for (const plugin of plugins) {
833
- const pluginKey = `${plugin.name}@${marketplaceName}`;
834
- enabled[pluginKey] = true;
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", { cwd: repoPath, encoding: "utf-8", stdio: "pipe" }).trim();
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", { cwd: repoPath, encoding: "utf-8", stdio: "pipe" }).trim();
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 = ["assets/app-icon.png", "assets/icon.png", "assets/logo.png", "assets/logo.svg"];
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(`${pluginName}: translated plugin root \u2192 \${${envVar}} in ${filePath.split("/").pop()}`)
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.2.10-canary.5",
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"