关于 Brownfield Cartographer
Brownfield Cartographer 静态映射 Python、SQL、dbt、Airflow 和 TypeScript 仓库中的依赖与数据血缘,供开发者和编码 Agent 评估变更影响。结果附带源文件证据和覆盖情况;分析在本地进行,不执行仓库代码。
主要功能
- 01跨语言依赖映射
- 02表与列的数据血缘
- 03变更影响和分支差异报告
- 04文件与行号证据
- 05CLI、Python API 和只读 MCP 服务
- 06本地分析且不执行代码
适用场景
- 01修改模型或模块前识别下游影响
- 02将数据列追溯到来源
- 03检查拉取请求的变更及受影响依赖
- 04为编码 Agent 提供带证据的仓库上下文
MCP 相关
提供只读 stdio MCP 服务,包含架构、符号查找、依赖追踪、影响分析、数据血缘和代码上下文工具。服务在固定仓库范围内读取已分析的索引。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Brownfield Cartographer
如果我改动这里,会有什么出问题? Cartographer 能发现语言服务器看不到的依赖:由 Python 任务写入、在 SQL 中转换、再由 dbt 模型使用的表。它会以静态、本地的方式绘制这些依赖,并提供文件和行号证据,供你和编码 Agent 使用。
cartographer analyze .
cartographer impact models/staging/stg_orders.sql # what is downstream of this file?
cartographer lineage customers --direction upstream # where does this table come from?
cartographer lineage customers::first_order # which source columns feed this column?
语言服务器和 grep 能回答有关代码符号的问题。Cartographer 则能回答跨越语言边界、通过字符串和配置中的名称关联的问题,首先覆盖 Python、SQL 和 dbt 之间的数据沿袭。每个结果都附带源代码证据和覆盖情况;对于不支持的情况,会明确报告而不是猜测。它可离线运行,无需 API 密钥,也不会执行仓库代码。
同一个查询引擎为 CLI、Python API 和只读 MCP 服务提供支持,可供 Claude Code、Codex 和 Cursor 使用。下方的支持情况表列出了当前能力和已知缺口。
60 秒快速体验
安装好 uv 后,在 dbt 的公开示例项目上运行。无需永久安装任何内容;此处的分析耗时 3 秒:
git clone --depth 1 https://github.com/dbt-labs/jaffle_shop && cd jaffle_shop
uvx --from brownfield-cartographer cartographer analyze .
uvx --from brownfield-cartographer cartographer impact models/staging/stg_payments.sql
analyze_impact | complete | snapshot eefa28cd4e13
┌───────────────┬──────────────┬──────────────────────────────────────┐
│ Symbol / node │ Relationship │ Evidence │
├───────────────┼──────────────┼──────────────────────────────────────┤
│ stg_payments │ PRODUCES │ models/staging/stg_payments.sql:1-26 │
│ orders │ PRODUCES │ models/orders.sql:1-57 │
│ customers │ PRODUCES │ models/customers.sql:1-70 │
└───────────────┴──────────────┴──────────────────────────────────────┘
列沿袭会跟踪每个模型中的重命名:
uvx --from brownfield-cartographer cartographer lineage customers::number_of_orders
trace_data_lineage | complete | snapshot eefa28cd4e13
┌──────────────────────┬──────────────┬────────────────────────────────────┐
│ Symbol / node │ Relationship │ Evidence │
├──────────────────────┼──────────────┼────────────────────────────────────┤
│ stg_orders::order_id │ DERIVES │ models/customers.sql:1-70 │
│ raw_orders::id │ DERIVES │ models/staging/stg_orders.sql:1-24 │
└──────────────────────┴──────────────┴────────────────────────────────────┘
在 Claude Code 中,插件可让你用自然语言提出相同的问题。
安装与分析
需要 Python 3.12+ 和 Git。使用 uv 或 pipx 从 PyPI 安装命令行工具:
uv tool install brownfield-cartographer
# or: pipx install brownfield-cartographer
cartographer --version
# Local analysis needs no network, API key, or model service.
cartographer analyze /path/to/repository
# Force a fresh rebuild or choose an output root.
cartographer analyze /path/to/repository --full -o ./results
# Optional: pin the SQL dialect instead of choosing the best fit per file.
cartographer analyze /path/to/repository --dialect bigquery
# Optional: use a previously generated dbt v12 manifest.
cartographer analyze /path/to/dbt-project --dbt-manifest target/manifest.json
如果要从源代码检出版本运行,请克隆仓库、运行 uv sync --frozen,并在命令前加上 uv run,如下方示例所示。
显式指定 GitHub URL 输入时,仍会下载一份检出副本:
cartographer analyze https://github.com/owner/repository
本地分析绝不会上传源代码,也不会调用模型。
输出与查询
对于本地检出版本,制品默认存放在
<repository>/.cartography/<repository-name>/。使用显式 --output 时,本地仓库会使用 <output-root>/.cartography/<repository-name>--<path-hash>/,以免同名检出版本相互覆盖。该哈希标识解析后的检出路径;移动检出版本会创建单独的索引。JSON 分析结果包含 artifact_directory,可将其作为 --index-dir 传给查询命令。已有的自定义输出索引会保持不变;重新分析会写入新目录。GitHub URL 输入默认使用当前目录,并采用 owner--repository 文件夹名。
| 制品 | 用途 |
|---|---|
index.json | 完整的带版本图谱、源代码位置、元数据和覆盖情况 |
module_graph.json | 结构图视图,包含函数 |
lineage_graph.json | 数据集/转换图视图 |
analysis_summary.json | 完整/部分状态、诊断信息和阶段结果 |
CODEBASE.md | 仓库静态上下文 |
onboarding_brief.md | 关键模块、数据入口/出口和变更热点 |
cartography_trace.jsonl | 保留的运行历史记录,含运行 ID |
state.json | 上次成功快照的内容指纹 |
使用 cartographer query /path/to/repository 进行交互式探索。它支持 find、impact、deps、dependents、lineage、lineage-down、context、overview、help 和 quit,并使用与下方命令相同的引擎。
或者使用单独的命令,输出人类可读内容或 JSON:
uv run --no-sync cartographer overview /path/to/repository --json
uv run --no-sync cartographer find run --repo /path/to/repository --json
uv run --no-sync cartographer impact producer.py --repo /path/to/repository
uv run --no-sync cartographer lineage output --repo /path/to/repository --direction upstream --json
使用 --index-dir 指定自定义输出位置。Python 调用方可使用 brownfield_cartographer.query_api.QueryEngine.open(Path(repo)) 和相同的查询方法。响应包含快照标识、覆盖情况、输出截断标记以及可用的源代码证据。对于存在歧义的目标,系统会拒绝处理。
审查拉取请求
cartographer diff 会报告某个分支有哪些更改,以及这些更改可能造成的影响,可用于 PR 评论或推送前的快速检查:
cartographer diff --base main # Markdown
cartographer diff --base main --json # for scripts
--base 指定的合并基点之后更改的行(已提交、未提交和未跟踪)会映射到函数、模块、SQL 语句、dbt 模型、架构 YAML 和 Airflow 任务,并列出有证据支持的下游依赖项。合并基点也会纳入分析,因此删除的代码也会被计算在内:删除模块、函数或模型时,会报告仍在使用它的导入方、调用方和模型。
要为每个拉取请求添加评论,请添加工作流:
on: pull_request
permissions:
contents: read
pull-requests: write
jobs:
impact:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0 # the merge base must be available
- uses: Sanoy24/[email protected]
此操作会持续更新一条评论,也会将报告写入作业摘要;对于来自复刻仓库的拉取请求,这种方式同样有效。
连接 AI 助手
Claude Code 插件(需要 uv;无需安装或配置其他内容):
/plugin marketplace add Sanoy24/the-brownfield-cartographer
/plugin install brownfield-cartographer@brownfield-cartographer
该插件会为当前项目启动 MCP 服务,并添加一个 data-impact 技能。你可以提问,例如“如果我更改 stg_orders,会有什么问题?”。如果项目尚未经过分析,工具会说明这一点,然后由助手运行 cartographer analyze(离线运行;绝不执行仓库代码)再作答。
任何 MCP 宿主:
cartographer analyze /absolute/path/to/repository
cartographer-mcp --repo /absolute/path/to/repository
stdio 服务提供 get_architecture、find_symbol、trace_dependencies、analyze_impact、trace_data_lineage 和 get_code_context。它会在固定的仓库范围内读取先前分析生成的索引,且绝不会调用大模型。有关 Claude Code、Codex 和 Cursor 的配置方法,请参阅 MCP 配置。
find 使用词法匹配。impact 报告的是潜在依赖项,并不保证每个使用方都会受到影响。依赖不完整扫描的结果之前,请先查看已保存的覆盖范围和诊断信息。
分析在快照完整或未更改时返回退出代码 0,覆盖不完整时返回 2,输入错误或运行期间发生致命错误时返回 1。部分运行不会推进成功检查点。目前,已更改的工作树会触发完整重建;未更改的成功快照可以复用完整索引。
支持范围与安全性
| 输入 | 当前支持范围 |
|---|---|
| Python | 函数/类、受支持的绝对/相对导入,以及仓库函数之间的调用(同一模块中的名称、导入的名称和模块、self/cls 方法;不会猜测对其他对象的调用和动态调用);保守识别字面量 I/O 关联(pandas、Spark 读取器和写入器)。传递给 execute/executemany/executescript、.sql() 和 read_sql 的 SQL 会从字面量和字符串常量中解析(同一模块中的常量,或从其他仓库模块导入的常量),包括 text() 和 DB-API 占位符。仅插入值的 f-string(比较、IN、LIMIT、带引号的字面量)会被解析;包含插入的表名或投影、字符串拼接或 .format 的 SQL 会被报告为动态内容,不会猜测 |
| SQL | SELECT/UNION、CTAS、INSERT、UPDATE、DELETE 和 MERGE;语句范围和表依赖关系。没有表血缘关系的 DDL 和事务语句会被跳过;其他语句(如 COPY)会逐条报告,不会因此丢弃文件中的其余内容。每个文件都会使用最匹配的方言解析(DuckDB、BigQuery、Snowflake、Postgres、MySQL、Spark、T-SQL、Trino),并在证据中记录为 sql:<dialect>;--dialect 可指定方言 |
| dbt | 明确支持导入 v12 清单中的模型、种子、快照和源;没有清单时采用基础 SQL/YAML 回退解析。会在仓库中的任何位置查找项目,包括同一仓库中的多个项目 |
| 列 | 支持 SQL 文件、嵌入 Python 的 SQL、Airflow 内联 SQL、来自已编译清单的 dbt 模型(--dbt-manifest,需先运行 dbt compile),以及唯一包含 Jinja ref/source/config/注释的 dbt 源模型中的 CREATE ... AS、INSERT ... SELECT(包括列列表)的列级血缘关系。每条边均标记为 copy 或 derived。会展开 CTE 和子查询中的 SELECT *;表上的 SELECT *、联接中的未限定列,以及含有其他 Jinja 的模型会计为无法解析,不会猜测 |
| Airflow | 支持 with DAG、@dag 和 dag= DAG 中由运算符和 @task 函数创建的任务;根据 >>/<<、列表、set_downstream、chain() 和 TaskFlow 数据传递推断顺序,并提供行证据。任务会关联到其运行的内容:python_callable、@task 函数、sql= 文件(包括 template_searchpath)和内联 SQL 血缘关系,以及 python x.py bash 命令。影响关系会从代码流经任务,再传递到下游任务。循环中创建的任务或使用计算得出的 id 的任务会被报告,不会猜测 |
| JavaScript/TypeScript | .js .mjs .cjs .jsx .ts .mts .cts .tsx:函数、箭头函数、类方法;支持使用字面量相对路径说明符的 ESM、仅类型导入、require() 和 import() 导入,以及 tsconfig/jsconfig paths/baseUrl 别名(采用最近的配置,支持仓库内的 extends)。包导入视为外部导入 |
共享扫描器会遵循嵌套的 .gitignore 和 .cartographerignore,排除构建/环境目录,拒绝符号链接/连接点,并限制文件大小、总字节数、文件数量、条目数量和遍历深度。常见的机密文件名会被排除;不会检测嵌入普通源代码中的机密信息。大型、二进制、无法读取或不受支持的文件会被报告,不会被视为已完成全面分析。本地分析不会执行任何仓库源代码。
有关支持的清单版本、数据集标识符、制品新鲜度和扫描器限制,请参阅 dbt 制品导入。
准确性基准测试会针对固定版本的 dbt、Python 和 SQL 语料库,将提取结果与手写的预期结果进行评分,其中也包括已知缺口。该测试会在 CI 中运行。
开发与分支管理
uv sync --frozen
uv run --no-sync pytest -q
uv run --no-sync ruff check src tests scripts
uv run --no-sync mypy -p brownfield_cartographer.scanner -p brownfield_cartographer.persistence -p brownfield_cartographer.query_api -p brownfield_cartographer.analyzers.javascript_analyzer -p brownfield_cartographer.analyzers.embedded_sql -p brownfield_cartographer.analyzers.sql_lineage -p brownfield_cartographer.analyzers.airflow_dag -p brownfield_cartographer.analyzers.dbt_manifest -p brownfield_cartographer.diff -p brownfield_cartographer.analyzers.python_calls --follow-imports=skip
uv build
uv run --no-sync python scripts/check_wheel.py
请使用短期的 feat/、fix/、docs/ 和 chore/ 分支,并通过拉取请求合并到稳定的 main 分支。请勿将功能直接推送到 main。有关工作流和发布约定,请参阅 CONTRIBUTING.md;有关发布历史,请参阅 CHANGELOG.md。
社区与许可证
参与者须遵守行为准则。如需报告漏洞,请按照 SECURITY.md 中的说明私下报告。
本项目采用 Apache License 2.0 许可。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。