fix(plugins): isole les menus plugin et durcit hello-plugin SDK contre la rechute #120

Requalification Architect du 2026-08-01: le crash INTERFACE INTERROMPUE au
chargement d'un plugin (menu + item) remonte via ProjectsView -> usePluginMenus
-> MenuBar jusqu'à RootErrorBoundary, quel que soit le plugin (ancien ou
reconstruit via SDK).

- usePluginMenus isole la résolution/conversion des contributions plugin :
  toute erreur retombe sur [] au lieu de propager.
- ProjectsView sépare les menus natifs des menus enrichis par plugin et rend
  MenuBar derrière une error boundary locale (fallback menus natifs seuls).
- hello-plugin (SDK) et les tests d'installation associés durcis en cohérence.

Bookkeeping ticket #120 uniquement (issue.md, carnet.md) ; les fichiers
counter.json/index.json et le dossier tickets/122/ restent hors commit car
une collision de numérotation #122 existe entre cette base et
feature/ticket120-hello-plugin-install-path-audit (deux tickets différents
revendiquent #122) — à arbitrer avant de committer le bookkeeping global.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-01 16:23:56 +02:00
parent 8031d86deb
commit 5a30ec8b9c
11 changed files with 516 additions and 75 deletions

View File

@ -301,8 +301,20 @@ export async function loadPlugins(
entries.map((entry) => loadOne(entry, gateways, resolvedOptions)),
);
for (const result of results) {
if ("failure" in result) failures.push(result.failure);
else registry.add(result.plugin);
if ("failure" in result) {
failures.push(result.failure);
console.warn(
`[plugins] load failed plugin=${result.failure.pluginId}: ${result.failure.reason}`,
);
} else {
registry.add(result.plugin);
}
}
if (entries.length > 0) {
console.info(
`[plugins] load complete loaded=${registry.list().length} failed=${failures.length}`,
);
}
return { registry, failures };