Borrowing it
Nothing to install: this file belongs to VOD-Studio/violet. Take a copy, put it at the same path in your own repository, and replace the rules that are about this project with yours.
curl -O https://raw.githubusercontent.com/VOD-Studio/violet/release/2.0/.agents/skills/frontend-conventions/SKILL.mdgit clone --depth 1 https://github.com/VOD-Studio/violetWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/vod-studio/violet/frontend-conventions)<a href="https://agentmods.dev/skills/vod-studio/violet/frontend-conventions"><img src="https://agentmods.dev/badge/skills/vod-studio/violet/frontend-conventions/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/skills/vod-studio/violet/frontend-conventions"><img src="https://agentmods.dev/badge/skills/vod-studio/violet/frontend-conventions.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00053 | $0.02282 |
| Opus 5.5 | $0.00021 | $0.00913 |
| Sonnet 5.5 | $0.00011 | $0.00456 |
| Haiku 4.5 | $0.00005 | $0.00228 |
Grade A, and why
frontend-conventions scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2mo ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 145 lines — stays where its author put it; the contents beside it link to each section on GitHub.
前端编码纪律
落笔前查重
写任何新 util / hook / 通用组件前,先搜同款,命中即复用:
- shared 层(
lib//ui/等,项目公共能力所在)。 - 本 feature 已有文件。
- 兄弟 feature——有近似实现而确实需要复用时,先把它上提到公共层(独立提交),再在新 feature 接入;两边各复制一份是最后选项。
新建前不存在同款才动笔;搜过但不确定算不算同款时,把候选列给用户。
文件落位
| 场景 | 落位 |
|---|---|
| 单 feature 私有工具 | feature 根的 lib/ 或 utils/(与兄弟 feature 既有命名对齐,grep 确认) |
| 单 feature 私有 hook | feature 根的 hooks/ |
| 复合组件的辅件 | 该组件目录内 components/ hooks/ utils/ 子目录 |
| 跨 feature 复用 | 公共层;先上提(独立提交)再接入 |
- 组件目录建
utils/hooks/子目录的门槛是「多文件复合体」;一两个文件平铺在组件旁,建了空目录结构就是堆砌。 - feature 私有内容禁止先放进公共层「备用」;公共化的触发条件是第二个消费方真实出现。
TS 注释规范
导出符号用 TSDoc 标准形态:首行一句话说明用途,@typeParam / param / returns / example 标签,example 可运行:
/**
* 服务端分页表格 Hook,管理分页状态并组装 pagination。
*
* @typeParam T - 列表项数据类型
* @param useList - 模块的列表查询 Hook
* @param baseQuery - 业务筛选参数,省略时查全部
* @returns 查询结果 + pagination,供 DataTable 直接消费
*/
头注释禁写(判定:删掉后调用方损失信息吗?不损失即删):
- 动机叙述:「本 hook 消除 7 个子页重复的样板」——为什么写它,属于 PR 描述。
- 历史论证:「原单一全量 query 有竞态,已拆为 X」——演进过程,属于 commit/ADR。
- 被否决方案对比:「IntersectionObserver 方案在边界会丢选中」——要写就压缩成一句「为什么不用 X」。
- @param 复读签名:类型与参数名已表达的不再用文字重述。
保留与提倡:
- 魔法值理由:值旁一句为什么是这个数(行尾或行上)。
- 行内陷阱注释:函数体内非显然的坑(为什么解构某个引用、为什么豁免某条 lint 依赖)——这是头注释该让位给它的部分。
- 编排契约:签名看不出的数据流顺序(「读配置 → 回填 → 提交部分字段」),一行。
interface 字段只在非自解释时加行上注释;组件内部私有函数默认不注释,非显然时一句。
API client / query hooks 注释特例
这两类函数天然自解释:函数名 = 操作,参数类型 = 请求,返回类型 = 响应,下一行代码就是协议与路径。默认不写头注释,只补签名外的语义,且不带函数名前缀:
// ✅ 语义写首行正文;取值约束、前置状态用标签或箭头式陈述
/**
* 审核通过。rejected 是改判,即该链接曾被拒绝。
*/
export const useApproveFriendLink = ...
/**
* 待审核数量。
*
* @remarks 消费方是后台导航角标,轮询间隔 60s。
*/
export const usePendingFriendLinkCount = ...
// ❌ 复读:函数名 + 「调 GET /admin/friend-links」全在签名与实现里
/** listFriendLinks - 调 GET /admin/friend-links(按状态筛选,分页) */
标签使用约定:
@remarks——次要语义(消费场景、缓存行为),首行装不下的放这。@default——默认值语义(@default 出现时加载),而非括号里写「默认 false」。@defaultValue同义,项目内统一用@default。- 状态机转换(
pending → rejected)直接写箭头式陈述,这是状态描述不是括号补语。 @param/@returns保持;自解释参数不写,写了就必须有签名外信息。
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 2mo ago First seen · 145 lines · 53 tokens per session scan A ccccfe69c59e
frontend-conventions is a skill published in the GitHub repository VOD-Studio/violet (4 stars, last pushed yesterday), licensed MIT. It adds 53 tokens to every session and 2,282 once invoked, about $0.0002 per session on Opus 5.5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.
frontend-conventions compared with skills from other repositories
| Mod | Type | Stars | Last push | Licence | Scan | Tokens | Works with |
|---|---|---|---|---|---|---|---|
| frontend-conventionsVOD-Studio/violet | Skill | 4 | yesterday | MIT | A | 53 | Claude Code, Codex |
| audit-network-securitygordcurrie/unifi-mcp | Skill | 2 | 15d ago | MIT | A | 81 | Claude Code, Codex |
| unifi-networkgordcurrie/unifi-mcp | Skill | 2 | 15d ago | MIT | A | 111 | Claude Code, Codex |
| dark-memoryOpita-Code/dark-memory-mcp | Skill | 1 | 4d ago | none | A | 353 | Claude Code, Codex |
| vibe-loop-gitOpita-Code/dark-memory-mcp | Skill | 1 | 4d ago | none | A | 0 | Claude Code, Codex |
| opencodeOpita-Code/dark-memory-mcp | Skill | 1 | 4d ago | none | A | 0 | Claude Code, Codex |
| claude-codeOpita-Code/dark-memory-mcp | Skill | 1 | 4d ago | none | A | 0 | Claude Code, Codex |