跳转至

工作原理

Floorplan 将工作分配给脚本和你运行它的 AI(Claude Code 或 Codex)。脚本负责所有机械性工作:查找文件、解析代码、将请求匹配到端点、布置地图。它们是纯 Node.js 脚本,没有依赖,也不消耗 token。AI 则做只有代码阅读者才能做的事:判断你应用的各个部分是什么,并通俗地解释它们。

flowchart TD
    status["status: is there a map already?"] -->|no| scan
    status -->|yes| refresh["refresh: re-scan, carry over what didn't change"]
    scan["scan: repos, files, imports, endpoints, requests"] --> arch["The AI writes architecture.json<br/>the parts of the app, outside services, flows, tour"]
    arch --> build["build: assign files, connect everything,<br/>Health, screens, the map"]
    build --> describe["The AI names and describes every file and endpoint"]
    describe --> recent["The AI marks recent work"]
    refresh --> describe
    recent --> open["open: serve the map and show it"]

1. 扫描

scan.mjs 会在你指定的文件夹下查找每个 git 仓库(可以是单个仓库、monorepo,或并排放置的多个仓库),并跳过重复的工作树。它通过 git 列出文件,因此会遵循你的 .gitignore,然后从每个文件中提取:

  • 导入,解析为真实文件:TypeScript 路径别名、Python 包、Go 模块、Rust crate、JVM 包;
  • 导出的定义及其文档注释;
  • 服务器定义的端点;
  • 代码发出的 Web 请求;
  • 内容指纹,以便后续更新能识别发生了什么变化。

支持的语言:TypeScript 和 JavaScript(包括 Vue、Svelte 和 Astro 文件)、Python、Go、Rust、Java、Kotlin、Scala 和 Groovy,对其他语言提供较轻量级的支持。

2. 将请求连接到端点

地图上最有用的连线将屏幕的 Web 请求连接到响应它们的服务器代码,而且常常跨越多个仓库。Floorplan:

  • 查找端点:Express、Koa、Hono、Next.js(路由文件和 API 路由)、Firebase Cloud Functions、Flask、FastAPI、Django、Go(net/http、Gin、Echo、chi、Fiber)、Actix、Axum 和 Spring。
  • 解析前缀:使用 url_prefix 注册的 Flask 蓝图,以及通过 app.use('/api/users', usersRouter) 挂载的 Express 路由器,包括挂载在其他路由器内部的路由器,以及前面带有中间件的挂载。
  • 查找请求:使用 fetch、axios、ky、requests 等发出的请求,包括:
  • 先在变量中构建的地址:const url = …; api.get(url);
  • 包含嵌套部分的模板字符串;
  • 同一文件中用于添加前缀的小型辅助函数,例如 call('/definitions')。
  • Firebase Cloud Functions 是按名称而非地址调用的。可调用函数(onCall)会以你的 functions 入口文件导出的名称显示为 CALL /approveItem,而网站的 httpsCallable(functions, 'approveItem') 调用可以到达它,包括通过你自己包装 httpsCallable 的辅助函数。onRequest 函数是位于 /<name> 的普通端点,传给它的 Express 应用会保留其在该名称下的自有路由。定时任务和其他后台函数(Firestore、Storage、Pub/Sub)会被列出,供 AI 放置到地图上。
  • 匹配两者。当请求只拼出地址的一部分(因为基础 URL 位于设置中)时,Floorplan 会学习每个客户端的基路径,并优先选择与之匹配的结果。

这是模式匹配,而不是编译器,因此它能捕获大多数连接,但不是全部。如果缺少某个重要连接,请要求将其添加到 floorplan 中,它会将其记录为显式连接。

3. AI 描述系统

Claude 或 Codex 会读取扫描摘要、README、设置文件和入口点,然后编写 architecture.json:

  • 应用的主要部分,每个都附有简明摘要;
  • 它真正通信的外部服务(数据库、支付服务商、电子邮件);
  • 扫描无法看到的连接,例如队列、定时任务和 webhook;
  • 一些引导式流程和一条“从这里开始”的导览。

然后构建会把每个文件分配到模式匹配的最深层部分,并报告任何剩余内容。

接下来,describe.mjs 会为每个部分编写一份工作表。工作表是每个文件和端点的摘要:它定义了哪些内容、它的文档注释、它使用了什么、以及什么使用了它。AI 会为每一项填写名称和描述。在大型项目中,Claude Code 会将工作表分发给并行的辅助助手。

默认情况下,所有内容都是为应用的所有者(而不是工程师)编写的:用日常语言说明每件事对业务的作用。如果你要求面向开发者的地图,它会切换为技术风格。

4. 构建

build.mjs 会验证 AI 编写的所有内容,并按名称报告问题(“你是指 … 吗?”)。然后它会:

  • 使用导入、匹配的请求和 AI 的显式连接来连接各个部分;
  • 运行 Health 检查;
  • 检测屏幕:Next.js、React Router、Vue、SvelteKit、Remix、Nuxt、Astro、Expo、Angular、TanStack;
  • 写入 graph.json 和自包含的 index.html,并注明是由 Claude Code 还是 Codex 生成的,以便地图的 Ask 栏和修复提示指向正确的工具。

地图会在你的浏览器中通过 ELK 自动布局,因此构建本身很快。

5. 最近的工作

每次 make 或 update 之后,AI 都会把刚刚处理的内容记录到 recent-work.json 中。recent.mjs 会列出事实:自上一张地图以来发生了什么变化、未提交的更改,以及最近的提交,每一项都匹配到对应的卡片。AI 会补充原因:你要求了什么,以及每个更改如何服务于这个要求。之前的亮点每次都会被替换。

6. 展示地图

open.mjs 会在后台启动地图的小型本地服务器,并打开你的浏览器。如果该地图的服务器已在运行,则会复用;任何打开的标签页都会在原地重新加载,而不是打开新标签页。

更新

refresh.mjs 会重新扫描并与上次构建进行比较,利用每个文件的指纹:

  • 确切内容,用于发现编辑、重命名和移动;
  • 签名:其导出、端点和文档注释。函数体内部的编辑不计入。

它随后:

  • 将描述带到已移动和重命名的文件与端点;
  • 移除已删除文件对应的条目;
  • 标记签名发生变化的条目,以供审查。

然后它会重建。AI 只需要描述新增或被标记的内容,并在改动较大时检查结构。这就是更新如此之快的原因。

蓝图

以上一切都是 Floorplan 映射现有代码的方式,这是它的主要工作。蓝图是另一种入口:一张尚未构建之物的地图。AI 读取 PRD 或描述,然后写出 floorplan/plan.json:系统需要的每个文件和端点、哪个屏幕调用哪个端点、哪些部分使用外部服务和数据库,以及谁可以使用每个端点。它还会列出所选择的技术栈、它的假设,以及 PRD 未决的问题。

plan.mjs 将计划转换成与 scan.mjs 从代码中生成的相同的扫描结果,因此构建、Screens、流程、导览和 Ask 都以同样的方式工作。不同之处在于:

  • 卡片使用虚线轮廓,面板上带有 Blueprint 标签;
  • Health 变成对计划的一项设计审查:任何人都可用来更改数据的端点、未决定谁可以使用它们的端点、未决问题,以及没有任何连接的部分;
  • 每个部分都有 Build this with Claude(或 Codex)按钮:一个按计划构建该部分的请求,列出它的文件、端点以及它所依赖的内容;
  • Ask 根据计划和 PRD 来回答,因为此时没有代码可读;
  • Ask 栏的 Change 开关接受诸如“顺便把退款也规划一下”之类的请求:智能体返回更新后的计划,地图服务器用 plan.mjs 和 build.mjs 检查它(把问题发回一次),保存它并重新绘制地图,同时高亮显示更改,Undo 则恢复上一个计划。每个设计审查项的 Resolve on the map 会替你填好那个请求:未决问题只需你给出答案。智能体保持只读:只有服务器能写入,而且只写 plan.json、architecture.json 和 recent-work.json。

更新蓝图时会从 plan.json 重新绘制。一旦代码存在,refresh.mjs --from-code 会改为映射真实代码,而 plan.json 保持不变。

提问

地图服务器使用你电脑上、你项目中的 AI 来回答每个问题:

  • Claude Code:它只使用只读工具运行 claude -p:读取和搜索文件,以及在地图中查找信息的 floorplan/query.mjs。
  • Codex:它在 Codex 的只读沙盒中运行 codex exec,使用同样的查找能力。这些运行不会保存到你的 Codex 历史记录中,因此后续提问时会带上最近几个问题和答案。

它会使用生成地图的那一个工具;如果那个工具未安装,则使用另一个。无论哪种方式,它都会用文本加要展示的卡片来回答,因此答案可以引用真实代码。

在 Claude 应用中,地图改为通过应用向 Claude 提问,使用相同的查找能力,但无法访问你的源代码。

同样的查找能力对普通的 Claude Code 会话也有帮助。Floorplan 在 CLAUDE.local.md 中添加的简短小节会告诉它们,在从头搜索代码之前先查看地图(query.mjs find、show、path、overview)。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 floorplan/floorplan