Floorplan 在 Codex 中的完整实践:插件安装、$floorplan 绘图与只读 Ask 问答
【免费下载链接】floorplan
See how your app actually fits together. An interactive, plain-English map of your codebase, drawn by Claude or Codex.
本文以 Floorplan 的 Codex 指南为主线,讲清楚三件事:如何在 Codex 应用中完成安装、如何用$floorplan生成并更新代码地图、以及地图上的 Ask 栏是怎样通过codex exec在你自己的 ChatGPT 登录态下以只读沙箱回答问题的。读完后你能独立完成安装、按需切换推理引擎、定位 CLI 路径,并清楚它与 Claude Code 版本的差异所在。
同一个技能,两套宿主
Floorplan 在 Codex 中的工作方式与在 Claude Code 中完全一致:同一份 skill、同一套脚本、同一张地图,差别只在于宿主如何加载插件、以及 Ask 栏调用哪个 CLI。整个过程不需要配置任何 API Key,使用的是你已经登录的 ChatGPT 账号。
这一点在仓库结构里可以直接看出来:Claude Code 的清单放在.claude-plugin/,Codex 的清单放在.codex-plugin/,两者version与description保持一致(发布测试tests/release.test.mjs正是校验这种一致性),而真正被两个宿主共用的技能定义只有一份,位于 skills/floorplan/SKILL.md。Codex 侧的入口描述则由 skills/floorplan/agents/openai.yaml 提供,它声明了展示名、一句话说明和默认提示词。
前置条件
- Codex:桌面应用或 CLI 均可,需要已用 ChatGPT 账号登录。
- Node.js 18 或更高版本。Floorplan 的所有脚本都是零依赖的普通 Node.js 程序,
package.json中的engines字段即声明>=18(见 package.json)。
用一条命令确认 Node 版本:
node --version与 Claude Code 相比,Codex 侧不需要额外安装 CLI 才能让 Ask 栏工作——Codex 应用本身已经包含 Ask 栏所依赖的能力。只有在你想手动指定可执行文件、或在服务器等场景下单独启动地图服务时,才需要关心codex命令本身是否在 PATH 上。
安装:应用内图形界面或命令行
在 Codex 应用内安装(无需终端)
- 打开Plugins,选择Add a marketplace。
- Source填入
haydenschmitty/floorplan,Git ref留空,点击Add marketplace。 - 在列表中找到Floorplan,点+安装。
- 新建一个会话(插件在会话启动时加载)。
用 Codex CLI 安装
codex plugin marketplace add haydenschmitty/floorplan codex plugin add floorplan@floorplan第一条命令把这个仓库注册为插件市场,第二条把floorplan@floorplan安装到你的环境。应用与 CLI 共享插件目录,所以在其中一侧安装,另一侧也能直接使用。
从仓库视角看,marketplace add读取的是 .agents/plugins/marketplace.json,其中把本仓库声明为一个单插件市场,插件源指向./,并设置了installed/authentication策略;而plugin add读取的是 .codex-plugin/plugin.json,它声明"skills": "./skills/",并带有"requires_local_executor": true——这正是 Floorplan 需要在你的机器上执行node脚本的原因。该文件里还有interface.defaultPrompt三个默认提示词("Draw a floorplan of this codebase"、"Update the floorplan with what we just changed"、"Show me how the frontend talks to the backend"),因此你在 Codex 的输入框里可以直接看到推荐话术。
画出第一张地图
在 Codex 中打开你的项目文件夹,然后用自然语言提问即可:
Draw a floorplan of this codebase
想按名字调用技能,输入$floorplan。之后的流程与 Claude Code 完全相同:Codex 扫描代码,为每个部分、文件和 Web 请求写名字与说明,构建地图并打开它。之后说"update the floorplan",它只重新读取发生变化的部分。
Codex 是如何被识别出来的
地图需要记住"是谁画的",这样 Ask 栏和"Fix with …"提示词才能叫对名字。识别逻辑在 skills/floorplan/scripts/lib/agent.mjs:
const DETECT = { claude: () => false, // the default codex: (env) => !!(env.CODEX_THREAD_ID || env.CODEX_SESSION_ID), };优先级是--agent <name>参数 →FLOORPLAN_AGENT环境变量 → 环境变量探测 → 默认claude。传入无法识别的值时会被忽略并回落到探测结果,这一行为在 tests/agents.test.mjs 中有明确断言(例如detectAgent({ agent: 'gpt' }, { CODEX_THREAD_ID: 'abc' })仍返回codex)。
识别结果写入graph.json的meta.agent,构建日志会打印AGENT Codex: questions on the map run through Codex(见 skills/floorplan/scripts/build.mjs)。打开的地图页面随后根据它决定按钮文案:skills/floorplan/assets/viewer.html 中,当服务器引擎或地图构建者被判定为 codex 时,界面使用{ id: 'codex', name: 'Codex', app: 'Codex' },登录提示也改成"打开 Codex 应用(或运行codex login)后重试"。
沙箱与地图服务器
Codex 打开地图时会要求把地图的服务器放到沙箱之外运行。原因有两层:服务必须在命令结束后继续存活,而 Ask 栏又需要访问网络才能连到 Codex。如果你不想授权,可以在项目目录里自行启动:
node floorplan/serve.mjs服务只监听127.0.0.1,默认端口 4378,并在启动后打印实际 URL。它还会校验请求的Host头必须是自己机器的名字,并给每个会话生成随机 token——即使网页发起 DNS 重绑定把域名指向127.0.0.1,也拿不到/api/*的访问权(实现见 skills/floorplan/assets/serve.mjs)。
Ask 栏:在你自己的机器上运行 Codex
地图上的 Ask 栏会在你本机运行codex exec,进入 Codex 的read-only沙箱,工作目录是你的项目文件夹,使用的是你的 ChatGPT 登录态。它阅读地图和源码来作答,且无法修改任何文件。这些运行不会写入你的 Codex 历史;追问时,服务会把最近几轮问答一起带上。
这些描述在源码里逐条可以对应上。codexRun(skills/floorplan/assets/serve.mjs)构造的参数是:
const args = [...cli.args, 'exec', '--json', '--sandbox', 'read-only', '--skip-git-repo-check', '--ephemeral', '--output-schema', mode.file, '-C', root]; if (model) args.push('--model', model); args.push('-');逐项解释:
| 参数 | 作用 | 带来的实际约束 |
|---|---|---|
exec | 非交互式执行一次请求 | 一次提问一次进程 |
--json | 输出 JSONL 事件流 | 服务按行解析,转成进度与最终答案 |
--sandbox read-only | 只读沙箱 | 确认是 CLI 层面强制的只读,而非提示词约束 |
--skip-git-repo-check | 跳过 git 仓库校验 | 非 git 目录也能用 |
--ephemeral | 不落盘为历史会话 | 不污染 Codex 历史记录 |
--output-schema <file> | 用文件指定输出结构 | Codex 从文件读取 schema |
-C <root> | 指定工作目录 | 固定为地图所在的项目根 |
- | 从标准输入读提示词 | 请求内容经 stdin 送入 |
结构化输出为什么要"改写"一次
--output-schema指向.cache/下的 JSON 文件,由load()在启动与每次重建地图时写出。关键在于:OpenAI 的结构化输出要求对象里每个属性都在required中,且不允许额外属性。因此serve.mjs在写盘前会递归地"收紧" schema:
function strict(s) { if (s?.type === 'object' && s.properties) return { ...s, properties: Object.fromEntries(Object.entries(s.properties).map(([k, v]) => [k, strict(v)])), required: Object.keys(s.properties), additionalProperties: false }; if (s?.type === 'array') return { ...s, items: strict(s.items) }; return s; }可选列表在这里一律变成"必填但可以为空"——这正是"可选的列表就返回空数组"的实际含义。测试 tests/ask.test.mjs 会遍历整份 schema,断言每个 object 都满足additionalProperties: false且required与properties的键集合一致,并确认steps、followups都在必填之列。
也因为 Codex 是"从文件读 schema"的引擎,ENGINES.codex里带有schemaFile: true标记(skills/floorplan/assets/serve.mjs),写盘逻辑据此只在 Codex 引擎下执行。
追问如何保持上下文
由于--ephemeral让每次运行彼此独立,服务用一个内存表convos维护对话:每轮结束后保存{ q, a },其中问题截断到 500 字符、答案截断到 1500 字符,只保留最近 4 轮:
convos.set(session, [...turns, { q: question.slice(0, 500), a: String(a.answer || '').slice(0, 1500) }].slice(-4));下一轮把这段内容以Earlier in this conversation:的形式拼进提示词。测试同时验证了两点:首轮提示词里不含该段,第二轮才出现;传入一个不认识的 session 会开启全新对话而不是复用旧上下文。会话 ID 是 16 位十六进制随机串。
引擎选择与 CLI 定位
服务端使用哪一个引擎,遵循如下顺序(skills/floorplan/assets/serve.mjs):
--engine claude|codex,或环境变量FLOORPLAN_ENGINE;- 否则用构建这张地图的那个 agent(读
graph.json的meta.agent); - 都不匹配则默认
claude; - 随后按顺序尝试定位 CLI,第一个找到的胜出——但显式指定
--engine时不再回退,找不到就直接报cli_missing。
在地图由 Claude 构建、但机器上只装了 Codex 的场景里,回退机制让 Ask 栏依然可用;而想强制走某个引擎时,显式指定就是硬性约束。强制指定 Codex:
node floorplan/serve.mjs --engine codexCLI 的查找范围:codex在 PATH 上(which/where),以及在 Windows 上 Codex 桌面应用自带的 CLI——它位于版本化目录%LOCALAPPDATA%\OpenAI\Codex\bin\<version>\codex.exe下,代码会按修改时间倒序取最新的一个(codexApp())。如果你的 Codex 装在别处:
node floorplan/serve.mjs --codex /path/to/codex模型方面,--model <name>(或环境变量FLOORPLAN_MODEL)会决定调用哪个模型;不指定时由你的 Codex 设置决定。
一个容易被忽略的细节:子进程环境清理
服务器本身可能是从 Codex 会话内部启动的。如果原样把环境变量传给子进程,CLI 会误以为自己被嵌套在另一个会话里。服务因此在派生子进程前会剥掉一批变量(skills/floorplan/assets/serve.mjs):
for (const k of Object.keys(env)) if (/^CLAUDE_?CODE_(SESSION|ENTRYPOINT|CHILD|MESSAGING|HOST|SDK)|^CLAUDECODE$|^CODEX_(THREAD_ID|SESSION_ID|TOOL_CALL_ID|CI$|SANDBOX)/.test(k)) delete env[k];注意CODEX_THREAD_ID、CODEX_SESSION_ID、CODEX_SANDBOX都在清理列表中——识别地图作者用它们,回答问题时不带它们。
出错时用户看到什么
failCode()会把错误归类为三种:登录相关(not logged in、401、sign in等)→not_logged_in;额度相关(429、rate limit)→rate_limited;其余 →cli_error。界面据此给出对应提示,Codex 的登录提示是"打开 Codex 应用或运行codex login"。测试用一个提示词里含SIGNED-OUT的假 CLI 复现了未登录路径,断言事件类型为failure且 code 为not_logged_in,并确认此时不会产出answer。
和 Claude Code 的三处差异
一、不写任何笔记文件
在 Claude Code 中,Floorplan 会在CLAUDE.local.md里维护一小段带标记的说明,指向地图与query.mjs的几个查询命令。这段逻辑在 skills/floorplan/scripts/lib/claudemd.mjs 中:块由<!-- floorplan:start -->与<!-- floorplan:end -->包裹,只重写自己的块,其余内容不动,并把该文件加入仓库本地的.git/info/exclude(而非.gitignore),因此不会影响已跟踪文件。
Codex 没有等价的"个人、不提交"的笔记文件——AGENTS.md是与团队共享的。所以 Codex 下 Floorplan 不碰你的项目笔记。测试对此有双重断言:用--agent codex构建后,CLAUDE.local.md和AGENTS.md都不存在;而用--agent claude构建后,CLAUDE.local.md中能看到/floorplan/query.mjs的引用。
二、没有 Claude app 这条发布路径
把地图发布到 Claude app 是 Claude 的特性。在 Codex 中,地图就是在你的浏览器里打开,由你本机的服务提供。对应的离线替代方案是"导出":node floorplan/serve.mjs --export [<file>] [--include flows,notes,recent,health],默认只带flows与notes,导出的单文件 HTML 会去掉 Ask 栏、本机路径与 git remote 信息(见 skills/floorplan/assets/serve.mjs)。这在你需要把地图发给别人看时最实用。
三、修复提示词改成对着 Codex 说
Health 面板里现成的修复提示词,在 Codex 版本中是给你粘贴进 Codex 的;蓝图上的Build this with Codex同理。工具栏的Change开关同样让 Codex 在只读沙箱中运行:Codex 返回更新后的计划,由地图服务器负责保存。
这条链路的实现值得展开,因为它展示了"只读的 agent 也能改计划"是怎么做到的。changePlan()(skills/floorplan/assets/serve.mjs)先把请求交给runAgent,再把返回的完整plan.json与architecture.json交给applyChange():先做快照(保留最近 20 份,用于 Undo),写盘,然后用技能自带的脚本校验并重绘——plan.mjs,build.mjs --check,最后build.mjs --no-claude-md。若检查不通过(例如有规划文件落在任何节点的 glob 之外),快照会被回滚,并把问题回喂给模型重试一次。整个过程有并发保护:changing为真时再次提交会返回busy。只有声明了structured: true的引擎才会出现 Change 开关,因为整条链路依赖 CLI 严格遵守 schema。
更新、移除与本地副本
更新
在应用内打开Plugins,找到 Floorplan 市场,选择Upgrade;或在终端执行:
codex plugin marketplace upgrade floorplan codex plugin add floorplan@floorplan移除
codex plugin remove floorplan@floorplan codex plugin marketplace remove floorplan地图本身不受影响——它们留在各项目的floorplan/目录里,直到你主动删除。
试用本地工作副本
把 Codex 指向本地克隆而不是远端仓库:
codex plugin marketplace add /path/to/floorplan codex plugin add floorplan@floorplan这里有一个与 Claude Code 的重要差异:当添加本地插件时,Codex 会把插件复制进自己的缓存;Claude Code 则是直接从文件夹运行。这意味着你改完插件后必须重新执行codex plugin add floorplan@floorplan并开启新会话,改动才会生效。安装后的缓存路径形如~/.codex/plugins/cache/floorplan/floorplan/<version>(见 docs/is-it-safe.md),可用codex plugin list查看当前版本。
如果你在开发 Floorplan 本身,--agent claude|codex(在build.mjs上)与--engine claude|codex(在serve.mjs上)可以让你从任意环境模拟任一宿主的产物,这一点在 docs/development.md 中有说明。
命令速查
| 目的 | 命令 |
|---|---|
| 添加插件市场 | codex plugin marketplace add haydenschmitty/floorplan |
| 安装插件 | codex plugin add floorplan@floorplan |
| 升级市场 | codex plugin marketplace upgrade floorplan |
| 移除插件 | codex plugin remove floorplan@floorplan |
| 移除市场 | codex plugin marketplace remove floorplan |
| 自行启动地图服务 | node floorplan/serve.mjs |
| 强制走 Codex 作答 | node floorplan/serve.mjs --engine codex |
| 指定 Codex 可执行文件 | node floorplan/serve.mjs --codex /path/to/codex |
| 指定模型 | node floorplan/serve.mjs --model <name> |
| 停止后台服务 | node floorplan/serve.mjs --stop |
| 导出可分享副本 | node floorplan/serve.mjs --export [<file>] |
| 查看安装情况 | codex plugin list |
serve.mjs还接受--port(默认 4378,端口被占用时会自动往后试到 +20)、--no-open(不自动打开浏览器)与--idle-exit <分钟>(最后一个标签页关闭后多久退出,后台启动时open.mjs用的是 120 分钟)。
常见问题定位
- Ask 栏提示需要 Codex:服务在 PATH 中找不到
codex,且(Windows 上)也没找到桌面应用自带的 CLI。安装 Codex CLI,或用--codex /path/to/codex指定路径。 - 提示未登录:打开 Codex 应用,或在终端运行
codex login后用 ChatGPT 账号登录,然后重新提问。 - 地图没打开,或 Ask 在 Codex 打开地图后失效:Codex 在沙箱中执行命令,而地图服务需要持续运行并访问网络。在 Codex 询问时允许服务在沙箱外运行,或自己在项目目录里执行
node floorplan/serve.mjs。 node不被识别:安装 Node.js 18+,然后重启会话让 Codex 重新读取 PATH。- Change 开关不出现:它只出现在蓝图(从 PRD 规划出来的地图)上,且必须通过
node floorplan/serve.mjs打开、并且可用的引擎支持结构化输出。真实代码的地图没有 Change——先让 Codex 改代码,再更新地图。
更多排障条目见 docs/troubleshooting.md,安全性说明与可自行校验的安装指纹见 docs/is-it-safe.md,地图上每个按钮与面板的用法见 docs/using-the-map.md,地图是如何从扫描到渲染的见 docs/how-it-works.md。
【免费下载链接】floorplan
See how your app actually fits together. An interactive, plain-English map of your codebase, drawn by Claude or Codex.
相关推荐
Floorplan:用 Claude Code 或 Codex 为代码库生成可交互的「平面图」——从安装到源码级的完整指南
Floorplan:用 Claude Code 或 Codex 为代码库生成可交互的「平面图」——从安装到源码级的完整指南 导读 :Floorplan 是一个零
Floorplan 技能实战:用 architecture.json 与描述文件为代码库绘制可交互地图
Floorplan 技能实战:用 architecture.json 与描述文件为代码库绘制可交互地图 Floorplan 是一个面向 Claude Code
next-ai-draw-io 内置 Floorplan 户型家具图元库:45 种 mxgraph 图形在 AI 绘图中的接入与使用
next ai draw io 内置 Floorplan 户型家具图元库:45 种 mxgraph 图形在 AI 绘图中的接入与使用 本指南以 floorpla
人工智能AI 应用MCP 服务前端后端桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考