Files
codex-app-server/cloud/console-react
host 994c4ea5d1 console: 任务详情自动显示成本明细
打开详情就自动拉 GET /tasks/{id}/cost(不再只靠
“查成本”按钮出 JSON),详情顶部新一行:美元、总
token(实际/估算、缓存、无价单列)、轮数、fallback
次数;美元小于 1 美分时用 4 位小数,避免小任务
显示成 $0.00 误导成免费;加载中/失败有各自的
弱化文案,成本拉失败不影响详情其它内容;原
“查成本”按钮不动,仍可手动拉原始 JSON。
服务端不用改:成本接口与 _get_task 的 token 聚合
都已在 #150 / 详情 meta 那单里就位。
2026-10-30 00:39:13 +08:00
..

Codex 命令台 · React 版

生产级 React 重写,替代 cloud/console.html 的旧单页脚本。视觉以 Muse 网页端/桌面端截图为准(2026-10-29 改版,取代此前的 v3 瓷墨印): 白底、细线分隔、无大标题栏;左侧图标栏 + 列表、中间对话、右侧 个人资料/今天/详情。颜色:文字 #1d2129、灰 #667085、线 #e4e7ec、助手气泡 #f2f2f2、用户气泡 #bfe0ff、蓝 #3b82f6、 已连接绿 #22c55e。

怎么改(只改 src,不改产物)

  • 改一个模块:只动 src/sections/<模块>.tsx,需要新数据时先在 src/api/types.ts 加类型、再在对应 src/hooks/use*.ts 里加 loader, 不要在组件里拼 URL 或各写一份请求。
  • 改通用样式/组件:src/tokens.css(唯一 token 源)或 src/components/ 下的共享组件(Card、DataList、StatusPill、 ChatList/ChatBubble/ChatInput、IconRail)。
  • 改 API:只动 src/api/paths.ts(全部路径集中在这里)和 src/api/client.ts(api()、错误文案、key 存取)。组件里不许出现 手拼的 /tasks/... 字符串。
  • 构建产物(dist/、console-react.html)不许手改。以后改页面 只改 src 再构建,产物永远由构建命令生成。

构建(一键,自动)

npm install
npm run build:console

npm run build:console = tsc -b && vite build(vite-plugin-singlefile 把 JS/CSS 全部内联成一个 dist/index.html),再由 scripts/copy-build.mjs 原样拷到 ../console-redesign/console-react.html(审阅用),并打印字节数与 sha256。脚本不改动产物内容。

自动部署链路(不留手工步骤)

改 src → npm run build:console → 产物拷到 cloud/console.html → 提交 → 部署

具体到仓库里的一步(由主 agent 在审阅后执行,本项目不部署生产):

cp console-redesign/console-react.html <仓库>/cloud/console.html
# 或在仓库分支里直接用构建产物覆盖 cloud/console.html
git add cloud/console.html && git commit -m "console: React 版"
# 随后走仓库已有的 PR → CI → 合并 → deploy.py git 模式部署

服务端无需改动:cloud/server.py 的 GET /console 本来就是每次请求 现读 cloud/console.html 这一个文件,无静态资源路由、无需重启。 产物是单文件、无外部 /assets/*、无外部字体/图片引用(唯一的 url(...) 是内联 SVG 下拉箭头),交给主 agent 就能直接部署到现有 /console 页面。

怎么验证

npm run build:console   # 必须 0 退出,tsc 无错误
ls -l ../console-redesign/console-react.html
sha256sum ../console-redesign/console-react.html
grep -E 'src="/assets|href="/assets' ../console-redesign/console-react.html  # 应无输出

部署后另行核对(主 agent 执行):公网 /console 的字节数/sha 与 构建产物一致、/health 正常、4 个服务 active。不要用真实 API key 做验证调用;本地构建验证不需要 key。

布局(Muse 式四栏联动)

  • 最左图标栏 IconRail(56px):每模块一个内联 SVG 图标,点 图标切换模块;手机上隐藏。
  • 左侧列表 TaskListSection(260px):顶部圆角搜索框(即原有 任务搜索),主要聊天 标题 + +(切到任务视图),状态/执行器 筛选紧凑行在下,任务列表行是 prompt 单行截断 + 状态点/id/状态/ 执行器,选中行灰底高亮。
  • 中间 ConversationSection(弹性宽,内容居中收敛 760px):顶部 只有返回箭头(回任务视图)和右侧栏开关,没有大标题栏;任务视图 时是对话主角——实时链路时间线在上、继续会话聊天框在下,气泡为 助手灰左、用户浅蓝右;非任务模块视图时是该模块的标准内容。
  • 右侧 RightPanel(300px):顶部 X 关闭本栏,圆形头像(字母 C, 无外部图片)+ Codex 命令台 + 真实连接状态(有 key 为绿字 已连接,否则未连接)+ 健康/配额/刷新时间;图标快捷行;今天 列表(最近 10 条任务,勾选圈 + 粗标题 + 灰副标题 + 右侧时间, 点一条切到该任务);下方可折叠的详情区:任务视图时是 TaskDetailPanel,模块视图时是该模块的上下文(项目→成员、 环境→仓库绑定、技能→MCP 操作、Workers/管理区/API Key→健康与 配额、自动化↔分诊互为上下文)。
  • 联动:左点任务 → showDetail(id) → 中间对话与右侧详情同时切到 该任务;左点模块 → 中间与右侧同时切到该模块。平板(≤1240px) 右侧整行落到下方;手机(≤900px)单列,依次是图标栏(隐藏)、 列表、对话、详情,聊天输入条 position: sticky; bottom: 0,在 手机上也固定在底部可用。

对话与详情的分工(什么进对话、什么进详情)

  • 进对话(src/components/chat/ 共享组件):任务 prompt(用户气泡)、 trace 的 message 条目(助手气泡)、exec/file/tool/call(工具气泡)、 plan/reasoning/agent-start/agent-done(居中状态提示)、继续/后续 消息(用户气泡)。流式追加、底部自动跟随、往上翻暂停跟随。
  • 进详情(右侧,不塞进气泡):状态/模型/强度/执行器/项目/turn/ 主机/PR/更新、结果/错误文本、fork/重试/取消/合并/提 PR/查成本、 评审、审批、协调子任务、子代理、线程操作、自动化、分诊。
  • 聊天发送只用已有接口,不造新接口:终态任务 → POST /tasks/:id/continue(只发 message,其余选项留空即沿用任务原值, 与 live 继续表单全留空等价);运行中/排队中 → POST /tasks/:id/followups(mode: "direct");merged/merge-failed 不可发送。trace 映射只按 live 的 kind 分角色,trace 条目本身没有 时间戳与发送方字段,所以不编造时间顺序:followup 气泡排在 trace 助手消息之后,而不是假装交错排序。

目录与职责

src/
  api/        client.ts(api()、key、错误文案、工具函数)
              paths.ts(全部 API 路径,唯一来源)
              types.ts(全部实体与表单类型)
  hooks/      useCatalog.ts(key/配额/健康/项目/worker/环境/成员/技能/模型/仓库/管理区)
              useTaskList.ts(任务列表、筛选、派发)
              useTaskDetail.ts(任务详情、trace SSE、聊天发送、全部详情子列表)
              useProjectTools.ts(自动化、分诊)
              useConsoleStore.ts(胶水:把上面合成 ConsoleCtx + 自动刷新策略)
              useAutoRefresh.ts(10s/60s 定时器、select 焦点保护)
  components/ Card.tsx、lists.tsx(DataList/StatusPill)、notes.tsx、
              controls.tsx、IconRail.tsx(含 ModuleIcon)、chat/(Chat.tsx、mapTrace.ts)
  sections/   一个模块一个文件:ApiKey、Admin、Projects、MembersPanel、
              Env、EnvContextPanel、Workers、Skills、SkillsToolsPanel、
              Automations、Triage、TaskList(左栏列表)、
              Conversation(中间对话组合)、TaskDetailPanel(右侧详情)、
              RightPanel(右侧个人资料/今天/详情)、
              Dispatch(派发,挂在对话上方作为新会话入口)
              detail/(TracePanel、ContinuePanel、DetailActions、
              ReviewPanel、DetailLists、ProjectToolsPanels)
  context.ts  ConsoleCtx 类型与 React context(不含业务逻辑)
  App.tsx     只做布局与组合:四栏 + Provider + 定时器接入
  tokens.css  唯一 token 源:颜色、圆角、间距、40px 控件、断点

已知边界(诚实版)

  • 左栏任务列表是紧凑行(id/状态/prompt/执行器),live 的 9 列 表格(turn、root turn、主机、PR、更新)不在左栏,改在右侧详情 里展示——这是 300px 左栏放不下表格的取舍,不是功能删除。
  • 继续聊天只发 message:live 继续表单里的模型/强度/权限/子任务 覆盖项在聊天框里没有入口,发送即沿用任务原值;需要覆盖时仍 是后端原有语义,未改动。
  • 本地构建验证未接真实后端(无 key 调用),上线前主 agent 需 独立用真实页面验一遍。