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

项目约定知识库:以 CLI 形式暴露brief

nesbitt.io·2026-04-21

该项目将团队内部的项目约定整理成结构化知识库,并通过命令行接口(CLI)提供访问。它允许开发者快速查询编码规范、构建流程、部署策略等关键信息,提升协作效率。该工具采用轻量级设计,易于集成到现有工作流中。作者认为标准化约定并自动化访问是提高工程一致性的有效方式。

Andrew Nesbitt

无论是新贡献者、安全扫描器,还是 AI 编码代理进入一个陌生的代码库,在真正派上用场之前,都必须回答几个基本问题:这是什么语言?如何安装依赖项?测试命令是什么?提交前需要运行哪个代码检查工具?如果是安全审查,该栈中哪些函数是危险的?

代理的情况最直观地体现了答错问题的代价——你可以看到 Claude 先查找 package.json,再读 Gemfile,尝试 npm test,被告知没有测试脚本,又试 yarn test,最后才发现实际用的是 pnpm,然后才能开始你真正要做的任务。所有 Rails 项目或 Go 模块的答案都是相同的,每次都从零重新发现这些知识是一种浪费。

brief 是一个涵盖 54 种编程语言生态系统中 516 个工具的数据库,由一个 Go 二进制文件驱动,支持通过管道输出 JSON,或在 TTY 上打印人类可读的摘要。其独特之处在于数据集部分:调用命令、配置文件路径,以及五百种工具在一个机器可读架构下的分类体系。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 标签集合(用于描述该工具的类型)。该 taxonomy 是一个姊妹项目:它定义了工具的词汇表;brief 则能识别项目使用了哪些工具。

依赖名称匹配由与 git-pkgs 相同的清单解析器驱动,因此工具定义可以声明“如果 bundle 中包含 rspec-core,则认为其存在”,而 brief 已内置支持读取 Gemfile、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 若未检测到某类工具,则会反转检查逻辑,报告在五个基准类别(测试、lint、格式化、类型检查、文档)中哪些缺失了对应生态系统的工具,并为每个缺口推荐标准选择。同时,该检测引擎也可作为 Go 库导入使用,避免通过 shell 调用。

工具定义位于 knowledge/ 目录中,我特别欢迎提交 PR 来添加新定义,尤其是针对我不常使用的生态系统。如果你发现它对某个项目的判断有误,请提 issue 或在 Mastodon 上联系我。

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

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