claudeup 4.10.0 → 4.10.1
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 +1 -1
- package/src/services/claude-cli.js +8 -4
- package/src/services/claude-cli.ts +12 -4
- package/src/ui/App.js +32 -2
- package/src/ui/App.tsx +50 -1
package/package.json
CHANGED
|
@@ -53,9 +53,8 @@ async function execClaude(args, timeoutMs = 30000) {
|
|
|
53
53
|
* Handles enabling + version tracking + cache copy in one shot.
|
|
54
54
|
*
|
|
55
55
|
* If the install fails because the plugin is "not found in marketplace",
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* the local marketplace clone.
|
|
56
|
+
* recovers the marketplace registry (fixes stale "directory" sources),
|
|
57
|
+
* triggers a marketplace update, and retries once.
|
|
59
58
|
*/
|
|
60
59
|
export async function installPlugin(pluginId, scope = "user") {
|
|
61
60
|
try {
|
|
@@ -64,10 +63,13 @@ export async function installPlugin(pluginId, scope = "user") {
|
|
|
64
63
|
catch (error) {
|
|
65
64
|
const msg = error instanceof Error ? error.message : String(error);
|
|
66
65
|
if (msg.includes("not found in marketplace")) {
|
|
67
|
-
// Local marketplace clone is stale — update and retry
|
|
68
66
|
const parts = pluginId.split("@");
|
|
69
67
|
const marketplace = parts[1];
|
|
70
68
|
if (marketplace) {
|
|
69
|
+
// Fix known_marketplaces.json first (stale "directory" → "github"),
|
|
70
|
+
// then update, then retry
|
|
71
|
+
const { recoverMarketplaceSettings } = await import("./claude-settings.js");
|
|
72
|
+
await recoverMarketplaceSettings();
|
|
71
73
|
await updateMarketplace(marketplace);
|
|
72
74
|
await execClaude([
|
|
73
75
|
"plugin",
|
|
@@ -136,6 +138,8 @@ export async function updatePlugin(pluginId, scope = "user") {
|
|
|
136
138
|
const parts = pluginId.split("@");
|
|
137
139
|
const marketplace = parts[1];
|
|
138
140
|
if (marketplace) {
|
|
141
|
+
const { recoverMarketplaceSettings } = await import("./claude-settings.js");
|
|
142
|
+
await recoverMarketplaceSettings();
|
|
139
143
|
await updateMarketplace(marketplace);
|
|
140
144
|
await execClaude(["plugin", "install", pluginId, "--scope", scope], 60000);
|
|
141
145
|
return;
|
|
@@ -70,9 +70,8 @@ async function execClaude(args: string[], timeoutMs = 30000): Promise<string> {
|
|
|
70
70
|
* Handles enabling + version tracking + cache copy in one shot.
|
|
71
71
|
*
|
|
72
72
|
* If the install fails because the plugin is "not found in marketplace",
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* the local marketplace clone.
|
|
73
|
+
* recovers the marketplace registry (fixes stale "directory" sources),
|
|
74
|
+
* triggers a marketplace update, and retries once.
|
|
76
75
|
*/
|
|
77
76
|
export async function installPlugin(
|
|
78
77
|
pluginId: string,
|
|
@@ -84,10 +83,15 @@ export async function installPlugin(
|
|
|
84
83
|
const msg =
|
|
85
84
|
error instanceof Error ? error.message : String(error);
|
|
86
85
|
if (msg.includes("not found in marketplace")) {
|
|
87
|
-
// Local marketplace clone is stale — update and retry
|
|
88
86
|
const parts = pluginId.split("@");
|
|
89
87
|
const marketplace = parts[1];
|
|
90
88
|
if (marketplace) {
|
|
89
|
+
// Fix known_marketplaces.json first (stale "directory" → "github"),
|
|
90
|
+
// then update, then retry
|
|
91
|
+
const { recoverMarketplaceSettings } = await import(
|
|
92
|
+
"./claude-settings.js"
|
|
93
|
+
);
|
|
94
|
+
await recoverMarketplaceSettings();
|
|
91
95
|
await updateMarketplace(marketplace);
|
|
92
96
|
await execClaude([
|
|
93
97
|
"plugin",
|
|
@@ -173,6 +177,10 @@ export async function updatePlugin(
|
|
|
173
177
|
const parts = pluginId.split("@");
|
|
174
178
|
const marketplace = parts[1];
|
|
175
179
|
if (marketplace) {
|
|
180
|
+
const { recoverMarketplaceSettings } = await import(
|
|
181
|
+
"./claude-settings.js"
|
|
182
|
+
);
|
|
183
|
+
await recoverMarketplaceSettings();
|
|
176
184
|
await updateMarketplace(marketplace);
|
|
177
185
|
await execClaude(
|
|
178
186
|
["plugin", "install", pluginId, "--scope", scope],
|
package/src/ui/App.js
CHANGED
|
@@ -7,7 +7,7 @@ import { DimensionsProvider, useDimensions, } from "./state/DimensionsContext.js
|
|
|
7
7
|
import { ModalContainer } from "./components/modals/index.js";
|
|
8
8
|
import { PluginsScreen, McpScreen, McpRegistryScreen, SettingsScreen, CliToolsScreen, ModelSelectorScreen, ProfilesScreen, SkillsScreen, } from "./screens/index.js";
|
|
9
9
|
import { repairAllMarketplaces } from "../services/local-marketplace.js";
|
|
10
|
-
import { migrateMarketplaceRename } from "../services/claude-settings.js";
|
|
10
|
+
import { migrateMarketplaceRename, recoverMarketplaceSettings, } from "../services/claude-settings.js";
|
|
11
11
|
import { checkForUpdates, getCurrentVersion, } from "../services/version-check.js";
|
|
12
12
|
import { useKeyboardHandler } from "./hooks/useKeyboardHandler.js";
|
|
13
13
|
import { ProgressBar } from "./components/layout/ProgressBar.js";
|
|
@@ -179,6 +179,7 @@ function AppContentInner({ showDebug, onDebugToggle, updateInfo, onExit, }) {
|
|
|
179
179
|
const { state, dispatch } = useApp();
|
|
180
180
|
const { progress } = state;
|
|
181
181
|
const dimensions = useDimensions();
|
|
182
|
+
const [recoveryReport, setRecoveryReport] = useState(null);
|
|
182
183
|
// Auto-refresh marketplaces on startup
|
|
183
184
|
useEffect(() => {
|
|
184
185
|
const noRefresh = process.argv.includes("--no-refresh");
|
|
@@ -190,6 +191,35 @@ function AppContentInner({ showDebug, onDebugToggle, updateInfo, onExit, }) {
|
|
|
190
191
|
});
|
|
191
192
|
// Migrate old marketplace names → magus (idempotent), then repair plugin.json files
|
|
192
193
|
migrateMarketplaceRename().catch(() => { }); // non-blocking, best-effort
|
|
194
|
+
// Recover stale marketplace registry entries (e.g. "directory" → "github")
|
|
195
|
+
recoverMarketplaceSettings()
|
|
196
|
+
.then(async (recovery) => {
|
|
197
|
+
const msgs = [];
|
|
198
|
+
if (recovery.reregistered.length > 0) {
|
|
199
|
+
msgs.push(`Re-registered as GitHub: ${recovery.reregistered.join(", ")}`);
|
|
200
|
+
// Update the marketplace clone now that the source is fixed
|
|
201
|
+
const { updateMarketplace } = await import("../services/claude-cli.js");
|
|
202
|
+
for (const mp of recovery.reregistered) {
|
|
203
|
+
try {
|
|
204
|
+
await updateMarketplace(mp);
|
|
205
|
+
msgs.push(`Updated marketplace: ${mp}`);
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
msgs.push(`Failed to update: ${mp}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
if (recovery.enabledAutoUpdate.length > 0) {
|
|
213
|
+
msgs.push(`Enabled auto-update: ${recovery.enabledAutoUpdate.join(", ")}`);
|
|
214
|
+
}
|
|
215
|
+
if (recovery.removed.length > 0) {
|
|
216
|
+
msgs.push(`Removed stale: ${recovery.removed.join(", ")}`);
|
|
217
|
+
}
|
|
218
|
+
if (msgs.length > 0) {
|
|
219
|
+
setRecoveryReport(msgs.join("\n"));
|
|
220
|
+
}
|
|
221
|
+
})
|
|
222
|
+
.catch(() => { }); // non-fatal
|
|
193
223
|
repairAllMarketplaces()
|
|
194
224
|
.then(async () => {
|
|
195
225
|
dispatch({ type: "HIDE_PROGRESS" });
|
|
@@ -199,7 +229,7 @@ function AppContentInner({ showDebug, onDebugToggle, updateInfo, onExit, }) {
|
|
|
199
229
|
dispatch({ type: "HIDE_PROGRESS" });
|
|
200
230
|
});
|
|
201
231
|
}, [dispatch]);
|
|
202
|
-
return (_jsxs("box", { flexDirection: "column", height: dimensions.terminalHeight, children: [updateInfo?.updateAvailable && _jsx(UpdateBanner, { result: updateInfo }), showDebug && (_jsx("box", { paddingLeft: 1, paddingRight: 1, children: _jsxs("text", { fg: "#888888", children: ["DEBUG: ", dimensions.terminalWidth, "x", dimensions.terminalHeight, " | content=", dimensions.contentHeight, " | screen=", state.currentRoute.screen] }) })), progress && _jsx(ProgressIndicator, { ...progress }), _jsx("box", { flexDirection: "column", height: dimensions.contentHeight, paddingLeft: 1, paddingRight: 1, children: _jsx(Router, {}) }), _jsx(GlobalKeyHandler, { onDebugToggle: onDebugToggle, onExit: onExit }), _jsx(ModalContainer, {})] }));
|
|
232
|
+
return (_jsxs("box", { flexDirection: "column", height: dimensions.terminalHeight, children: [updateInfo?.updateAvailable && _jsx(UpdateBanner, { result: updateInfo }), recoveryReport && (_jsxs("box", { paddingLeft: 1, paddingRight: 1, children: [_jsx("text", { bg: "green", fg: "black", children: _jsx("strong", { children: " RECOVERED " }) }), _jsxs("text", { fg: "green", children: [" ", recoveryReport.split("\n").join(" | ")] })] })), showDebug && (_jsx("box", { paddingLeft: 1, paddingRight: 1, children: _jsxs("text", { fg: "#888888", children: ["DEBUG: ", dimensions.terminalWidth, "x", dimensions.terminalHeight, " | content=", dimensions.contentHeight, " | screen=", state.currentRoute.screen] }) })), progress && _jsx(ProgressIndicator, { ...progress }), _jsx("box", { flexDirection: "column", height: dimensions.contentHeight, paddingLeft: 1, paddingRight: 1, children: _jsx(Router, {}) }), _jsx(GlobalKeyHandler, { onDebugToggle: onDebugToggle, onExit: onExit }), _jsx(ModalContainer, {})] }));
|
|
203
233
|
}
|
|
204
234
|
function AppContent({ onExit }) {
|
|
205
235
|
const { state } = useApp();
|
package/src/ui/App.tsx
CHANGED
|
@@ -24,7 +24,10 @@ import {
|
|
|
24
24
|
} from "./screens/index.js";
|
|
25
25
|
import type { Screen } from "./state/types.js";
|
|
26
26
|
import { repairAllMarketplaces } from "../services/local-marketplace.js";
|
|
27
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
migrateMarketplaceRename,
|
|
29
|
+
recoverMarketplaceSettings,
|
|
30
|
+
} from "../services/claude-settings.js";
|
|
28
31
|
import {
|
|
29
32
|
checkForUpdates,
|
|
30
33
|
getCurrentVersion,
|
|
@@ -258,6 +261,7 @@ function AppContentInner({
|
|
|
258
261
|
const { state, dispatch } = useApp();
|
|
259
262
|
const { progress } = state;
|
|
260
263
|
const dimensions = useDimensions();
|
|
264
|
+
const [recoveryReport, setRecoveryReport] = useState<string | null>(null);
|
|
261
265
|
|
|
262
266
|
// Auto-refresh marketplaces on startup
|
|
263
267
|
useEffect(() => {
|
|
@@ -272,6 +276,43 @@ function AppContentInner({
|
|
|
272
276
|
// Migrate old marketplace names → magus (idempotent), then repair plugin.json files
|
|
273
277
|
migrateMarketplaceRename().catch(() => {}); // non-blocking, best-effort
|
|
274
278
|
|
|
279
|
+
// Recover stale marketplace registry entries (e.g. "directory" → "github")
|
|
280
|
+
recoverMarketplaceSettings()
|
|
281
|
+
.then(async (recovery) => {
|
|
282
|
+
const msgs: string[] = [];
|
|
283
|
+
if (recovery.reregistered.length > 0) {
|
|
284
|
+
msgs.push(
|
|
285
|
+
`Re-registered as GitHub: ${recovery.reregistered.join(", ")}`,
|
|
286
|
+
);
|
|
287
|
+
// Update the marketplace clone now that the source is fixed
|
|
288
|
+
const { updateMarketplace } = await import(
|
|
289
|
+
"../services/claude-cli.js"
|
|
290
|
+
);
|
|
291
|
+
for (const mp of recovery.reregistered) {
|
|
292
|
+
try {
|
|
293
|
+
await updateMarketplace(mp);
|
|
294
|
+
msgs.push(`Updated marketplace: ${mp}`);
|
|
295
|
+
} catch {
|
|
296
|
+
msgs.push(`Failed to update: ${mp}`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (recovery.enabledAutoUpdate.length > 0) {
|
|
301
|
+
msgs.push(
|
|
302
|
+
`Enabled auto-update: ${recovery.enabledAutoUpdate.join(", ")}`,
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
if (recovery.removed.length > 0) {
|
|
306
|
+
msgs.push(
|
|
307
|
+
`Removed stale: ${recovery.removed.join(", ")}`,
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
if (msgs.length > 0) {
|
|
311
|
+
setRecoveryReport(msgs.join("\n"));
|
|
312
|
+
}
|
|
313
|
+
})
|
|
314
|
+
.catch(() => {}); // non-fatal
|
|
315
|
+
|
|
275
316
|
repairAllMarketplaces()
|
|
276
317
|
.then(async () => {
|
|
277
318
|
dispatch({ type: "HIDE_PROGRESS" });
|
|
@@ -285,6 +326,14 @@ function AppContentInner({
|
|
|
285
326
|
return (
|
|
286
327
|
<box flexDirection="column" height={dimensions.terminalHeight}>
|
|
287
328
|
{updateInfo?.updateAvailable && <UpdateBanner result={updateInfo} />}
|
|
329
|
+
{recoveryReport && (
|
|
330
|
+
<box paddingLeft={1} paddingRight={1}>
|
|
331
|
+
<text bg="green" fg="black">
|
|
332
|
+
<strong> RECOVERED </strong>
|
|
333
|
+
</text>
|
|
334
|
+
<text fg="green"> {recoveryReport.split("\n").join(" | ")}</text>
|
|
335
|
+
</box>
|
|
336
|
+
)}
|
|
288
337
|
{showDebug && (
|
|
289
338
|
<box paddingLeft={1} paddingRight={1}>
|
|
290
339
|
<text fg="#888888">
|