21.2 插件架构与生命周期

第 21 章 · 插件开发基础 · 第6部分:插件系统

21.2.1 插件架构概述#

整体架构#

Claude Code 插件采用分层架构设计,确保模块化和可扩展性。

markdown
复制
┌─────────────────────────────────────────┐ │ Claude Code 核心系统 │ ├─────────────────────────────────────────┤ │ 插件接口层 (Plugin Interface) │ ├─────────────────────────────────────────┤ │ 插件核心层 (Plugin Core) │ ├─────────────────────────────────────────┤ │ ┌──────────┐ ┌──────────┐ ┌────────┐ │ │ │ 工具层 │ │ 命令层 │ │钩子层 │ │ │ │(Tools) │ │(Commands)│ │(Hooks) │ │ │ └──────────┘ └──────────┘ └────────┘ │ ├─────────────────────────────────────────┤ │ 插件基础层 (Plugin Base) │ ├─────────────────────────────────────────┤ │ 插件实现层 (Plugin Impl) │ └─────────────────────────────────────────┘

架构组件#

typescript
复制
// 插件架构组件interfacePluginArchitecture{// 插件接口层interface:{ IPlugin: PluginInterface; ITool: ToolInterface; ICommand: CommandInterface; IHook: HookInterface;}; // 插件核心层 core:{ PluginManager: PluginManager; PluginRegistry: PluginRegistry; PluginLoader: PluginLoader;}; // 插件功能层 features:{ tools: Tool[]; commands: Command[]; hooks: Hook[];}; // 插件基础层 base:{ Plugin: PluginBase; Tool: ToolBase; Command: CommandBase; Hook: HookBase;};}

21.2.2 插件接口定义#

1. IPlugin 接口#

typescript
复制
// src/types/index.tsimport{ PluginConfig, PluginContext, PluginResult }from'@claude-code/plugin-sdk'; /** * 插件接口 */exportinterfaceIPlugin{/** * 插件名称 */ name:string; /** * 插件版本 */ version:string; /** * 插件描述 */ description:string; /** * 插件作者 */ author?:string; /** * 插件许可证 */ license?:string; /** * 初始化插件 */initialize(config: PluginConfig):Promisevoid>; /** * 启动插件 */start():Promisevoid>; /** * 停止插件 */stop():Promisevoid>; /** * 清理插件 */cleanup():Promisevoid>; /** * 获取插件状态 */getStatus(): PluginStatus;}

2. ITool 接口#

typescript
复制
/** * 工具接口 */exportinterfaceITool{/** * 工具名称 */ name:string; /** * 工具描述 */ description:string; /** * 工具参数定义 */ parameters: ToolParameter[]; /** * 执行工具 */execute(params: Recordstring,any>, context: PluginContext):PromiseToolResult>; /** * 验证参数 */validate(params: Recordstring,any>): ValidationResult;} /** * 工具参数定义 */exportinterfaceToolParameter{/** * 参数名称 */ name:string; /** * 参数类型 */ type:'string'|'number'|'boolean'|'object'|'array'; /** * 参数描述 */ description:string; /** * 是否必需 */ required:boolean; /** * 默认值 */default?:any; /** * 枚举值 */enum?:any[];} /** * 工具执行结果 */exportinterfaceToolResult{/** * 是否成功 */ success:boolean; /** * 结果数据 */ data?:any; /** * 错误信息 */ error?:string; /** * 执行时间 */ executionTime?:number;}

3. ICommand 接口#

typescript
复制
/** * 命令接口 */exportinterfaceICommand{/** * 命令名称 */ name:string; /** * 命令描述 */ description:string; /** * 命令参数定义 */ parameters: CommandParameter[]; /** * 执行命令 */execute(args:string[], context: PluginContext):PromiseCommandResult>; /** * 显示帮助 */help():string;} /** * 命令参数定义 */exportinterfaceCommandParameter{/** * 参数名称 */ name:string; /** * 参数类型 */ type:'string'|'number'|'boolean'|'flag'; /** * 参数描述 */ description:string; /** * 是否必需 */ required:boolean; /** * 简写 */ short?:string; /** * 默认值 */default?:any;} /** * 命令执行结果 */exportinterfaceCommandResult{/** * 是否成功 */ success:boolean; /** * 输出内容 */ output?:string; /** * 错误信息 */ error?:string; /** * 退出码 */ exitCode?:number;}

4. IHook 接口#

typescript
复制
/** * 钩子接口 */exportinterfaceIHook{/** * 钩子名称 */ name:string; /** * 钩子类型 */ type: HookType; /** * 钩子描述 */ description:string; /** * 执行钩子 */execute(event: HookEvent, context: PluginContext):PromiseHookResult>;} /** * 钩子类型 */exporttypeHookType=|'before_command'// 命令执行前|'after_command'// 命令执行后|'on_error'// 错误发生时|'on_start'// 插件启动时|'on_stop'// 插件停止时|'on_message'// 消息接收时; /** * 钩子事件 */exportinterfaceHookEvent{/** * 事件类型 */ type:string; /** * 事件数据 */ data: Recordstring,any>; /** * 事件时间戳 */ timestamp: Date;} /** * 钩子执行结果 */exportinterfaceHookResult{/** * 是否成功 */ success:boolean; /** * 是否阻止后续处理 */ preventDefault?:boolean; /** * 修改后的事件数据 */ modifiedData?: Recordstring,any>; /** * 错误信息 */ error?:string;}

21.2.3 插件生命周期#

生命周期阶段#

typescript
复制
/** * 插件生命周期阶段 */exportenum PluginLifecycleStage {/** * 未加载 */UNLOADED='unloaded',/** * 已加载 */LOADED='loaded',/** * 已初始化 */INITIALIZED='initialized',/** * 运行中 */RUNNING='running',/** * 已停止 */STOPPED='stopped',/** * 已卸载 */UNLOADED_FINAL='unloaded_final'}/** * 插件状态 */exportinterfacePluginStatus{/** * 生命周期阶段 */stage: PluginLifecycleStage;/** * 是否启用 */enabled:boolean;/** * 错误信息 */error?:string;/** * 启动时间 */startTime?: Date;/** * 运行时间 */uptime?:number;}

生命周期管理#

typescript
复制
```typescript // src/plugin.ts import { IPlugin, PluginConfig, PluginContext, PluginResult, PluginLifecycleStage, PluginStatus } from '@claude-code/plugin-sdk'; export class Plugin implements IPlugin { name: string; version: string; description: string; author?: string; license?: string; private stage: PluginLifecycleStage = PluginLifecycleStage.UNLOADED; private enabled: boolean = false; private startTime?: Date; private error?: string; constructor(config: { name: string; version: string; description: string; author?: string; license?: string; }) { this.name = config.name; this.version = config.version; this.description = config.description; this.author = config.author; this.license = config.license; } /** * 初始化插件 */ async initialize(config: PluginConfig): Promise { if (this.stage !== PluginLifecycleStage.UNLOADED) { throw new Error(`Plugin ${this.name}is already initialized`); } try { // 加载配置 this.loadConfig(config); // 初始化依赖 await this.initializeDependencies(); // 注册工具 this.registerTools(); // 注册命令 this.registerCommands(); // 注册钩子 this.registerHooks(); // 更新状态 this.stage = PluginLifecycleStage.INITIALIZED; console.log(`Plugin ${this.name} initialized`); } catch (error) { this.error = error.message; throw error; } } /** * 启动插件 */ async start(): Promise { if (this.stage !== PluginLifecycleStage.INITIALIZED) { throw new Error(`Plugin ${this.name}is not initialized`); } try { // 启动后台任务 await this.startBackgroundTasks(); // 建立连接 await this.establishConnections(); // 更新状态 this.stage = PluginLifecycleStage.RUNNING; this.enabled = true; this.startTime = new Date(); console.log(`Plugin ${this.name} started`);}catch(error){this.error = error.message;
bash
复制
  throw error;
}

}

/**

  • 停止插件 */ async stop(): Promise { if (this.stage !== PluginLifecycleStage.RUNNING) { throw new Error(Plugin ${this.name} is not running); }
bash
复制
try {
bash
复制
  // 停止后台任务
  await this.stopBackgroundTasks();

  // 关闭连接
  await this.closeConnections();

  // 更新状态
  this.stage = PluginLifecycleStage.STOPPED;
  this.enabled = false;

  console.log(`Plugin ${this.name} stopped`);
} catch (error) {
  this.error = error.message;
  throw error;
}

}

/**

  • 清理插件 */ async cleanup(): Promise { try { // 清理资源 await this.cleanupResources();

    // 注销注册 this.unregisterAll();

    // 更新状态 this.stage = PluginLifecycleStage.UNLOADED_FINAL; this.error = undefined;

    console.log(Plugin ${this.name} cleaned up); } catch (error) { this.error = error.message; throw error; } }

/**

  • 获取插件状态 */ getStatus(): PluginStatus { const uptime = this.startTime ? Date.now() - this.startTime.getTime() : 0;
bash
复制
return {
bash
复制
  stage: this.stage,
  enabled: this.enabled,
  error: this.error,
  startTime: this.startTime,
  uptime
};

}

/**

  • 加载配置 */ protected loadConfig(config: PluginConfig): void { // 子类实现 }

/**

  • 初始化依赖 */ protected async initializeDependencies(): Promise { // 子类实现 }

/**

  • 注册工具 */ protected registerTools(): void { // 子类实现 }

/**

  • 注册命令 */ protected registerCommands(): void { // 子类实现 }

/**

  • 注册钩子 */ protected registerHooks(): void { // 子类实现 }

/**

  • 启动后台任务 */ protected async startBackgroundTasks(): Promise { // 子类实现 }

/**

  • 建立连接 */ protected async establishConnections(): Promise { // 子类实现 }

/**

  • 停止后台任务 */ protected async stopBackgroundTasks(): Promise { // 子类实现 }

/**

  • 关闭连接 */ protected async closeConnections(): Promise { // 子类实现 }

/**

  • 清理资源 */ protected async cleanupResources(): Promise { // 子类实现 }

/**

  • 注销所有注册 */ protected unregisterAll(): void { // 子类实现 } }
bash
复制
### 事件定义

/**
* 插件生命周期事件
*/
export interface PluginLifecycleEvent {
/**
* 事件类型
*/
type: 'initialize' | 'start' | 'stop' | 'cleanup' | 'error';
/**
* 插件名称
*/
pluginName: string;
/**
* 事件数据
*/
data: {
stage: PluginLifecycleStage;
error?: Error;
timestamp: Date;
};
}
/**
* 事件监听器
*/
export type PluginEventListener = (event: PluginLifecycleEvent) => void;

事件管理#

typescript
复制
```typescript /** * 插件事件管理器 */ export class PluginEventManager { private listeners: Map = new Map(); /** * 注册事件监听器 */ on(eventType: string, listener: PluginEventListener): void { if (!this.listeners.has(eventType)) { this.listeners.set(eventType, []); } this.listeners.get(eventType)!.push(listener); } /** * 移除事件监听器 */ off(eventType: string, listener: PluginEventListener): void { const listeners = this.listeners.get(eventType); if (listeners) { const index = listeners.indexOf(listener); if (index > -1) { listeners.splice(index, 1); } } } /** * 触发事件 */ emit(event: PluginLifecycleEvent): void { const listeners = this.listeners.get(event.type); if (listeners) { listeners.forEach(listener => listener(event)); } } } ```### 事件集成 // src/plugin.tsimport{ PluginEventManager, PluginLifecycleEvent }from'@claude-code/plugin-sdk';exportclassPluginimplementsIPlugin{private eventManager: PluginEventManager =newPluginEventManager();/** * 初始化插件 */asyncinitialize(config: PluginConfig):Promisevoid>{try{// ... 初始化逻辑// 触发初始化事件this.emitEvent('initialize',{});console.log(`Plugin ${this.name} initialized`);}catch(error){// 触发错误事件this.emitEvent('error',{ error });throw error;}}/** * 启动插件 */asyncstart():Promisevoid>{try{// ... 启动逻辑// 触发启动事件this.emitEvent('start',{});console.log(`Plugin ${this.name} started`);}catch(error){// 触发错误事件this.emitEvent('error',{ error });throw error;}}/** * 停止插件 */asyncstop():Promisevoid>{try{// ... 停止逻辑// 触发停止事件this.emitEvent('stop',{});console.log(`Plugin ${this.name} stopped`);}catch(error){// 触发错误事件this.emitEvent('error',{ error });throw error;}}/** * 清理插件 */asynccleanup():Promisevoid>{try{// ... 清理逻辑// 触发清理事件this.emitEvent('cleanup',{});console.log(`Plugin ${this.name} cleaned up`);}catch(error){// 触发错误事件this.emitEvent('error',{ error });throw error;}}/** * 触发事件 */privateemitEvent(type:'initialize'|'start'|'stop'|'cleanup'|'error',data: Recordstring,any>):void{const event: PluginLifecycleEvent ={type,pluginName:this.name,data:{stage:this.stage,timestamp:newDate(),...data }};this.eventManager.emit(event);}/** * 注册事件监听器 */on(eventType:string, listener: PluginEventListener):void{this.eventManager.on(eventType, listener);}/** * 移除事件监听器 */off(eventType:string, listener: PluginEventListener):void{this.eventManager.off(eventType, listener);}}

21.2.5 生命周期钩子#

钩子定义#

typescript
复制
```typescript /** * 插件生命周期钩子 */ export interface PluginLifecycleHook { /** * 钩子名称 */ name: string; /** * 钩子阶段 */ stage: PluginLifecycleStage; /** * 钩子函数 */ hook: (context: PluginContext) => Promise; /** * 优先级 */ priority?: number; } ```### 钩子管理 /** * 插件钩子管理器 */exportclassPluginHookManager{private hooks: MapPluginLifecycleStage, PluginLifecycleHook[]>=newMap();/** * 注册钩子 */register(hook: PluginLifecycleHook):void{if(!this.hooks.has(hook.stage)){this.hooks.set(hook.stage,[]);}const hooks =this.hooks.get(hook.stage)!;hooks.push(hook);// 按优先级排序hooks.sort((a, b)=>(b.priority ||0)-(a.priority ||0));}/** * 执行钩子 */asyncexecute(stage: PluginLifecycleStage, context: PluginContext):Promisevoid>{const hooks =this.hooks.get(stage);if(!hooks){return;}for(const hook of hooks){try{await hook.hook(context);}catch(error){console.error(`Hook ${hook.name} failed:`, error);}}}/** * 移除钩子 */unregister(name:string):void{for(const hooks ofthis.hooks.values()){const index = hooks.findIndex(h => h.name === name);if(index >-1){hooks.splice(index,1);}}}}

钩子集成#

typescript
复制
```typescript // src/plugin.tsimport{ PluginHookManager, PluginLifecycleHook }from'@claude-code/plugin-sdk'; exportclassPluginimplementsIPlugin{private hookManager: PluginHookManager =newPluginHookManager(); /** * 注册生命周期钩子 */registerLifecycleHook(hook: PluginLifecycleHook):void{this.hookManager.register(hook);} /** * 初始化插件 */asyncinitialize(config: PluginConfig):Promisevoid>{// 执行初始化前钩子awaitthis.hookManager.execute(PluginLifecycleStage.INITIALIZED,{ plugin:this, config }); // ... 初始化逻辑 // 执行初始化后钩子awaitthis.hookManager.execute(PluginLifecycleStage.INITIALIZED,{ plugin:this, config });} /** * 启动插件 */asyncstart():Promisevoid>{// 执行启动前钩子awaitthis.hookManager.execute(PluginLifecycleStage.RUNNING,{ plugin:this}); // ... 启动逻辑 // 执行启动后钩子awaitthis.hookManager.execute(PluginLifecycleStage.RUNNING,{ plugin:this});} /** * 停止插件 */asyncstop():Promisevoid>{// 执行停止前钩子awaitthis.hookManager.execute(PluginLifecycleStage.STOPPED,{ plugin:this}); // ... 停止逻辑 // 执行停止后钩子awaitthis.hookManager.execute(PluginLifecycleStage.STOPPED,{ plugin:this});}}