Something went wrong. Try again.
source dump of claude code forked from oppi.li/claude-code
Something went wrong. Try again.
5.0 kB · 159 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160/** * Built-in Plugin Registry * * Manages built-in plugins that ship with the CLI and can be enabled/disabled * by users via the /plugin UI. * * Built-in plugins differ from bundled skills (src/skills/bundled/) in that: * - They appear in the /plugin UI under a "Built-in" section * - Users can enable/disable them (persisted to user settings) * - They can provide multiple components (skills, hooks, MCP servers) * * Plugin IDs use the format `{name}@builtin` to distinguish them from * marketplace plugins (`{name}@{marketplace}`). */
import type { Command } from '../commands.js'import type { BundledSkillDefinition } from '../skills/bundledSkills.js'import type { BuiltinPluginDefinition, LoadedPlugin } from '../types/plugin.js'import { getSettings_DEPRECATED } from '../utils/settings/settings.js'
const BUILTIN_PLUGINS: Map<string, BuiltinPluginDefinition> = new Map()
export const BUILTIN_MARKETPLACE_NAME = 'builtin'
/** * Register a built-in plugin. Call this from initBuiltinPlugins() at startup. */export function registerBuiltinPlugin( definition: BuiltinPluginDefinition,): void { BUILTIN_PLUGINS.set(definition.name, definition)}
/** * Check if a plugin ID represents a built-in plugin (ends with @builtin). */export function isBuiltinPluginId(pluginId: string): boolean { return pluginId.endsWith(`@${BUILTIN_MARKETPLACE_NAME}`)}
/** * Get a specific built-in plugin definition by name. * Useful for the /plugin UI to show the skills/hooks/MCP list without * a marketplace lookup. */export function getBuiltinPluginDefinition( name: string,): BuiltinPluginDefinition | undefined { return BUILTIN_PLUGINS.get(name)}
/** * Get all registered built-in plugins as LoadedPlugin objects, split into * enabled/disabled based on user settings (with defaultEnabled as fallback). * Plugins whose isAvailable() returns false are omitted entirely. */export function getBuiltinPlugins(): { enabled: LoadedPlugin[] disabled: LoadedPlugin[]} { const settings = getSettings_DEPRECATED() const enabled: LoadedPlugin[] = [] const disabled: LoadedPlugin[] = []
for (const [name, definition] of BUILTIN_PLUGINS) { if (definition.isAvailable && !definition.isAvailable()) { continue }
const pluginId = `${name}@${BUILTIN_MARKETPLACE_NAME}` const userSetting = settings?.enabledPlugins?.[pluginId] // Enabled state: user preference > plugin default > true const isEnabled = userSetting !== undefined ? userSetting === true : (definition.defaultEnabled ?? true)
const plugin: LoadedPlugin = { name, manifest: { name, description: definition.description, version: definition.version, }, path: BUILTIN_MARKETPLACE_NAME, // sentinel — no filesystem path source: pluginId, repository: pluginId, enabled: isEnabled, isBuiltin: true, hooksConfig: definition.hooks, mcpServers: definition.mcpServers, }
if (isEnabled) { enabled.push(plugin) } else { disabled.push(plugin) } }
return { enabled, disabled }}
/** * Get skills from enabled built-in plugins as Command objects. * Skills from disabled plugins are not returned. */export function getBuiltinPluginSkillCommands(): Command[] { const { enabled } = getBuiltinPlugins() const commands: Command[] = []
for (const plugin of enabled) { const definition = BUILTIN_PLUGINS.get(plugin.name) if (!definition?.skills) continue for (const skill of definition.skills) { commands.push(skillDefinitionToCommand(skill)) } }
return commands}
/** * Clear built-in plugins registry (for testing). */export function clearBuiltinPlugins(): void { BUILTIN_PLUGINS.clear()}
// --
function skillDefinitionToCommand(definition: BundledSkillDefinition): Command { return { type: 'prompt', name: definition.name, description: definition.description, hasUserSpecifiedDescription: true, allowedTools: definition.allowedTools ?? [], argumentHint: definition.argumentHint, whenToUse: definition.whenToUse, model: definition.model, disableModelInvocation: definition.disableModelInvocation ?? false, userInvocable: definition.userInvocable ?? true, contentLength: 0, // 'bundled' not 'builtin' — 'builtin' in Command.source means hardcoded // slash commands (/help, /clear). Using 'bundled' keeps these skills in // the Skill tool's listing, analytics name logging, and prompt-truncation // exemption. The user-toggleable aspect is tracked on LoadedPlugin.isBuiltin. source: 'bundled', loadedFrom: 'bundled', hooks: definition.hooks, context: definition.context, agent: definition.agent, isEnabled: definition.isEnabled ?? (() => true), isHidden: !(definition.userInvocable ?? true), progressMessage: 'running', getPromptForCommand: definition.getPromptForCommand, }}