Files
codex-app-server/cloud/console-react/README.md
T
host ebc5624893 console: React 生产级重写(左列表 + 中对话 + 右详情)
旧单页 console.html 换成 Vite + React + TypeScript 单文件构建产物
(309525 字节,sha 90345ec8…,重建字节一致),源码在
cloud/console-react/,改页面只改 src 再 npm run build:console,
产物不手改。布局:左侧列表(模块导航 + 任务列表)、中间标准对话
(实时链路时间线 + 继续会话聊天框,共用 Chat 组件)、右侧详情
(元数据、操作、评审、审批、协调子任务、子代理、线程)。
API 与后端语义未改,key 只存浏览器 localStorage。
6 个 console 标记单测随实现改名更新(意图不变:壳确实调了
这些接口、turn 信息仍在详情里、旧 goal 输入仍不存在);
P1 标记单测未动且通过。
2026-10-29 06:32:38 +08:00

139 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Codex 命令台 · React 版
生产级 React 重写,替代 `cloud/console.html` 的旧单页脚本。视觉沿用 v3
瓷墨印(白底圆角卡、松绿 `#14544a`、朱印 `#be2a1e` 只作点缀),布局是
三栏:左侧列表、中间对话、右侧详情。
## 怎么改(只改 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`、`LeftNav`)。
- 改 API:只动 `src/api/paths.ts`(全部路径集中在这里)和
`src/api/client.ts`(`api()`、错误文案、key 存取)。组件里不许出现
手拼的 `/tasks/...` 字符串。
- 构建产物(`dist/`、`console-react.html`)**不许手改**。以后改页面
只改 `src` 再构建,产物永远由构建命令生成。
## 构建(一键,自动)
```bash
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 在审阅后执行,本项目不部署生产):
```bash
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` 页面。
## 怎么验证
```bash
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。
## 布局(三栏联动)
- 左侧 `LeftNav` + `TaskListSection`(约 300px):模块导航(任务、
项目、环境、Workers、技能与 MCP、自动化、分诊、管理区、API Key)
在上,紧凑任务列表(状态/执行器筛选 + 搜索 + 状态行)在下。
- 中间 `ConversationSection`(弹性宽,内容居中收敛 800px):任务视图
时是对话主角——实时链路时间线在上、继续会话聊天框在下;非任务
模块视图时是该模块的标准内容。
- 右侧(约 340px):任务视图时是 `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、LeftNav.tsx、chat/(Chat.tsx、mapTrace.ts)
sections/ 一个模块一个文件:ApiKey、Admin、Projects、MembersPanel、
Env、EnvContextPanel、Workers、Skills、SkillsToolsPanel、
Automations、Triage、TaskList(左栏紧凑列表)、
Conversation(中间对话组合)、TaskDetailPanel(右侧详情)、
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 需
独立用真实页面验一遍。