source dump of claude code
at main 216 lines 7.7 kB view raw
1import type { ContentBlockParam } from '@anthropic-ai/sdk/resources/index.mjs' 2import type { UUID } from 'crypto' 3import type { CanUseToolFn } from '../hooks/useCanUseTool.js' 4import type { CompactionResult } from '../services/compact/compact.js' 5import type { ScopedMcpServerConfig } from '../services/mcp/types.js' 6import type { ToolUseContext } from '../Tool.js' 7import type { EffortValue } from '../utils/effort.js' 8import type { IDEExtensionInstallationStatus, IdeType } from '../utils/ide.js' 9import type { SettingSource } from '../utils/settings/constants.js' 10import type { HooksSettings } from '../utils/settings/types.js' 11import type { ThemeName } from '../utils/theme.js' 12import type { LogOption } from './logs.js' 13import type { Message } from './message.js' 14import type { PluginManifest } from './plugin.js' 15 16export type LocalCommandResult = 17 | { type: 'text'; value: string } 18 | { 19 type: 'compact' 20 compactionResult: CompactionResult 21 displayText?: string 22 } 23 | { type: 'skip' } // Skip messages 24 25export type PromptCommand = { 26 type: 'prompt' 27 progressMessage: string 28 contentLength: number // Length of command content in characters (used for token estimation) 29 argNames?: string[] 30 allowedTools?: string[] 31 model?: string 32 source: SettingSource | 'builtin' | 'mcp' | 'plugin' | 'bundled' 33 pluginInfo?: { 34 pluginManifest: PluginManifest 35 repository: string 36 } 37 disableNonInteractive?: boolean 38 // Hooks to register when this skill is invoked 39 hooks?: HooksSettings 40 // Base directory for skill resources (used to set CLAUDE_PLUGIN_ROOT environment variable for skill hooks) 41 skillRoot?: string 42 // Execution context: 'inline' (default) or 'fork' (run as sub-agent) 43 // 'inline' = skill content expands into the current conversation 44 // 'fork' = skill runs in a sub-agent with separate context and token budget 45 context?: 'inline' | 'fork' 46 // Agent type to use when forked (e.g., 'Bash', 'general-purpose') 47 // Only applicable when context is 'fork' 48 agent?: string 49 effort?: EffortValue 50 // Glob patterns for file paths this skill applies to 51 // When set, the skill is only visible after the model touches matching files 52 paths?: string[] 53 getPromptForCommand( 54 args: string, 55 context: ToolUseContext, 56 ): Promise<ContentBlockParam[]> 57} 58 59/** 60 * The call signature for a local command implementation. 61 */ 62export type LocalCommandCall = ( 63 args: string, 64 context: LocalJSXCommandContext, 65) => Promise<LocalCommandResult> 66 67/** 68 * Module shape returned by load() for lazy-loaded local commands. 69 */ 70export type LocalCommandModule = { 71 call: LocalCommandCall 72} 73 74type LocalCommand = { 75 type: 'local' 76 supportsNonInteractive: boolean 77 load: () => Promise<LocalCommandModule> 78} 79 80export type LocalJSXCommandContext = ToolUseContext & { 81 canUseTool?: CanUseToolFn 82 setMessages: (updater: (prev: Message[]) => Message[]) => void 83 options: { 84 dynamicMcpConfig?: Record<string, ScopedMcpServerConfig> 85 ideInstallationStatus: IDEExtensionInstallationStatus | null 86 theme: ThemeName 87 } 88 onChangeAPIKey: () => void 89 onChangeDynamicMcpConfig?: ( 90 config: Record<string, ScopedMcpServerConfig>, 91 ) => void 92 onInstallIDEExtension?: (ide: IdeType) => void 93 resume?: ( 94 sessionId: UUID, 95 log: LogOption, 96 entrypoint: ResumeEntrypoint, 97 ) => Promise<void> 98} 99 100export type ResumeEntrypoint = 101 | 'cli_flag' 102 | 'slash_command_picker' 103 | 'slash_command_session_id' 104 | 'slash_command_title' 105 | 'fork' 106 107export type CommandResultDisplay = 'skip' | 'system' | 'user' 108 109/** 110 * Callback when a command completes. 111 * @param result - Optional user-visible message to display 112 * @param options - Optional configuration for command completion 113 * @param options.display - How to display the result: 'skip' | 'system' | 'user' (default) 114 * @param options.shouldQuery - If true, send messages to the model after command completes 115 * @param options.metaMessages - Additional messages to insert as isMeta (model-visible but hidden) 116 */ 117export type LocalJSXCommandOnDone = ( 118 result?: string, 119 options?: { 120 display?: CommandResultDisplay 121 shouldQuery?: boolean 122 metaMessages?: string[] 123 nextInput?: string 124 submitNextInput?: boolean 125 }, 126) => void 127 128/** 129 * The call signature for a local JSX command implementation. 130 */ 131export type LocalJSXCommandCall = ( 132 onDone: LocalJSXCommandOnDone, 133 context: ToolUseContext & LocalJSXCommandContext, 134 args: string, 135) => Promise<React.ReactNode> 136 137/** 138 * Module shape returned by load() for lazy-loaded commands. 139 */ 140export type LocalJSXCommandModule = { 141 call: LocalJSXCommandCall 142} 143 144type LocalJSXCommand = { 145 type: 'local-jsx' 146 /** 147 * Lazy-load the command implementation. 148 * Returns a module with a call() function. 149 * This defers loading heavy dependencies until the command is invoked. 150 */ 151 load: () => Promise<LocalJSXCommandModule> 152} 153 154/** 155 * Declares which auth/provider environments a command is available in. 156 * 157 * This is separate from `isEnabled()`: 158 * - `availability` = who can use this (auth/provider requirement, static) 159 * - `isEnabled()` = is this turned on right now (GrowthBook, platform, env vars) 160 * 161 * Commands without `availability` are available everywhere. 162 * Commands with `availability` are only shown if the user matches at least one 163 * of the listed auth types. See meetsAvailabilityRequirement() in commands.ts. 164 * 165 * Example: `availability: ['claude-ai', 'console']` shows the command to 166 * claude.ai subscribers and direct Console API key users (api.anthropic.com), 167 * but hides it from Bedrock/Vertex/Foundry users and custom base URL users. 168 */ 169export type CommandAvailability = 170 // claude.ai OAuth subscriber (Pro/Max/Team/Enterprise via claude.ai) 171 | 'claude-ai' 172 // Console API key user (direct api.anthropic.com, not via claude.ai OAuth) 173 | 'console' 174 175export type CommandBase = { 176 availability?: CommandAvailability[] 177 description: string 178 hasUserSpecifiedDescription?: boolean 179 /** Defaults to true. Only set when the command has conditional enablement (feature flags, env checks, etc). */ 180 isEnabled?: () => boolean 181 /** Defaults to false. Only set when the command should be hidden from typeahead/help. */ 182 isHidden?: boolean 183 name: string 184 aliases?: string[] 185 isMcp?: boolean 186 argumentHint?: string // Hint text for command arguments (displayed in gray after command) 187 whenToUse?: string // From the "Skill" spec. Detailed usage scenarios for when to use this command 188 version?: string // Version of the command/skill 189 disableModelInvocation?: boolean // Whether to disable this command from being invoked by models 190 userInvocable?: boolean // Whether users can invoke this skill by typing /skill-name 191 loadedFrom?: 192 | 'commands_DEPRECATED' 193 | 'skills' 194 | 'plugin' 195 | 'managed' 196 | 'bundled' 197 | 'mcp' // Where the command was loaded from 198 kind?: 'workflow' // Distinguishes workflow-backed commands (badged in autocomplete) 199 immediate?: boolean // If true, command executes immediately without waiting for a stop point (bypasses queue) 200 isSensitive?: boolean // If true, args are redacted from the conversation history 201 /** Defaults to `name`. Only override when the displayed name differs (e.g. plugin prefix stripping). */ 202 userFacingName?: () => string 203} 204 205export type Command = CommandBase & 206 (PromptCommand | LocalCommand | LocalJSXCommand) 207 208/** Resolves the user-visible name, falling back to `cmd.name` when not overridden. */ 209export function getCommandName(cmd: CommandBase): string { 210 return cmd.userFacingName?.() ?? cmd.name 211} 212 213/** Resolves whether the command is enabled, defaulting to true. */ 214export function isCommandEnabled(cmd: CommandBase): boolean { 215 return cmd.isEnabled?.() ?? true 216}