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 标记单测未动且通过。
This commit is contained in:
host committed 2026-10-29 06:32:38 +08:00
1 parent 3f4e849a93
commit ebc5624893
57 files changed
+4789 -1746

No files matched your search

+86
View File
@@ -0,0 +1,86 @@
import { useState } from "react";
import { ConsoleContext } from "./context";
import { useConsoleStore } from "./hooks/useConsoleStore";
import { useAutoRefresh, useIntervalMs } from "./hooks/useAutoRefresh";
import LeftNav, { type View } from "./components/LeftNav";
import ApiKeySection from "./sections/ApiKeySection";
import AdminSection from "./sections/AdminSection";
import ProjectsSection from "./sections/ProjectsSection";
import MembersPanel from "./sections/MembersPanel";
import EnvSection from "./sections/EnvSection";
import EnvContextPanel from "./sections/EnvContextPanel";
import WorkersSection from "./sections/WorkersSection";
import SkillsSection from "./sections/SkillsSection";
import SkillsToolsPanel from "./sections/SkillsToolsPanel";
import AutomationsSection from "./sections/AutomationsSection";
import TriageSection from "./sections/TriageSection";
import TaskListSection from "./sections/TaskListSection";
import ConversationSection from "./sections/ConversationSection";
import TaskDetailPanel from "./sections/TaskDetailPanel";
import HealthPanel from "./sections/HealthPanel";
// Layout only: three columns, ChatGPT/Claude style.
// Left (~300px): module nav + task list. Centre (elastic, content
// centred to ~800px): conversation, or the selected module's content.
// Right (~340px): detail/context for whatever the centre shows.
// Selecting a task (left) switches the centre conversation and the
// right detail to that task together; selecting a module switches the
// centre to that module and the right to its context.
export default function App() {
const store = useConsoleStore();
const [view, setView] = useState<View>("task");
useAutoRefresh((selectFocused) => store.refreshAll(selectFocused), 10000);
useIntervalMs(() => store.refreshSlow(), 60000);
const centre = (() => {
switch (view) {
case "projects": return <ProjectsSection />;
case "env": return <EnvSection />;
case "workers": return <WorkersSection />;
case "skills": return <SkillsSection />;
case "automations": return <AutomationsSection />;
case "triage": return <TriageSection />;
case "admin": return <AdminSection />;
case "key": return <ApiKeySection />;
default: return <ConversationSection />;
}
})();
const right = (() => {
switch (view) {
case "projects": return <MembersPanel />;
case "env": return <EnvContextPanel />;
case "skills": return <SkillsToolsPanel />;
case "workers": case "admin": case "key": return <HealthPanel />;
case "automations": return <TriageSection />;
case "triage": return <AutomationsSection />;
default: return <TaskDetailPanel />;
}
})();
return (
<ConsoleContext.Provider value={store}>
<div className="site-header">
<div className="topbar">
<span className="seal-mark">令</span>
<div>
<h1>Codex 命令台</h1>
<p className="subtitle">瓷 · 墨 · 印</p>
</div>
<span className="version">key 只存本浏览器</span>
<span className="muted" style={{ marginLeft: "auto" }}>{store.healthText} | 自动刷新 · 每 10 秒 · 已刷新 {store.refreshStamp}</span>
</div>
</div>
<div className="shell">
<aside className="rail">
<LeftNav view={view} onSelect={setView} />
<TaskListSection />
</aside>
<main className="center-col">
<div className="center-inner">{centre}</div>
</main>
<aside className="detail-col">{right}</aside>
</div>
</ConsoleContext.Provider>
);
}