claudeup 3.6.4 → 3.6.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudeup",
3
- "version": "3.6.4",
3
+ "version": "3.6.6",
4
4
  "description": "TUI tool for managing Claude Code plugins, MCPs, and configuration",
5
5
  "type": "module",
6
6
  "main": "src/main.tsx",
@@ -11,6 +11,8 @@
11
11
  import { execFile } from "node:child_process";
12
12
  import { promisify } from "node:util";
13
13
  import { which } from "../utils/command-utils.js";
14
+ import { removeGlobalInstalledPluginVersion, removeLocalInstalledPluginVersion, } from "./claude-settings.js";
15
+ import { removeInstalledPluginVersion, } from "./plugin-manager.js";
14
16
  const execFileAsync = promisify(execFile);
15
17
  /**
16
18
  * Get the path to the claude CLI binary
@@ -54,11 +56,27 @@ export async function installPlugin(pluginId, scope = "user") {
54
56
  await execClaude(["plugin", "install", pluginId, "--scope", scope]);
55
57
  }
56
58
  /**
57
- * Uninstall a plugin using claude CLI
58
- * Handles disabling + version removal in one shot
59
+ * Uninstall a plugin using claude CLI.
60
+ * Falls back to direct settings removal if CLI uninstall fails
61
+ * (e.g., for plugins installed via old JSON method).
62
+ * @param projectPath - Required for project/local scope fallback
59
63
  */
60
- export async function uninstallPlugin(pluginId, scope = "user") {
61
- await execClaude(["plugin", "uninstall", pluginId, "--scope", scope]);
64
+ export async function uninstallPlugin(pluginId, scope = "user", projectPath) {
65
+ try {
66
+ await execClaude(["plugin", "uninstall", pluginId, "--scope", scope]);
67
+ }
68
+ catch {
69
+ // Fallback: directly remove from settings JSON
70
+ if (scope === "user") {
71
+ await removeGlobalInstalledPluginVersion(pluginId);
72
+ }
73
+ else if (scope === "local" && projectPath) {
74
+ await removeLocalInstalledPluginVersion(pluginId, projectPath);
75
+ }
76
+ else if (projectPath) {
77
+ await removeInstalledPluginVersion(pluginId, projectPath);
78
+ }
79
+ }
62
80
  }
63
81
  /**
64
82
  * Enable a previously disabled plugin
@@ -12,6 +12,13 @@
12
12
  import { execFile } from "node:child_process";
13
13
  import { promisify } from "node:util";
14
14
  import { which } from "../utils/command-utils.js";
15
+ import {
16
+ removeGlobalInstalledPluginVersion,
17
+ removeLocalInstalledPluginVersion,
18
+ } from "./claude-settings.js";
19
+ import {
20
+ removeInstalledPluginVersion,
21
+ } from "./plugin-manager.js";
15
22
 
16
23
  const execFileAsync = promisify(execFile);
17
24
 
@@ -75,14 +82,28 @@ export async function installPlugin(
75
82
  }
76
83
 
77
84
  /**
78
- * Uninstall a plugin using claude CLI
79
- * Handles disabling + version removal in one shot
85
+ * Uninstall a plugin using claude CLI.
86
+ * Falls back to direct settings removal if CLI uninstall fails
87
+ * (e.g., for plugins installed via old JSON method).
88
+ * @param projectPath - Required for project/local scope fallback
80
89
  */
81
90
  export async function uninstallPlugin(
82
91
  pluginId: string,
83
92
  scope: PluginScope = "user",
93
+ projectPath?: string,
84
94
  ): Promise<void> {
85
- await execClaude(["plugin", "uninstall", pluginId, "--scope", scope]);
95
+ try {
96
+ await execClaude(["plugin", "uninstall", pluginId, "--scope", scope]);
97
+ } catch {
98
+ // Fallback: directly remove from settings JSON
99
+ if (scope === "user") {
100
+ await removeGlobalInstalledPluginVersion(pluginId);
101
+ } else if (scope === "local" && projectPath) {
102
+ await removeLocalInstalledPluginVersion(pluginId, projectPath);
103
+ } else if (projectPath) {
104
+ await removeInstalledPluginVersion(pluginId, projectPath);
105
+ }
106
+ }
86
107
  }
87
108
 
88
109
  /**
@@ -457,7 +457,7 @@ export function PluginsScreen() {
457
457
  try {
458
458
  const scope = scopeValue;
459
459
  if (action === "uninstall") {
460
- await cliUninstallPlugin(plugin.id, scope);
460
+ await cliUninstallPlugin(plugin.id, scope, state.projectPath);
461
461
  }
462
462
  else if (action === "update") {
463
463
  await cliUpdatePlugin(plugin.id, scope);
@@ -556,7 +556,7 @@ export function PluginsScreen() {
556
556
  modal.loading(`${actionLabel}...`);
557
557
  try {
558
558
  if (action === "uninstall") {
559
- await cliUninstallPlugin(plugin.id, scope);
559
+ await cliUninstallPlugin(plugin.id, scope, state.projectPath);
560
560
  }
561
561
  else if (action === "update") {
562
562
  await cliUpdatePlugin(plugin.id, scope);
@@ -611,7 +611,7 @@ export function PluginsScreen() {
611
611
  return; // Cancelled
612
612
  modal.loading(`Uninstalling ${plugin.name}...`);
613
613
  try {
614
- await cliUninstallPlugin(plugin.id, scopeValue);
614
+ await cliUninstallPlugin(plugin.id, scopeValue, state.projectPath);
615
615
  modal.hideModal();
616
616
  fetchData();
617
617
  }
@@ -595,7 +595,7 @@ export function PluginsScreen() {
595
595
  try {
596
596
  const scope = scopeValue as PluginScope;
597
597
  if (action === "uninstall") {
598
- await cliUninstallPlugin(plugin.id, scope);
598
+ await cliUninstallPlugin(plugin.id, scope, state.projectPath);
599
599
  } else if (action === "update") {
600
600
  await cliUpdatePlugin(plugin.id, scope);
601
601
  } else {
@@ -702,7 +702,7 @@ export function PluginsScreen() {
702
702
 
703
703
  try {
704
704
  if (action === "uninstall") {
705
- await cliUninstallPlugin(plugin.id, scope);
705
+ await cliUninstallPlugin(plugin.id, scope, state.projectPath);
706
706
  } else if (action === "update") {
707
707
  await cliUpdatePlugin(plugin.id, scope);
708
708
  } else {
@@ -769,7 +769,7 @@ export function PluginsScreen() {
769
769
  modal.loading(`Uninstalling ${plugin.name}...`);
770
770
 
771
771
  try {
772
- await cliUninstallPlugin(plugin.id, scopeValue as PluginScope);
772
+ await cliUninstallPlugin(plugin.id, scopeValue as PluginScope, state.projectPath);
773
773
  modal.hideModal();
774
774
  fetchData();
775
775
  } catch (error) {