gmira
21 Claude Code skills for building web interfaces that do not look AI-generated. Written visual direction first, 7 shadcn registries (514 components), a GPU floor for WebGL, Playwright acceptance across 5 viewports.
Package details
Install gmira from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:gmira- Package
gmira- Version
0.1.0- Published
- Aug 3, 2026
- Downloads
- 126/mo · 126/wk
- Author
- ahmad_othman_adi
- License
- MIT
- Types
- skill
- Size
- 593.3 KB
- Dependencies
- 0 dependencies · 0 peers
Pi manifest JSON
{
"skills": [
"skills/gmira-a11y/SKILL.md",
"skills/gmira-arsenal/SKILL.md",
"skills/gmira-brief/SKILL.md",
"skills/gmira-canvas/SKILL.md",
"skills/gmira-catalog/SKILL.md",
"skills/gmira-detail/SKILL.md",
"skills/gmira-direction/SKILL.md",
"skills/gmira-flow/SKILL.md",
"skills/gmira-hero/SKILL.md",
"skills/gmira-motion/SKILL.md",
"skills/gmira-nav/SKILL.md",
"skills/gmira-palette/SKILL.md",
"skills/gmira-perf/SKILL.md",
"skills/gmira-proof/SKILL.md",
"skills/gmira-scroll/SKILL.md",
"skills/gmira-ship/SKILL.md",
"skills/gmira-slop/SKILL.md",
"skills/gmira-states/SKILL.md",
"skills/gmira-typeset/SKILL.md",
"skills/gmira-verify/SKILL.md",
"skills/gmira/SKILL.md"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
简体中文 | English
问题在哪
让任何一个编码 agent 做个网站,出来的都是同一个页面。卡片网格、渐变标题、每个板块头上顶一行加了字间距的大写小标题、居中首屏配两个按钮。做得没错,可以互换,也记不住。
常规解法是换一套更好的组件库。这条路走不通,而且有截图为证。
证据 A:给了一套刻意压暗的配色,组件当没看见
从 514 个组件的军火库里第一次安装。一个 WebGL 首屏组件,配色给的是近黑、深绿、金。给汽车经销商用的克制暗色首屏。

彩虹涂抹。正中间焊着一个过曝的白盘。控制台零报错,所以组件“跑通了”。配色根本没有到达像素。
原因在着色器里,读一遍源码就清楚。整支着色器有九层:配色只在第 2 层生效一次,后面六层直接往颜色上加,中间不做任何归一化,只有最后一行做了 clamp。最狠的是一处辉光,在 clamp 之前每个通道大约加了 +1.84,不管配色是什么,出来都是白的。这处辉光的位置和强度写死在 uniform 块里,而且每一帧都重新赋值,没有任何 prop 能碰到它。组件自己的源码注释里写着 “VISIBLE Mouse interaction”,但它从头到尾没接过鼠标。
证据 B:改四行之后

同一个组件,同一份需求,同一组配色 prop。补丁做的事是把那个焊死的常量提成 prop,并且默认关掉。
注册表里的组件是一台引擎,不是一份设计。它的默认值是为了赢下五秒的展示 GIF,而这种展示 GIF 就是新的套路。 2026 年的彩虹 WebGL 团块,坐的正是 2021 年紫色 CSS 渐变的那个位置。
完整记录见 research/FINDING-01-tame-the-arsenal.md。
它做什么
输出显得套路,不是能力问题,是回避决策的问题。模型对设计选项的排序,是它自身先验的确定性函数,所以让它“有创意一点”没有用:这条指令会被它本来要纠正的那个东西拿去评判。
只有外部指派能打败先验。所以 GMIRA 先把决策逼出来,再给执行决策的材料。
1 BRIEF 事实是什么,给谁看,内容到底是什么
2 DIRECTION 一份 5 段式方向契约,写成文字,在放下任何元素之前
3 BUILD 用军火库里的组件搭页面,先修复,再驯服
4 GATE 套路审计、无障碍、性能,最后用眼睛看真实截图
第 2 步成本是 150 个字,差别全在这里。契约有五段,外加一条可证伪性测试:
THESIS 一句话:这个页面在主张什么
OWN-WORLD 它借用的那个物质世界,要指名道姓
STORY 从首屏到最后一屏之间发生了什么变化
FIRST VIEWPORT 滚动之前屏幕上有什么,用名词写
FORM 结构性决策:页面是怎么搭起来的,而不是它感觉如何
如果某一段读起来像一种情绪,那方向就还没定下来。“高端、现代”是情绪。“1970 年代保时捷零件目录:等宽字体的零件号、发丝线分隔、照片压在中性色卡纸上、任何地方都不用圆角”才是方向。
物质世界是按外部索引抽出来的,不是挑出来的。指派,而不是选择。方向技能抽取的目录里有 40 个物质世界。
安装
把技能复制进 Claude Code 的技能目录:
git clone https://github.com/OthmanAdi/gmira.git
cp -r gmira/skills/* ~/.claude/skills/
也可以从 npm 安装(gmira,一个包带全 21 个技能):
pi install npm:gmira
然后把组件注册表接进项目的 components.json:
{
"registries": {
"@componentry": "https://componentry.dev/r/{name}.json",
"@canvas-ui": "https://canvasui.dev/r/{name}.json",
"@bklit": "https://ui.bklit.com/r/{name}.json",
"@ncdai": "https://chanhdai.com/r/{name}.json",
"@kibo-ui": "https://kibo-ui.com/r/{name}.json",
"@react-bits": "https://reactbits.dev/r/{name}.json",
"@soundcn": "https://soundcn.xyz/r/{name}.json"
}
}
7 个注册表共 514 个组件,全部验证可达。用 npx shadcn@latest mcp init 接上 shadcn MCP,agent 就能在这 7 个注册表里搜索和安装。
依赖保持轻。framer-motion、lenis、lucide-react 三个就覆盖了所有非 three.js 组件,包括四个纯 WebGL 首屏组件,因为纯 WebGL 不需要任何库。three.js 大约 600 KB,只有当某个具体组件确实值这个体积时才装。
输入 /gmira 让路由技能分派,也可以直接调用其中任何一个。
21 个技能
一个路由技能加二十个,每一个都是可以单独调用的技能,各自带一份 SKILL.md。
决策
| 技能 | 什么时候用 |
|---|---|
gmira-brief |
任何事情的开头。抽出产品事实、模式,以及真实的内容模型。 |
gmira-direction |
5 段式方向契约,带一整套反默认机制。这一步之前不动手。 |
gmira-palette |
色彩世界。有承诺的配色策略,主色覆盖 30% 到 60% 的表面,对比度实测。 |
gmira-typeset |
排版语气。行宽、字号级差、字间距,以及等宽字体到底允许表示什么。 |
构建
| 技能 | 什么时候用 |
|---|---|
gmira-hero |
首屏。管着效果预算和第 0 帧问题。 |
gmira-scroll |
滚动编排:钉住、scrub、倾斜、揭示。只留一个被设计过的时刻。 |
gmira-catalog |
任何一组东西:库存、商品、课程、创意墙。反卡片网格的那个技能。 |
gmira-detail |
单个东西的深度页:商品详情页、车辆详情页、课程页。参数表和变体状态。 |
gmira-flow |
多步流程:结算、报名、金融试算、预约、申请。 |
gmira-proof |
口碑、成果、logo 墙、案例,并且一个都不编。 |
gmira-nav |
页头、命令面板、页脚,以及承载整个世界的那层外壳。 |
手艺
| 技能 | 什么时候用 |
|---|---|
gmira-arsenal |
安装任何注册表组件时。跑修复与驯服流程。不可跳过。 |
gmira-canvas |
写或者审 canvas 与 WebGL 的活。GPU 底线归它管。 |
gmira-motion |
挑选并做出那一个被设计过的动效时刻。 |
gmira-states |
悬停、焦点、禁用、加载、错误、空态。最常被跳过的六个。 |
验收
| 技能 | 什么时候用 |
|---|---|
gmira-slop |
审查检测器抓不到的视觉痕迹。交给用户之前先跑。 |
gmira-a11y |
对比度、焦点顺序、语义化、canvas 兜底后的可读性。 |
gmira-perf |
帧预算、包体积、DPR 上限、GPU 销毁。 |
gmira-verify |
Playwright 跑五个视口,然后用你自己的眼睛读截图。 |
gmira-ship |
构建、暂存、发布。没有明确指令绝不部署。 |
另外还有五份垂直行业参考手册(汽车经销商、电商、应用型 AI 工程学院、GTM 与 UGC 投放学院),以及一份 40 个物质世界的目录。
三条由构建验证出来的定律
不是从风格指南里抄来的。这三条是把军火库装上、看渲染结果得出来的。
- 注册表里的组件是一台引擎,不是一份设计。 它的默认值是为了赢下五秒的展示 GIF。装进来就当场驯服,一口气做完。用之前先 grep 焊死的常量:某个东西明明有 prop,另一处却有个硬编码值每帧把它覆盖掉。
- 军火库到手就是坏的。 componentry 的 56 个组件里,12 个的
cn导入路径根本解析不了,10 个引用了自己没声明的包。写页面之前先修。 - 一个效果必须在第 0 帧、没有任何输入的时候就站得住。 指针驱动的效果,在大多数访客真正看到的那个状态里等于不存在。展示 GIF 永远不会暴露这一点,因为录制的人手已经在动鼠标了。
GPU 底线
这套库学得最多的那个设计技能,为字体、色彩、布局、动效都给了数值底线,唯独 GPU 这块没有。它自己的差距分析里就是这么写的。下面这些是我们补的。
| 检查项 | 底线 |
|---|---|
| 帧预算 | 60fps 下一共 16.7ms,效果层最多占 8ms。要测,不要估 |
| 像素比 | 全屏背景封顶 1.5,局部区域封顶 2.0。绝不直接把原始 devicePixelRatio 传进去 |
| 精度 | 桌面端 highp,移动端 mediump,显式声明,不吃默认值 |
| 模拟网格 | 全屏时 sim grid 不超过 128,显示纹理不超过 512 |
| 上下文丢失 | 必须监听 webglcontextlost 并写恢复路径 |
| 销毁 | 必须暴露并调用显式的 destroy()。浏览器同时存活的上下文大约只有 16 个,泄漏不会报错,只会让之后每一个 canvas 静默失效 |
| 离屏 | IntersectionObserver 离开视口时暂停,visibilitychange 隐藏时也暂停 |
| 减少动态效果 | prefers-reduced-motion 时冻结在一帧你亲眼挑过的静帧上,而不是 t=0 |
| 首帧 | 内容之后再挂载。绝不让首次内容绘制卡在着色器编译上 |
| 失败态 | 把 canvas 元素整个删掉,页面说的每一句话仍然读得到 |
性能在这里被当作一种设计材料,不只是约束。加载时间、首帧时间、发热表现都有肉眼可见的后果,所以它们是决策。
验收
gmira-verify 用 Playwright 跑 1920x1080、1440x900、1024x768、834x1112、390x844 五个视口。它测计算后的对比度、文本溢出、行宽、字间距、逐个元素真实聚焦之后的焦点样式、标题层级顺序,以及 canvas 的 DPR。它写出截图和一份报告。
它做不了判断,而且它自己就是这么说的。最后一道关是 G10:截图被 agent 亲眼读过,并且把发现写了下来。
它强制执行的其中一条方法,单独拿出来也值得抄。当你手上同时有一个确定性检查器和一次判断性审阅时,先做判断,而且要隔离着做,否则检查器的输出就成了判断的天花板。先看截图,写下你看到了什么,再去打开报告。报告读完之后,那第一眼就再也拿不回来了。
四份实证
四个垂直行业,全部经由这套库构建,每一个都按外部哈希索引抽出自己的物质世界,而不是凭偏好挑。同一套技术栈,同一批技能,四个页面彼此之间没有任何相似之处。
| 垂直行业 | 抽中的物质世界 | 它改变了什么 |
|---|---|---|
| 汽车经销商 | 工业设备拍卖图录 | 库存变成了拍品清单。车况等级取代价格成为组织页面的那一列。事故与损伤报告成了页面上最强的物件,而不是垫在底部的一句道歉 |
| 应用型 AI 工程学院 | 车间流转卡(随工单) | 课程表变成一条九道工序的工艺路线,每道工序带一枚盖了章的验收标准,付款之前就能完整读到 |
| GTM 与 UGC 投放学院 | 拳赛节目单与垫场赛 | 每一条广告都按一场拳赛来排位,包括亏钱的那条。垫场赛部分的字号是按每周产出量算出来的 |
| 商店 | 种子袋货架融合染坊色卡 | 商品挂在导轨上,而不是摆在网格里。每个颜色都带一个耐光牢度数值,画成八个填色方块 |
下面每一张都是 lab/ 里的真实截图,由 scripts/shot.mjs 在同一天、同一尺寸、同一套技能库下拍出来的。没有一张是效果图。
汽车经销商抽到索引 0,工业设备拍卖图录。没有首屏大图。没有卡片。没有渐变。拍品编号用等宽字体,车况等级做成旋转的印章,价格印成落槌估价,全页只有一种 0.5px 的横线粗细。
商店抽到的是 Operate 模式,所以它的特效预算接近零,全程没有装任何一个 WebGL 组件。这份实证的存在,就是为了证明这套库知道什么时候该收手。
十道关在五个视口上全绿,上面每一条路由都是。
常见问题
为什么 AI 生成的落地页都长一个样?
因为什么都没定。一个没有承诺过方向的 agent 只会去够中位数,而中位数渲染成 HTML 就是卡片网格、渐变标题、每个板块头上一行小标题、居中首屏配两个按钮。换一套更唬人的组件库只是把问题挪了个地方。GMIRA 要求在放下任何元素之前先写一份 5 段式方向契约,而且契约里那个物质世界是按外部索引抽的,模型自己的先验够不着。
为什么我传的配色,shadcn 或者 WebGL 组件根本不认?
多半是焊死的常量。注册表组件常常一边给了 prop,一边在别处有个硬编码值每帧把它覆盖掉;而且叠加式的着色器根本没法尊重一套暗色配色:两次以上的 col += ... 中间不做归一化,结果一定趋向白色。验证方式是拿渲染出来的像素跟源配色的十六进制值比对,绝不能只信 prop 的名字。gmira-arsenal 会对每一次安装跑一遍修复与驯服。
它是要替掉我的组件库吗?
不是,它压在组件库上面。GMIRA 接了 7 个 shadcn 注册表共 514 个组件,并且把每一个装进来的组件都当成一台待修待驯的引擎,而不是一份成品设计。shadcn 把源码复制进你的仓库,本来就是为了让你改它。
怎么确认页面是真的无障碍、真的不卡,而不只是 lint 通过?
gmira-verify 跑五个视口,读的是计算后的真实值而不是假定值:对比度取自 computed style,焦点样式靠逐个元素真实聚焦之后再读,另外还有文本溢出、行宽、字间距、标题层级顺序和 canvas DPR。GPU 底线补的是任何无障碍 lint 工具都没有的几项:上下文丢失处理、显式销毁、离屏暂停、把减少动态效果当成彻底的关闭开关,以及删掉 canvas 元素之后页面仍然可读。
它假设什么技术栈?
Next.js 16、React 19、Tailwind v4、shadcn v4,以及用于注册表搜索和安装的 shadcn MCP。教义、手艺底线和 GPU 底线本身不依赖技术栈,安装命令和注册表配置依赖。
每个技能一张样张
二十张样张,每个技能一张,全部由这套库自己构建,按同一尺寸拍摄。每一张都刻意做成不同的印刷世界:如果它们长得都一样,这套库就在自己的文档里推翻了自己的主张。源码在 lab/src/app/specimen/。
站在谁的肩膀上
研究过,并致谢:pbakaus/impeccable 提供了品味引擎与反默认机制,DavidHDev/canvas-ui 提供了 html-in-canvas 的技法,bklit/bklit-ui 提供了图表构成与技能打包方式,ncdai/chanhdai.com 提供了结构层面的手艺,componentry 提供了军火库。
他们的技法被提取到了 research/ 里,附带该抄什么、以及往前还能走到哪。
许可证
MIT。
作者: Ahmad-Othman Adi