(error: PluginError)
| 59 | return getPluginErrorMessage(_exhaustive); |
| 60 | } |
| 61 | export function getErrorGuidance(error: PluginError): string | null { |
| 62 | switch (error.type) { |
| 63 | case 'path-not-found': |
| 64 | return 'Check that the path in your manifest or marketplace config is correct'; |
| 65 | case 'git-auth-failed': |
| 66 | return error.authType === 'ssh' ? 'Configure SSH keys or use HTTPS URL instead' : 'Configure credentials or use SSH URL instead'; |
| 67 | case 'git-timeout': |
| 68 | case 'network-error': |
| 69 | return 'Check your internet connection and try again'; |
| 70 | case 'manifest-parse-error': |
| 71 | return 'Check manifest file syntax in the plugin directory'; |
| 72 | case 'manifest-validation-error': |
| 73 | return 'Check manifest file follows the required schema'; |
| 74 | case 'plugin-not-found': |
| 75 | return `Plugin may not exist in marketplace "${error.marketplace}"`; |
| 76 | case 'marketplace-not-found': |
| 77 | return error.availableMarketplaces.length > 0 ? `Available marketplaces: ${error.availableMarketplaces.join(', ')}` : 'Add the marketplace first using /plugin marketplace add'; |
| 78 | case 'mcp-config-invalid': |
| 79 | return 'Check MCP server configuration in .mcp.json or manifest'; |
| 80 | case 'mcp-server-suppressed-duplicate': |
| 81 | { |
| 82 | // duplicateOf is "plugin:name:srv" when another plugin won dedup — |
| 83 | // users can't remove plugin-provided servers from their MCP config, |
| 84 | // so point them at the winning plugin instead. |
| 85 | if (error.duplicateOf.startsWith('plugin:')) { |
| 86 | const winningPlugin = error.duplicateOf.split(':')[1] ?? 'the other plugin'; |
| 87 | return `Disable plugin "${winningPlugin}" if you want this plugin's version instead`; |
| 88 | } |
| 89 | return `Remove "${error.duplicateOf}" from your MCP config if you want the plugin's version instead`; |
| 90 | } |
| 91 | case 'hook-load-failed': |
| 92 | return 'Check hooks.json file syntax and structure'; |
| 93 | case 'component-load-failed': |
| 94 | return `Check ${error.component} directory structure and file permissions`; |
| 95 | case 'mcpb-download-failed': |
| 96 | return 'Check your internet connection and URL accessibility'; |
| 97 | case 'mcpb-extract-failed': |
| 98 | return 'Verify the MCPB file is valid and not corrupted'; |
| 99 | case 'mcpb-invalid-manifest': |
| 100 | return 'Contact the plugin author about the invalid manifest'; |
| 101 | case 'marketplace-blocked-by-policy': |
| 102 | if (error.blockedByBlocklist) { |
| 103 | return 'This marketplace source is explicitly blocked by your administrator'; |
| 104 | } |
| 105 | return error.allowedSources.length > 0 ? `Allowed sources: ${error.allowedSources.join(', ')}` : 'Contact your administrator to configure allowed marketplace sources'; |
| 106 | case 'dependency-unsatisfied': |
| 107 | return error.reason === 'not-enabled' ? `Enable "${error.dependency}" or uninstall "${error.plugin}"` : `Install "${error.dependency}" or uninstall "${error.plugin}"`; |
| 108 | case 'lsp-config-invalid': |
| 109 | return 'Check LSP server configuration in the plugin manifest'; |
| 110 | case 'lsp-server-start-failed': |
| 111 | case 'lsp-server-crashed': |
| 112 | case 'lsp-request-timeout': |
| 113 | case 'lsp-request-failed': |
| 114 | return 'Check LSP server logs with --debug for details'; |
| 115 | case 'plugin-cache-miss': |
| 116 | return 'Run /plugins to refresh the plugin cache'; |
| 117 | case 'marketplace-load-failed': |
| 118 | case 'generic-error': |
no outgoing calls
no test coverage detected