console: 按 Muse 网页端/桌面端视觉重做

仅视觉与布局改动,功能与 API 未改:全屏四栏(56px 图标栏 +
260px 列表 + 弹性对话 + 300px 右侧栏),左侧搜索 + 主要聊天
列表,中间灰/浅蓝气泡对话 + 圆角输入条,右侧头像 + 已连接
(真实 key/健康状态)+ 今天任务清单,下方仍可展开原详情。
旧 v3 松绿/朱印与顶部大标题栏已移除,产物为单文件
(316226 字节,sha f8fea987…,本地重建字节一致)。
console 标记单测未动,本地 53 项通过。
This commit is contained in:
host committed 2026-10-29 06:52:34 +08:00
1 parent 5ca5cc91cc
commit 66790b5123
12 files changed
+394 -227

No files matched your search

+27 -41
View File
@@ -2,33 +2,32 @@ 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 IconRail, { type View } from "./components/IconRail";
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";
import RightPanel from "./sections/RightPanel";
// 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.
// Layout only, Muse web/desktop style: no big header bar.
// Icon rail (56px) + left list (260px) + centre conversation (elastic,
// content centred) + right panel (300px, profile/today/detail). The
// centre top bar is minimal: a back arrow (back to the task view) on
// the left, and, only when the right panel is closed, a button to
// reopen it — the right panel's own X closes it. Selecting a task in
// the left list switches the centre conversation and the right detail
// to that task together; selecting a module switches the centre to
// that module and the right detail to its context.
export default function App() {
const store = useConsoleStore();
const [view, setView] = useState<View>("task");
const [rightOpen, setRightOpen] = useState(true);
useAutoRefresh((selectFocused) => store.refreshAll(selectFocused), 10000);
useIntervalMs(() => store.refreshSlow(), 60000);
@@ -46,40 +45,27 @@ export default function App() {
}
})();
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 />
<div className={"muse-app" + (rightOpen ? "" : " no-right")}>
<IconRail view={view} onSelect={setView} />
<aside className="list-col">
<TaskListSection onNew={() => setView("task")} />
</aside>
<main className="center-col">
<div className="center-topbar">
<button type="button" className="icon-btn" aria-label="返回任务" title="返回任务" onClick={() => setView("task")}>←</button>
{rightOpen ? <span className="muted">Codex 命令台</span> : (
<button type="button" onClick={() => setRightOpen(true)}>显示右侧栏</button>
)}
</div>
<div className="center-inner">{centre}</div>
</main>
<aside className="detail-col">{right}</aside>
{rightOpen ? (
<aside className="right-col">
<RightPanel view={view} onSelect={setView} onClose={() => setRightOpen(false)} />
</aside>
) : null}
</div>
</ConsoleContext.Provider>
);