OmX插件开发指南:从零开始创建你的第一个Hook

张开发
2026/4/16 22:57:18 15 分钟阅读

分享文章

OmX插件开发指南:从零开始创建你的第一个Hook
OmX插件开发指南从零开始创建你的第一个Hook【免费下载链接】oh-my-codexOmX - Oh My codeX: Your codex is not alone. Add hooks, agent teams, HUDs, and so much more.项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-codexOmXOh My CodeX是一个强大的CodeX CLI工作流增强工具它提供了丰富的插件扩展系统让你可以自定义自动化工作流。本文将为你详细介绍如何从零开始创建你的第一个OmX Hook插件实现个性化的事件响应和自动化任务。为什么需要OmX插件开发OmX插件系统允许开发者扩展和自定义CodeX工作流通过监听各种事件如会话开始、任务完成、工具使用等来触发自定义逻辑。这种扩展性让OmX能够适应各种复杂的开发场景从简单的通知提醒到复杂的自动化工作流。OmX插件核心架构OmX的插件系统采用事件驱动架构主要包含以下组件事件分发器src/hooks/extensibility/dispatcher.ts- 负责将事件分发给所有注册的插件插件加载器src/hooks/extensibility/loader.ts- 自动发现和加载插件插件SDKsrc/hooks/extensibility/sdk.ts- 提供丰富的API供插件使用事件系统src/hooks/extensibility/events.ts- 定义事件类型和构建函数快速开始创建第一个Hook插件步骤1初始化插件目录首先使用OmX CLI创建插件脚手架omx hooks init这个命令会在你的项目根目录下创建.omx/hooks/sample-plugin.mjs文件这是插件的基础模板。步骤2理解插件结构查看生成的示例插件文件export async function onHookEvent(event, sdk) { if (event.event ! turn-complete) return; const current Number((await sdk.state.read(sample-seen-count)) ?? 0); const next Number.isFinite(current) ? current 1 : 1; await sdk.state.write(sample-seen-count, next); await sdk.log.info(sample-plugin observed turn-complete, { turn_id: event.turn_id, seen_count: next, }); }这个简单的插件会监听turn-complete事件统计事件触发次数并记录日志。步骤3验证插件配置运行以下命令检查插件是否正确配置omx hooks status # 查看插件状态 omx hooks validate # 验证插件导出 omx hooks test # 测试插件响应OmX插件开发核心概念事件类型详解OmX支持多种事件类型主要分为两大类原生事件Native Eventssession-start- 会话开始session-end- 会话结束turn-complete- 回合完成session-idle- 会话空闲派生事件Derived Eventsneeds-input- 需要用户输入pre-tool-use- 工具使用前post-tool-use- 工具使用后SDK功能概览OmX插件SDK提供了强大的功能集// TMUX操作 await sdk.tmux.sendKeys({ text: echo Hello from plugin!, submit: true }); // 日志记录 await sdk.log.info(插件执行成功, { data: some data }); await sdk.log.warn(警告信息); await sdk.log.error(错误信息); // 状态管理 await sdk.state.write(my-key, my-value); const value await sdk.state.read(my-key); await sdk.state.delete(my-key); const allData await sdk.state.all(); // OMX运行时状态读取 const session await sdk.omx.session.read(); const hud await sdk.omx.hud.read();实战案例创建智能通知插件让我们创建一个实用的通知插件当任务完成时发送通知export async function onHookEvent(event, sdk) { // 只处理任务完成事件 if (event.event ! turn-complete) return; // 获取任务信息 const taskName event.context?.task_name || 未知任务; const duration event.context?.duration_ms || 0; // 记录到状态 const completionCount Number((await sdk.state.read(completion-count)) ?? 0) 1; await sdk.state.write(completion-count, completionCount); await sdk.state.write(last-completed-task, taskName); // 发送TMUX通知 await sdk.tmux.sendKeys({ text: echo 任务完成: ${taskName} (耗时: ${duration}ms), submit: true }); // 记录详细日志 await sdk.log.info(任务完成通知已发送, { task: taskName, duration: duration, total_completions: completionCount, timestamp: new Date().toISOString() }); // 每完成5个任务发送汇总通知 if (completionCount % 5 0) { await sdk.tmux.sendKeys({ text: echo 里程碑: 已完成 ${completionCount} 个任务!, submit: true }); } }高级插件开发技巧1. 错误处理最佳实践export async function onHookEvent(event, sdk) { try { // 你的插件逻辑 await processEvent(event, sdk); } catch (error) { // 记录错误但不中断其他插件 await sdk.log.error(插件执行失败, { error: error.message, stack: error.stack, event: event.event }); // 可以选择发送错误通知 await sdk.tmux.sendKeys({ text: echo ❌ 插件错误: ${error.message}, submit: true }); } }2. 性能优化建议export async function onHookEvent(event, sdk) { // 使用缓存避免重复计算 const cacheKey processed-${event.turn_id}; const alreadyProcessed await sdk.state.read(cacheKey); if (alreadyProcessed) { return; // 跳过已处理的事件 } // 标记为已处理 await sdk.state.write(cacheKey, true); // 设置过期时间24小时 setTimeout(async () { await sdk.state.delete(cacheKey); }, 24 * 60 * 60 * 1000); // 执行实际逻辑 await processEventLogic(event, sdk); }3. 插件配置管理// 配置管理插件 export async function onHookEvent(event, sdk) { // 读取插件配置 const config { enabled: await sdk.state.read(plugin-enabled) ?? true, notificationLevel: await sdk.state.read(notification-level) ?? info, maxRetries: await sdk.state.read(max-retries) ?? 3, }; if (!config.enabled) { return; // 插件被禁用 } // 根据配置级别处理事件 switch (config.notificationLevel) { case verbose: await handleVerbose(event, sdk); break; case info: await handleInfo(event, sdk); break; case error-only: if (event.event.includes(error) || event.event.includes(failed)) { await handleError(event, sdk); } break; } }调试和测试插件启用调试模式# 设置环境变量启用详细日志 export OMX_DEBUG_HOOKS1 export OMX_HOOK_PLUGIN_TIMEOUT_MS5000 # 运行测试 omx hooks test查看插件日志插件日志存储在.omx/logs/hooks-YYYY-MM-DD.jsonl文件中你可以使用以下命令查看tail -f .omx/logs/hooks-$(date %Y-%m-%d).jsonl性能基准测试插件开发最佳实践1. 保持插件轻量级避免在插件中执行长时间运行的任务使用异步操作避免阻塞事件循环合理使用缓存减少重复计算2. 遵循命名约定使用有意义的插件名称如notify-slack.mjs文件名使用小写字母和连字符确保插件ID在项目中唯一3. 错误处理和恢复所有操作都应该有错误处理插件失败不应该影响其他插件提供有意义的错误信息4. 状态管理使用sdk.state进行持久化存储定期清理过期数据避免存储大量数据在状态中常见问题解答Q: 插件如何禁用A: 设置环境变量OMX_HOOK_PLUGINS0或删除插件文件。Q: 插件超时时间如何调整A: 设置OMX_HOOK_PLUGIN_TIMEOUT_MS3000默认1500ms。Q: 如何在团队工作模式下使用插件A: 在团队工作模式下插件副作用默认被跳过避免重复执行。可以通过设置allowTeamWorkerSideEffectstrue启用。Q: 插件可以访问哪些系统资源A: 插件可以访问TMUX会话、文件系统通过状态存储、网络通过自定义模块等。进阶插件示例Git自动化插件export async function onHookEvent(event, sdk) { if (event.event turn-complete) { const task event.context?.task_name || ; // 检测到代码修改任务时自动提交 if (task.includes(代码修改) || task.includes(bug修复)) { await sdk.tmux.sendKeys({ text: git add ., submit: true }); await sdk.tmux.sendKeys({ text: git commit -m 自动提交: ${task}, submit: true }); await sdk.log.info(Git自动提交完成, { task: task, timestamp: new Date().toISOString() }); } } }总结OmX插件系统为开发者提供了强大的扩展能力让你可以根据自己的需求定制自动化工作流。通过本文的指南你应该已经掌握了✅ 如何创建和配置Hook插件✅ 理解事件系统和SDK API✅ 编写健壮的生产级插件✅ 调试和测试插件的最佳实践✅ 实际应用案例和进阶技巧开始你的OmX插件开发之旅吧通过创建自定义Hook你可以极大地提升开发效率实现真正个性化的自动化工作流。记住好的插件应该是简单、可靠且易于维护的。从简单的通知插件开始逐步扩展到更复杂的自动化场景你会发现OmX插件系统的强大之处提示查看官方文档docs/hooks-extension.md获取更多详细信息并参考src/hooks/extensibility/目录下的源代码来深入了解插件系统的内部实现。【免费下载链接】oh-my-codexOmX - Oh My codeX: Your codex is not alone. Add hooks, agent teams, HUDs, and so much more.项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-codex创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

更多文章