fix(management): skip broken shared plugin entries

This commit is contained in:
Kai (Tam Nhu) Tran
2026-05-30 14:57:17 -04:00
parent c21f589247
commit f44b651cd6
2 changed files with 38 additions and 1 deletions
+13 -1
View File
@@ -354,7 +354,19 @@ class SharedManager {
}
const entryPath = path.join(sharedPluginsPath, entry.name);
const stats = fs.statSync(entryPath);
let stats: fs.Stats;
try {
stats = fs.statSync(entryPath);
} catch (err) {
const code = (err as NodeJS.ErrnoException).code;
console.log(
warn(
`Skipping plugins/${entry.name}: unable to inspect shared plugin entry${code ? ` (${code})` : ''}`
)
);
continue;
}
items.set(entry.name, {
name: entry.name,
type: stats.isDirectory() ? 'directory' : 'file',
+25
View File
@@ -307,6 +307,31 @@ describe('SharedManager', () => {
});
describe('marketplace registry ownership', () => {
it('skips unstatable shared plugin entries during instance linking', () => {
const manager = new SharedManager();
const instancePath = instanceDir('work');
const sharedPluginsPath = path.join(claudeDir(), 'plugins');
const logSpy = spyOn(console, 'log').mockImplementation(() => {});
fs.mkdirSync(instancePath, { recursive: true });
fs.mkdirSync(sharedPluginsPath, { recursive: true });
fs.symlinkSync(
path.join(sharedPluginsPath, 'missing-plugin'),
path.join(sharedPluginsPath, 'broken-plugin'),
'dir'
);
expect(() => manager.linkSharedDirectories(instancePath)).not.toThrow();
expect(fs.existsSync(path.join(instancePath, 'plugins', 'broken-plugin'))).toBe(false);
expect(
logSpy.mock.calls.some(([message]) =>
String(message).includes(
'Skipping plugins/broken-plugin: unable to inspect shared plugin entry'
)
)
).toBe(true);
});
it('writes global and instance registries with different authoritative install locations', () => {
const globalRegistryPath = path.join(claudeDir(), 'plugins', 'known_marketplaces.json');
ensureMarketplacePayload(claudeDir());