MCPcopy Create free account
hub / github.com/AnukarOP/claude-code-leaked / pluginListHandler

Function pluginListHandler

source code/cli/handlers/plugins.ts:159–446  ·  view source on GitHub ↗
(options: {
  json?: boolean
  available?: boolean
  cowork?: boolean
})

Source from the content-addressed store, hash-verified

157
158// plugin list (lines 5217–5416)
159export async function pluginListHandler(options: {
160 json?: boolean
161 available?: boolean
162 cowork?: boolean
163}): Promise<void> {
164 if (options.cowork) setUseCoworkPlugins(true)
165 logEvent('tengu_plugin_list_command', {})
166
167 const installedData = loadInstalledPluginsV2()
168 const { getPluginEditableScopes } = await import(
169 '../../utils/plugins/pluginStartupCheck.js'
170 )
171 const enabledPlugins = getPluginEditableScopes()
172
173 const pluginIds = Object.keys(installedData.plugins)
174
175 // Load all plugins once. The JSON and human paths both need:
176 // - loadErrors (to show load failures per plugin)
177 // - inline plugins (session-only via --plugin-dir, source='name@inline')
178 // which are NOT in installedData.plugins (V2 bookkeeping) — they must
179 // be surfaced separately or `plugin list` silently ignores --plugin-dir.
180 const {
181 enabled: loadedEnabled,
182 disabled: loadedDisabled,
183 errors: loadErrors,
184 } = await loadAllPlugins()
185 const allLoadedPlugins = [...loadedEnabled, ...loadedDisabled]
186 const inlinePlugins = allLoadedPlugins.filter(p =>
187 p.source.endsWith('@inline'),
188 )
189 // Path-level inline failures (dir doesn't exist, parse error before
190 // manifest is read) use source='inline[N]'. Plugin-level errors after
191 // manifest read use source='name@inline'. Collect both for the session
192 // section — these are otherwise invisible since they have no pluginId.
193 const inlineLoadErrors = loadErrors.filter(
194 e => e.source.endsWith('@inline') || e.source.startsWith('inline['),
195 )
196
197 if (options.json) {
198 // Create a map of plugin source to loaded plugin for quick lookup
199 const loadedPluginMap = new Map(allLoadedPlugins.map(p => [p.source, p]))
200
201 const plugins: Array<{
202 id: string
203 version: string
204 scope: string
205 enabled: boolean
206 installPath: string
207 installedAt?: string
208 lastUpdated?: string
209 projectPath?: string
210 mcpServers?: Record<string, unknown>
211 errors?: string[]
212 }> = []
213
214 for (const pluginId of pluginIds.sort()) {
215 const installations = installedData.plugins[pluginId]
216 if (!installations || installations.length === 0) continue

Callers 1

runFunction · 0.85

Calls 15

setUseCoworkPluginsFunction · 0.85
logEventFunction · 0.85
loadInstalledPluginsV2Function · 0.85
getPluginEditableScopesFunction · 0.85
loadAllPluginsFunction · 0.85
parsePluginIdentifierFunction · 0.85
loadPluginMcpServersFunction · 0.85
getPluginErrorMessageFunction · 0.85
getInstallCountsFunction · 0.85
createPluginIdFunction · 0.85

Tested by

no test coverage detected