plugin-updater 1.0.41 → 1.0.42

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/dist/cli.js CHANGED
@@ -130,8 +130,8 @@ async function setupEntry(updater, configDir, url, branch) {
130
130
  }
131
131
  async function main() {
132
132
  const parsed = parseArgs(process.argv.slice(2));
133
- if (!["init", "add", "run"].includes(parsed.command)) {
134
- console.log("usage: plugin-updater <init|add|run> [git-urls...] [--app claude|opencode] [--branch name]");
133
+ if (!["init", "add", "run", "remove"].includes(parsed.command)) {
134
+ console.log("usage: plugin-updater <init|add|remove|run> [git-urls-or-names...] [--app claude|opencode] [--branch name]");
135
135
  process.exit(parsed.command ? 1 : 0);
136
136
  }
137
137
  const app = detectApp(parsed.app);
@@ -159,6 +159,23 @@ async function main() {
159
159
  await setupEntry(updater, configDir, url, parsed.branch);
160
160
  }
161
161
  }
162
+ else if (parsed.command === "remove") {
163
+ if (parsed.urls.length === 0)
164
+ throw new Error("remove requires at least one plugin name");
165
+ for (const arg of parsed.urls) {
166
+ const name = arg.replace(/\.git$/, "").split("/").pop() ?? arg;
167
+ removePluginEntry(configDir, name);
168
+ try {
169
+ fs.rmSync(path.join(configDir, "repos", name), { recursive: true, force: true });
170
+ }
171
+ catch { /* ignore */ }
172
+ try {
173
+ fs.rmSync(path.join(configDir, "plugin", `${name}.js`), { force: true });
174
+ }
175
+ catch { /* ignore */ }
176
+ console.log(`Removed ${name}`);
177
+ }
178
+ }
162
179
  else {
163
180
  const entries = readJson(pluginsJsonPath(configDir)) ?? [];
164
181
  await updater.earlyLaunch(configDir, entries);
package/dist/index.js CHANGED
@@ -5,6 +5,38 @@ import { selfUpdate, updateNpmPlugin } from "./npm.js";
5
5
  import { updatePlugin } from "./git.js";
6
6
  import { deployToExecutionDir } from "./deploy.js";
7
7
  import path from "path";
8
+ import fs from "fs";
9
+ // remove repos/ clones and deployed plugin/ files for plugins no longer in
10
+ // plugins.json, so a removed/renamed plugin stops showing up
11
+ function pruneOrphans(configDir, plugins) {
12
+ const keep = new Set(plugins.map((p) => p.name));
13
+ try {
14
+ for (const dir of fs.readdirSync(path.join(configDir, "repos"))) {
15
+ if (!keep.has(dir)) {
16
+ try {
17
+ fs.rmSync(path.join(configDir, "repos", dir), { recursive: true, force: true });
18
+ writeLog(`Pruned orphaned repos/${dir}`);
19
+ }
20
+ catch { /* ignore */ }
21
+ }
22
+ }
23
+ }
24
+ catch { /* no repos dir */ }
25
+ try {
26
+ for (const file of fs.readdirSync(path.join(configDir, "plugin"))) {
27
+ if (!file.endsWith(".js"))
28
+ continue;
29
+ if (!keep.has(file.slice(0, -3))) {
30
+ try {
31
+ fs.unlinkSync(path.join(configDir, "plugin", file));
32
+ writeLog(`Pruned orphaned plugin/${file}`);
33
+ }
34
+ catch { /* ignore */ }
35
+ }
36
+ }
37
+ }
38
+ catch { /* no plugin dir */ }
39
+ }
8
40
  // re-exported public API (consumers import these from "plugin-updater")
9
41
  export { getNpmPlugins, installNpmPlugin, uninstallNpmPlugin, updateNpmPlugin } from "./npm.js";
10
42
  export { getPlugins, getPluginsPath } from "./config.js";
@@ -70,6 +102,8 @@ export async function earlyLaunch(configDir, plugins) {
70
102
  writeLog(`Failed to process ${plugin.name}: ${e.message}`, true);
71
103
  }
72
104
  }
105
+ if (plugins.length > 0)
106
+ pruneOrphans(configDir, plugins);
73
107
  }
74
108
  export async function activate(opencodeHookInput) {
75
109
  // module load below calls activate() with no argument; opencode passes a
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plugin-updater",
3
- "version": "1.0.41",
3
+ "version": "1.0.42",
4
4
  "description": "Plugin lifecycle manager for OpenCode and Claude Code launchers",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",