npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@wisdomgarden/torque-knowledge

v1.0.7

Published

Machine-readable knowledge artifact for @wisdomgarden/torque — component catalog (SQLite) and AI coding rules (Markdown). Consumed by CI code review and local AI tooling, not by application runtime.

Downloads

465

Readme

@wisdomgarden/torque-knowledge

这个包是给机器读的,不是给人读的。 人读的组件文档在 @wisdomgarden/torque-doc(文档站),组件本身在 @wisdomgarden/torque

它把组件库的知识打包成一个可发布、可版本寻址的 artifact,供两个消费端取用。 包里不含任何运行时代码,不要 import —— 没有 main / exports, 消费端是 npm pack 之后解包取文件。

产物

| 文件 | 给谁 | 是什么 | | --- | --- | --- | | dist/torque-components.md | ditinglms-web 的 CI code review) | 选型决策树 + 可用组件清单 + 硬约束 + 禁止事项。只有清单和策略,没有组件细节 —— 细节查 components.db。带 diting 认的 frontmatter(单行 keywords / globs),解包进它的 rule_dirs 就能被召回 | | dist/components.db | lms-web 的本地 MCP + diting | SQLite 组件目录,MCP search_component() 和 diting query_ui_components 共同的数据源。44 个组件的导出名(含 Combobox.InfiniteDropdown 这类点号子组件名)、英文描述、keywords 和完整 props | | dist/.meta.json | CI / 下游漂移检测 | { knowledge, torque, generatedAt } —— 这份知识是哪个版本、描述的又是哪个 torque 版本 |

版本与 @wisdomgarden/torque 相互独立

四个包各自独立版本号,这个包的 version 没有torque 相等的义务 —— [email protected] 描述 [email protected] 是完全正常的状态。

下游取的是 latestnpm pack @wisdomgarden/torque-knowledge@latest), 不经过 lockfile —— 因为把它装成 devDependency 会让 lms-web 的 base image (1642 个包)在每次知识更新时重建,而这个包有时只改了几句描述。

代价是版本对齐从「精确」降成「有窗口」,靠漂移检测兜住:dist/.meta.jsontorque 字段记着这份知识描述的是哪个版本,下游拿它和自己装的 torque 比对。 所以那个字段是必须的,不是锦上添花 —— 上游不落地 .meta.json, 下游的漂移检测就是恒静默的,不报错也不会有人发现。

构建

pnpm --filter @wisdomgarden/torque-knowledge build

dist/ 是构建产物,不入库。仓库根的 pnpm build 会自动带上这个包。

源与数据流

packages/torque/src/index.ts              ← 组件清单的唯一来源(不是 readdir)
packages/torque/src/components/*/readme.md ← 39 篇,props 和中文描述
packages/torque/src/provider/readme.md     ← 第 40 篇
src/fallback.json                          ← 全部 44 个组件的英文描述(手工维护)
src/handwritten/*.md                       ← 人工提炼的正文片段
        │
        └──> scripts/gen.mjs ──> dist/

机械的部分(扫源码、解析 props、产 db 和组件清单)在 gen.mjs 里,每次 pnpm build 都跑。需要判断力的部分(读懂 readme 提炼选型/约束、复核英文描述)在 .claude/skills/torque-knowledge/ 这个 skill 里。

scripts/check-changes.mjs 是两者之间的闸门:

node scripts/check-changes.mjs --check-only   # 只问「有活吗」,不写缓存、不生成
node scripts/check-changes.mjs                # 有变化就顺便重新生成

退出码是契约:0 有变化 / 1 无变化 / 2 有变化但生成失败。 --check-only 的意义是让调用方先判断要不要花一次 AI 调用 —— lms-web 实测 22 个生产日里 有 21 天没活干。缓存在 .cache/changes.json(gitignore)。

gen.mjscheck-changes.mjs 共用 scripts/lib/parse-barrel.mjs 解析组件清单。 别在任一个里重写一遍正则 —— 两份必然漂移,一个认得 StickyBox 另一个不认得, 变更检测就会报出永远修不掉的假变化。

几件容易踩的事,改 gen.mjs 前先看一眼:

  • 组件清单从 barrel 推,不要 readdir components/sticky-box.tsx 是裸文件、 没有目录也没有 readme,但公开导出 StickyBox_inner/ 则不该暴露。barrel 两个问题都没有。

  • components.db 的 schema 是硬契约,而且有两个消费端。 lms-web 的 MCP 和 diting 的 query_ui_components 都按字段名取值,改了名两边都静默返回 undefined,不会报错。 表名 components 也是契约 —— diting 不认文件名,它在 rule_dirs 下逐个 SQLite 文件试探「有没有 components 表」来发现这份目录,所以文件名能改、表名不能。

  • 一份文案只发一份。 when_to_use 列保留但写 NULL —— 它曾经是 description 的逐字节副本(44/44 个组件一字不差),同一段话发两遍不只是费 token,挂在两个字段名 下还会让模型当成两条独立信息。fallback.json 只有一份文案,就只写 description; 列不能删,消费方读到空值自己回落。

  • 子组件名要进 exported_names Combobox.InfiniteDropdown / Tabs.List / Popover.Target 在 barrel 里查不到(挂在父组件上),但调用方写的就是这个名字。 gen.mjs 扫组件源码的 X.Sub = YObject.assign(Root, {...}) 两种写法把它们 补进去 —— 不补的话下游精确查询 miss、fuzzy 落回父组件,模型拿不到答案就去翻源码, 而 torque 在 node_modules 里根本翻不到。md 清单不列它们:数量不定又被 slice(0, 4) 截断,漏出随机的一两个比一个不列更误导。

  • db 保持默认的 DELETE journal 模式,不要设 WAL。 WAL 标记会持久化进 db header, 产物在只读目录下会直接打不开。

  • md 只放「有什么」和「怎么选」,组件细节一律留给 components.db 清单里只有 组件名和导出名,没有描述 —— 用途、完整 props、readme 里的注意事项都按需查 db。 两条界线:

    • 不能砍到只剩组件名。 kebab → Pascal 有一串不规则的(form-wrapperFormItemWrapperproviderUiProvidertabTabsmessagemessages),而且好几个组件导出多个名字。少了导出名,模型要么多查一次 db 才能写 import,要么猜错一个标识符。这一列 1 KB,买的是「不用查就能正确导入」。
    • 也不能整节砍掉。 模型不知道有什么就不会去查 —— 「不知道自己不知道」。 这份文件的全部意义就是防止它自己造一个组件或直接用 mantine 原生的。
    • 要明说「一次能查多个」。 清单没有描述,模型选型时手上是一串候选,逐个查就是 逐个 round trip。这句话不绑参数形态(空格分隔还是数组由两端实现决定),只说能力。
  • torque-components.md 的 frontmatter 是 diting 的硬契约keywords / globs 必须单行逗号分隔(它用 ^keywords:\s*(.*?)$ 解析,多行 YAML 数组会静默变成空)。

  • 不设 alwaysApply: true,但这份 md 事实上每次 review 都全量注入。 别以为 alwaysApply: false 拦住了什么。召回是 keywords 驱动的,而且是对整个 diff 做子串匹配 —— rule_loader.pyload_matched_rules 把「改动文件路径 + 完整 diff」 拼成一个 search_text,然后 if kw in search_text_lower。我们的 keywords 里有 ui / text / tab,而 builduicontexttexttabletab —— 任何非空 diff 基本必中。而 keywords 一命中就 continueglobs 那条路径根本走不到。 globs 本身也很宽,只是宽得没那么彻底:_match_glob**/* 压成 * 再交给 Python fnmatch,而 fnmatch* 是匹配 / 的,所以 globs: src/**/*.{tsx,ts} 等于「路径里含 src/ 的任何 .ts/.tsx」—— lms-web 有 5974 个这样的文件,另有 296 个在 testing/ 下(那些只有 keywords 能召回)。 全量注入本身是可以接受的(组件选型规则本来就该对每个 tsx 生效,14.5 KB 不是大头), 但想收敛只能剪 keywords,收窄 globs 一个字节都省不下来。 而剪掉 ui / component 这类泛词,模型主动 search_project_rules 时的召回也跟着掉 —— 同一个旋钮的两个方向, 所以现状是刻意的选择,不是疏漏。

  • 别在 .md 里写某一端专有的工具名search_component() 之类)。这份 md 是给 diting 读的,而那个名字只存在于 lms-web 的 MCP,diting 里没有;写了模型会照着调, 拿一个 "tool not found" 白烧一轮探索预算。指数据文件(components.db)两端都成立。

  • gen.mjs 不写回 src/fallback.json 缺 entry 就报错退出,由人补。 写回会让 pnpm build 变成改动被追踪源文件的操作。

  • 不要给这个包加 npm 依赖。 它会被解包进 CI 环境,只用 Node 内置模块。

新增组件之后

  1. packages/torque/src/index.ts 里导出它(gen.mjs 从这里认组件)
  2. src/fallback.json 加一条英文whenToUse + keywords —— 不加的话 pnpm build 会直接报错退出,并把建议的起手式打出来
  3. 组件有 readme 的话,props 会自动解析出来(表格或 - \name?: Type`: 说明` 列表都认)
  4. 如果它带来了新的硬约束或禁止事项,补进 src/handwritten/