返回 2026-04-21
🛠 工具 / 开源

brief:将项目规范转化为CLI的知识库brief

nesbitt.io·2026-04-21

该项目提出一种将团队开发规范、编码约定和流程文档结构化为可执行命令行工具(CLI)的方法。通过将知识库暴露为CLI接口,开发者可以直接在终端查询、验证或执行标准化操作,减少文档过时与执行偏差。系统支持自定义规则定义与自动化检查,提升协作一致性与开发效率。

Andrew Nesbitt

无论是新贡献者、安全扫描器还是 AI 编码代理,任何进入一个陌生代码库的人,在开展任何有效工作之前,都必须回答同样几个基本问题:这是什么语言?如何安装依赖?测试命令是什么?提交前该运行哪个 linter?如果是安全审查,这个技术栈中哪些函数是危险函数?

代理的情况尤其容易看出出错的代价,因为你可以看到 Claude 去 grep package.json,读取 Gemfile,尝试 npm test,被告知没有测试脚本,再试 yarn test,最后发现其实是 pnpm,这时才能开始你真正要求的工作。对于每一个 Rails 项目或每一个 Go 模块,这些答案都完全相同,而每次都要从头重新发现这些信息,纯粹是浪费精力。

brief 是一个涵盖 54 个语言生态、共 516 种工具的知识库,前面挂着一个独立的 Go 二进制程序,负责查询并以 JSON 格式输出(当通过管道传输时)或在 TTY 上输出人类可读的摘要。真正独特的是这个数据集:调用命令、配置文件位置,以及五百多种工具在统一机器可读 schema 下的分类体系。CI 模板、devcontainer 生成器和编辑器引导流程是我能找到的最接近的东西,但它们各自只包含其中一部分,且没有共享的上游数据源。我把这个 CLI 看作是该数据的一种视图,并预期未来会有其他形式的访问方式。

你只需将其指向一个目录、一个 git URL,或像 gem:rails 或 npm:express 这样的注册表坐标,它就会报告该项目的工具链,涵盖二十个类别,每个类别都包含要运行的命令及其驱动的配置文件,此外还会列出在常规位置找到的所有治理和社区文件(如带 SPDX 标识符的许可证、安全策略、CODEOWNERS、FUNDING.yml 等)。

brief .                       # local directory
brief gem:rails               # registry package, resolved to source repo
brief diff                    # only tools touched by changed files
brief missing                 # baseline categories with no tool configured
brief threat-model            # CWE/OWASP categories implied by the stack
brief sinks                   # dangerous functions in detected tools

检查全部 516 个定义耗时不到 250 毫秒,因为任何在每次会话或流水线步骤开头运行的工具都不能成为性能瓶颈;在本博客自己的仓库中,它大约在 220 毫秒内识别出 Jekyll、Bundler、Rake、Dependabot 和 GitHub Actions;而在一个 Go 项目中,输出如下:

$ brief .
Language:        Go
Package Manager: Go Modules (go mod download)
Test:            go test (go test ./...)
Lint:            golangci-lint (golangci-lint run)  [.golangci.yml]
Format:          gofmt (gofmt -w .)
Build:           GoReleaser (goreleaser release --clean)
Security:        govulncheck (govulncheck ./...)
CI:              GitHub Actions  [.github/workflows/]

我自己在克隆任何仓库后首先运行的就是它,并且已将其集成到我的全局代理指令中,因此每次 Claude 会话一开始都会先执行 brief .。这样只需一次工具调用就能让代理熟悉该仓库,省去了它原本会浪费在探索性 grep 和错误猜测上的 token。在功能分支上,brief diff 会将报告范围缩小到仅受更改文件影响的工具,因此阅读报告的人就知道要运行 golangci-lint(因为 .go 文件变了),而不会被告知 monorepo 另一侧的 Python linter。

由于 JSON 输出遵循已发布的 schema,它也可作为其他工具的构建块:brief --json . | jq -r '.tools.test[0].command.run' 可让一个多语言 CI 任务获取项目的测试命令,而无需为每种语言编写特定逻辑;该查询结果还可用于生成 devcontainer 或引导脚本;目前的计划是在 ecosyste.ms 索引的每个仓库上运行它,以便为每个软件包提供其技术栈元数据。

检测规则采用 TOML 格式而非 Go 语言编写,这意味着添加新工具只需在 knowledge/ 目录下创建一个文件,无需修改任何代码:包括工具名称、所属类别、表明其存在的文件或依赖项名称、运行该工具的命令,以及可选的一组 oss-taxonomy 标签(用于描述该工具的类型)。该分类体系是一个独立项目:它定义了“工具”的术语体系;而 brief 则负责检测项目实际使用了哪些工具。

依赖项名称的匹配逻辑与 git-pkgs 使用相同的清单解析器,因此工具定义可以声明“当 rspec-core 存在于 bundle 中时即视为存在”,而 brief 已内置支持解析 Gemfiles、package.json、go.mod、Cargo.toml 及其他受支持的锁文件格式,无需重复实现这些解析逻辑。

这些标签最初的作用是让 JSON 输出能显示“Web 框架”而非笼统的“构建工具”,但当数百个定义都带上标签后,它们清晰地映射到了 CWE 和 OWASP 分类上。因此,对 Rails 项目进行威胁建模时,brief 无需扫描一行代码就能识别出 SQL 注入、批量赋值、XSS、CSRF 和 SSTI 等风险,因为这些正是 Rails 和 ActiveRecord 的典型特征。此外,定义中还包含了每个工具暴露的具体危险函数(整个数据集约有 700 个),这为审查一个陌生技术栈的安全问题提供了一个合理的初始 grep 关键词列表。

$ brief sinks .
ActiveRecord:
  Arel.sql            sql_injection      CWE-89
  find_by_sql         sql_injection      CWE-89
  where               sql_injection      CWE-89   string interpolation only
Rails:
  html_safe           xss                CWE-79
  redirect_to         open_redirect      CWE-601  when target is from params
  render inline:      ssti               CWE-1336
Ruby:
  eval                code_injection     CWE-95
  Marshal.load        deserialization    CWE-502

brief missing 功能会反向检查,并报告在已检测到的生态系统中,五个基准类别(测试、代码检查、格式化、类型检查、文档)中哪些尚未配置工具,同时指出每个空缺对应的推荐工具。该检测引擎也可作为一个 Go 库被导入使用,如果你不想通过 shell 调用的话。

工具定义文件存放在 knowledge/ 目录中,我最欢迎的贡献就是提交新增定义的 PR,尤其是针对那些我不常接触的生态系统。如果你发现 brief 对某个项目的判断有误,请提交 issue 或在 Mastodon 上联系我。

brew install git-pkgs/git-pkgs/brief / github.com/git-pkgs/brief

需要完整排版与评论请前往来源站点阅读。