它不只是换头像:面板、状态栏、事件钩子、提示词改写、工具拦截与自动化测试,都能运行在Claude Code进程内部。
先说预测:Claude Code Mods最有价值的地方,不是给终端换一套皮肤,而是让开发者开始构建真正贴在Agent执行链上的交互与安全层:看见工具在做什么、在危险操作前阻断、把状态展示给用户,并用测试证明规则确实生效。
这次公开实测做了一个“雨姐工位”:她坐在Claude Code右侧面板,记录命令、文件修改和报错;测试失败会变脸,任务完成会弹提示,遇到危险删除和强制改写则在执行前拦下。

它看起来像趣味皮肤,底层却展示了Claude Code Mods的完整能力:Pane面板、AbovePrompt提示条、状态栏、toast、自定义命令、状态管理、prompt.compose和tool.call。
01 / 先搞清楚:Mod不是Skill,也不是MCP

| 扩展方式 | 主要作用 | 运行位置 |
|---|---|---|
| Skill | 给Claude可复用的说明、流程和资源 | 作为上下文与工作方法 |
| MCP | 连接外部工具、数据和服务 | 独立服务或连接器 |
| 传统Hooks | 在固定时机执行外部命令 | Claude Code进程之外 |
| Mods | 参与事件链并直接渲染界面 | Claude Code进程内部 |
Mods运行时会持续产生事件:会话开始是session.start,提交提示词是prompt.submit,工具准备执行是tool.call,界面渲染是ui.render,一轮结束是turn.complete。开发者把函数挂到这些事件上,就能观察、改写或接管流程。
02 / 第一步:创建最小Mod和“雨姐工位”
示例的核心结构只有三个文件:
yujie/
├── .claude-plugin/
│ └── plugin.json
└── hooks/
├── hooks.json
└── register.tsx
hooks.json负责声明模块:
{ "modules": ["./register.tsx"] }
register.tsx导出注册函数,在会话启动时注册命令、写状态栏并打开面板;界面渲染时把台词画到输入框上方:
export const register: Register = on => {
on('session.start', async ($, e, next) => {
await $.command.register({ name: 'yujie', description: '打开雨姐工位面板' })
$.ui.status('雨姐在岗 · 铁锅已热')
$.ui.open({ id: 'yujie', title: '雨姐工位' })
return next(e)
})
on('ui.render', { component: 'AbovePrompt' }, async ($, e) => {
const { Box, Text } = $.ui.resolve(e)
return <Box><Text color="#e0567a">雨姐:</Text><Text>{await read($, line)}</Text></Box>
})
}

开发时可将Mod放在会话专属开发目录中启用热重载,也可以使用claude --plugin-dir ./yujie加载本地目录。原作者测试时使用Claude Code v2.1.287以上;Mods属于早期接口,实际版本要求应以当前官方仓库和本机类型定义为准。
03 / 第二步:用Raster把像素头像搬进终端
终端无法像网页那样随意显示图片,Raster使用“▀”上半块字符和前景色、背景色,把一个字符格拆成上下两个像素。每格的数据由字符、上半像素颜色和下半像素颜色组成。
words[at] = 0x2580
words[at + 1] = top
words[at + 2] = bottom

实践中要特别注意终端色彩。tmux或某些终端会降为256色,Raster还可能压缩颜色通道,深棕和暗红容易偏成绿色或橄榄色。最稳妥的做法是直接按终端可用色板设计大颗粒、少颜色的像素图,并让不同表情保持相同构图尺寸,避免面板跳动。
04 / 第三步:tool.call的三种能力
Claude准备运行命令或修改文件时,会先经过tool.call。Mod可以做三件事:
- 旁观:调用
next(e)原样放行,只记录结果、更新计数和表情。 - 改写:调用
next({...e}),修改事件后继续执行。 - 接管:不调用
next,直接返回deny或自定义结果。
最基础的旁观钩子可以在命令结束后读取结果,测试失败就切换表情并弹出通知:
on('tool.call', { tool: 'Bash' }, async ($, e, next) => {
const ran = await next(e)
if (ran.isError || /fail [1-9]/.test(ran.text ?? '')) {
await say($, 'angry', '又红了,先看看日志')
$.ui.toast('雨姐:测试报错了')
}
return ran
})

这里有一个很实用的坑:npm test 2>&1 | tail -40的最终退出码可能来自tail,即使前面的测试失败,工具仍可能看起来成功。生产实现应优先保留原始退出码,例如启用pipefail,不要只靠输出文本中的“fail 1”判断。
05 / 第四步:用prompt.compose切换“东北话模式”
斜杠命令/yujie-talk可以切换一个状态,再由prompt.compose向系统提示词追加风格要求。这样用户原始输入不会被改写,关闭后下一轮也不再携带方言要求。
on('prompt.compose', async ($, e, next) => {
const composed = await next(e)
if (!(await read($, isDialect))) return composed
return {
...composed,
sections: [...composed.sections, {
id: 'yujie:dialect',
text: DIALECT,
scope: 'session'
}]
}
})

这种做法不仅能做趣味口吻,也可用于团队规范:要求回答包含风险、测试结果、变更文件和回滚方法。但系统提示词改写会影响模型行为,应在界面上明确展示当前模式,避免用户不知道Agent为何突然改变表达。
06 / 第五步:在危险命令真正执行前接管
演示中对删除、强推和硬重置设置了阻断规则。命中时不调用next,工具不会执行,拒绝原因会回到Claude上下文,让模型沿着安全规则继续寻找替代方案。
if (DANGER.test(e.command)) {
$.ui.toast('雨姐:危险命令,先别执行')
return {
deny: '这条命令可能删除或强行改写数据。请换一个更安全的做法,或者让用户确认后自行执行。'
}
}

安全边界:简单正则不是权限系统。rm -r -f、脚本包装、变量展开和其他等价写法都可能绕过字符串匹配。真正的安全Mod应解析命令结构、评估文件范围、阻断符号链接与路径逃逸,并在高风险步骤显示“继续/取消”确认。
07 / 第六步:验证源码,再用事件测试证明没有真执行
claude plugin validate会静态读取清单和源码,列出注册的事件及调用接口。建议发布前加严格模式,并修复全部警告。但静态检查只能告诉你“写法大致合法”,不能证明运行时行为一定正确。
自动化测试的关键是设置一个计数器:如果危险命令被正确拒绝,真正的工具处理器一次都不应运行。
test('dangerous delete is denied before the tool runs', async ($, on) => {
let ran = 0
on('tool.call', () => {
ran += 1
return { result: { stdout: '', stderr: '', interrupted: false } }
})
const answer = await $.tool.call({ tool: 'Bash', command: 'rm -rf node_modules' })
expect(answer.deny).toContain('删除或强行改写数据')
expect(ran).toBe(0)
})
还应补测普通命令正常放行、模式开关可恢复、状态变化触发渲染,以及claude -p等无界面环境。示例就发现过一个问题:阻断命令时尝试拉起面板,在无UI测试环境会报错,最终通过捕获界面调用异常解决。
08 / 从业者观点:最值得做的不是角色皮肤,而是“可见的安全闸”
趣味角色让Mods容易传播,但真正有生产价值的方向是:
- 把Agent正在执行的命令、文件、测试和权限状态做成可见面板;
- 对删除、覆盖、强推、发布和凭证操作设置影响范围评估;
- 在规则阻断后给Claude结构化原因,让它自动选择更安全的替代方案;
- 把团队编码规范、发布检查和审计信息做成可测试的运行时策略。
我们的判断:Mods把Claude Code从“可配置的Agent”推向“可编程的Agent宿主”。但它越靠近工具执行链,插件代码的权限与风险就越高。安装第三方Mod前必须审查源码、固定版本、查看它监听的事件和调用的接口,并在隔离项目中测试。
官方资料与站内延伸
Claude Code Mods站内导航:
https://www.zuoshipin.com/link/47313.html
Anthropic官方Mods目录:
https://github.com/anthropics/claude-code/tree/main/mods
Anthropic站内导航:
https://www.zuoshipin.com/link/1191.html
站内Codex插件生态观察:
https://www.zuoshipin.com/article/33506
站内Claude与Codex效率工具合集:
https://www.zuoshipin.com/article/31931






