Merge pull request #125 from openqj/feat-console-muse-style

console: 按 Muse 网页端/桌面端视觉重做
This commit is contained in:
openqj authored and GitHub committed 2026-10-29 06:58:11 +08:00
commit 811912c841
12 files changed
+394 -227

No files matched your search

+33 -20
View File
@@ -1,8 +1,11 @@
# Codex 命令台 · React 版 # Codex 命令台 · React 版
生产级 React 重写,替代 `cloud/console.html` 的旧单页脚本。视觉沿用 v3 生产级 React 重写,替代 `cloud/console.html` 的旧单页脚本。视觉以 Muse
瓷墨印(白底圆角卡、松绿 `#14544a`、朱印 `#be2a1e` 只作点缀),布局是 网页端/桌面端截图为准(2026-10-29 改版,取代此前的 v3 瓷墨印):
三栏:左侧列表、中间对话、右侧详情。 白底、细线分隔、无大标题栏;左侧图标栏 + 列表、中间对话、右侧
个人资料/今天/详情。颜色:文字 `#1d2129`、灰 `#667085`、线
`#e4e7ec`、助手气泡 `#f2f2f2`、用户气泡 `#bfe0ff`、蓝 `#3b82f6`、
已连接绿 `#22c55e`。
## 怎么改(只改 src,不改产物) ## 怎么改(只改 src,不改产物)
@@ -11,7 +14,7 @@
不要在组件里拼 URL 或各写一份请求。 不要在组件里拼 URL 或各写一份请求。
- 改通用样式/组件:`src/tokens.css`(唯一 token 源)或 - 改通用样式/组件:`src/tokens.css`(唯一 token 源)或
`src/components/` 下的共享组件(`Card`、`DataList`、`StatusPill`、 `src/components/` 下的共享组件(`Card`、`DataList`、`StatusPill`、
`ChatList`/`ChatBubble`/`ChatInput`、`LeftNav`)。 `ChatList`/`ChatBubble`/`ChatInput`、`IconRail`)。
- 改 API:只动 `src/api/paths.ts`(全部路径集中在这里)和 - 改 API:只动 `src/api/paths.ts`(全部路径集中在这里)和
`src/api/client.ts`(`api()`、错误文案、key 存取)。组件里不许出现 `src/api/client.ts`(`api()`、错误文案、key 存取)。组件里不许出现
手拼的 `/tasks/...` 字符串。 手拼的 `/tasks/...` 字符串。
@@ -65,22 +68,31 @@ grep -E 'src="/assets|href="/assets' ../console-redesign/console-react.html #
构建产物一致、`/health` 正常、4 个服务 active。不要用真实 API key 构建产物一致、`/health` 正常、4 个服务 active。不要用真实 API key
做验证调用;本地构建验证不需要 key。 做验证调用;本地构建验证不需要 key。
## 布局(三栏联动) ## 布局(Muse 式四栏联动)
- 左侧 `LeftNav` + `TaskListSection`(约 300px):模块导航(任务、 - 最左图标栏 `IconRail`(56px):每模块一个内联 SVG 图标,点
项目、环境、Workers、技能与 MCP、自动化、分诊、管理区、API Key) 图标切换模块;手机上隐藏。
在上,紧凑任务列表(状态/执行器筛选 + 搜索 + 状态行)在下。 - 左侧列表 `TaskListSection`(260px):顶部圆角搜索框(即原有
- 中间 `ConversationSection`(弹性宽,内容居中收敛 800px):任务视图 任务搜索),`主要聊天` 标题 + `+`(切到任务视图),状态/执行器
时是对话主角——实时链路时间线在上、继续会话聊天框在下;非任务 筛选紧凑行在下,任务列表行是 prompt 单行截断 + 状态点/id/状态/
模块视图时是该模块的标准内容。 执行器,选中行灰底高亮。
- 右侧(约 340px):任务视图时是 `TaskDetailPanel`(元数据、操作、 - 中间 `ConversationSection`(弹性宽,内容居中收敛 760px):顶部
结果/错误、评审、审批、协调子任务、子代理、线程、成本);模块视图 只有返回箭头(回任务视图)和右侧栏开关,没有大标题栏;任务视图
时是该模块的上下文(项目→成员、环境→仓库绑定、技能→MCP 操作、 时是对话主角——实时链路时间线在上、继续会话聊天框在下,气泡为
Workers/管理区/API Key→健康与配额、自动化↔分诊互为上下文)。 助手灰左、用户浅蓝右;非任务模块视图时是该模块的标准内容。
- 右侧 `RightPanel`(300px):顶部 X 关闭本栏,圆形头像(字母 C,
无外部图片)+ `Codex 命令台` + 真实连接状态(有 key 为绿字
已连接,否则未连接)+ 健康/配额/刷新时间;图标快捷行;`今天`
列表(最近 10 条任务,勾选圈 + 粗标题 + 灰副标题 + 右侧时间,
点一条切到该任务);下方可折叠的详情区:任务视图时是
`TaskDetailPanel`,模块视图时是该模块的上下文(项目→成员、
环境→仓库绑定、技能→MCP 操作、Workers/管理区/API Key→健康与
配额、自动化↔分诊互为上下文)。
- 联动:左点任务 → `showDetail(id)` → 中间对话与右侧详情同时切到 - 联动:左点任务 → `showDetail(id)` → 中间对话与右侧详情同时切到
该任务;左点模块 → 中间与右侧同时切到该模块。平板(≤1240px) 该任务;左点模块 → 中间与右侧同时切到该模块。平板(≤1240px)
右侧整行落到下方;手机(≤900px)单列,依次是列表、对话、详情, 右侧整行落到下方;手机(≤900px)单列,依次是图标栏(隐藏)、
聊天输入条 `position: sticky; bottom: 0`,在手机上也固定在底部可用。 列表、对话、详情,聊天输入条 `position: sticky; bottom: 0`,在
手机上也固定在底部可用。
## 对话与详情的分工(什么进对话、什么进详情) ## 对话与详情的分工(什么进对话、什么进详情)
@@ -113,16 +125,17 @@ src/
useConsoleStore.ts(胶水:把上面合成 ConsoleCtx + 自动刷新策略) useConsoleStore.ts(胶水:把上面合成 ConsoleCtx + 自动刷新策略)
useAutoRefresh.ts(10s/60s 定时器、select 焦点保护) useAutoRefresh.ts(10s/60s 定时器、select 焦点保护)
components/ Card.tsx、lists.tsx(DataList/StatusPill)、notes.tsx、 components/ Card.tsx、lists.tsx(DataList/StatusPill)、notes.tsx、
controls.tsx、LeftNav.tsx、chat/(Chat.tsx、mapTrace.ts) controls.tsx、IconRail.tsx(含 ModuleIcon)、chat/(Chat.tsx、mapTrace.ts)
sections/ 一个模块一个文件:ApiKey、Admin、Projects、MembersPanel、 sections/ 一个模块一个文件:ApiKey、Admin、Projects、MembersPanel、
Env、EnvContextPanel、Workers、Skills、SkillsToolsPanel、 Env、EnvContextPanel、Workers、Skills、SkillsToolsPanel、
Automations、Triage、TaskList(左栏紧凑列表)、 Automations、Triage、TaskList(左栏列表)、
Conversation(中间对话组合)、TaskDetailPanel(右侧详情)、 Conversation(中间对话组合)、TaskDetailPanel(右侧详情)、
RightPanel(右侧个人资料/今天/详情)、
Dispatch(派发,挂在对话上方作为新会话入口) Dispatch(派发,挂在对话上方作为新会话入口)
detail/(TracePanel、ContinuePanel、DetailActions、 detail/(TracePanel、ContinuePanel、DetailActions、
ReviewPanel、DetailLists、ProjectToolsPanels) ReviewPanel、DetailLists、ProjectToolsPanels)
context.ts ConsoleCtx 类型与 React context(不含业务逻辑) context.ts ConsoleCtx 类型与 React context(不含业务逻辑)
App.tsx 只做布局与组合:三栏 + Provider + 定时器接入 App.tsx 只做布局与组合:四栏 + Provider + 定时器接入
tokens.css 唯一 token 源:颜色、圆角、间距、40px 控件、断点 tokens.css 唯一 token 源:颜色、圆角、间距、40px 控件、断点
``` ```
+27 -41
View File
@@ -2,33 +2,32 @@ import { useState } from "react";
import { ConsoleContext } from "./context"; import { ConsoleContext } from "./context";
import { useConsoleStore } from "./hooks/useConsoleStore"; import { useConsoleStore } from "./hooks/useConsoleStore";
import { useAutoRefresh, useIntervalMs } from "./hooks/useAutoRefresh"; 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 ApiKeySection from "./sections/ApiKeySection";
import AdminSection from "./sections/AdminSection"; import AdminSection from "./sections/AdminSection";
import ProjectsSection from "./sections/ProjectsSection"; import ProjectsSection from "./sections/ProjectsSection";
import MembersPanel from "./sections/MembersPanel";
import EnvSection from "./sections/EnvSection"; import EnvSection from "./sections/EnvSection";
import EnvContextPanel from "./sections/EnvContextPanel";
import WorkersSection from "./sections/WorkersSection"; import WorkersSection from "./sections/WorkersSection";
import SkillsSection from "./sections/SkillsSection"; import SkillsSection from "./sections/SkillsSection";
import SkillsToolsPanel from "./sections/SkillsToolsPanel";
import AutomationsSection from "./sections/AutomationsSection"; import AutomationsSection from "./sections/AutomationsSection";
import TriageSection from "./sections/TriageSection"; import TriageSection from "./sections/TriageSection";
import TaskListSection from "./sections/TaskListSection"; import TaskListSection from "./sections/TaskListSection";
import ConversationSection from "./sections/ConversationSection"; import ConversationSection from "./sections/ConversationSection";
import TaskDetailPanel from "./sections/TaskDetailPanel"; import RightPanel from "./sections/RightPanel";
import HealthPanel from "./sections/HealthPanel";
// Layout only: three columns, ChatGPT/Claude style. // Layout only, Muse web/desktop style: no big header bar.
// Left (~300px): module nav + task list. Centre (elastic, content // Icon rail (56px) + left list (260px) + centre conversation (elastic,
// centred to ~800px): conversation, or the selected module's content. // content centred) + right panel (300px, profile/today/detail). The
// Right (~340px): detail/context for whatever the centre shows. // centre top bar is minimal: a back arrow (back to the task view) on
// Selecting a task (left) switches the centre conversation and the // the left, and, only when the right panel is closed, a button to
// right detail to that task together; selecting a module switches the // reopen it — the right panel's own X closes it. Selecting a task in
// centre to that module and the right to its context. // 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() { export default function App() {
const store = useConsoleStore(); const store = useConsoleStore();
const [view, setView] = useState<View>("task"); const [view, setView] = useState<View>("task");
const [rightOpen, setRightOpen] = useState(true);
useAutoRefresh((selectFocused) => store.refreshAll(selectFocused), 10000); useAutoRefresh((selectFocused) => store.refreshAll(selectFocused), 10000);
useIntervalMs(() => store.refreshSlow(), 60000); 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 ( return (
<ConsoleContext.Provider value={store}> <ConsoleContext.Provider value={store}>
<div className="site-header"> <div className={"muse-app" + (rightOpen ? "" : " no-right")}>
<div className="topbar"> <IconRail view={view} onSelect={setView} />
<span className="seal-mark">令</span> <aside className="list-col">
<div> <TaskListSection onNew={() => setView("task")} />
<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> </aside>
<main className="center-col"> <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> <div className="center-inner">{centre}</div>
</main> </main>
<aside className="detail-col">{right}</aside> {rightOpen ? (
<aside className="right-col">
<RightPanel view={view} onSelect={setView} onClose={() => setRightOpen(false)} />
</aside>
) : null}
</div> </div>
</ConsoleContext.Provider> </ConsoleContext.Provider>
); );
@@ -0,0 +1,47 @@
import type { ReactNode } from "react";
// Far-left icon rail from the Muse screenshot: one simple inline-SVG
// icon per module, no emoji, no external image. This replaces LeftNav
// as the module switcher; the left list panel below it is the task list.
export type View = "task" | "projects" | "env" | "workers" | "skills" | "automations" | "triage" | "admin" | "key";
function Svg({ children }: { children: ReactNode }) {
return (
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
{children}
</svg>
);
}
export function ModuleIcon({ view }: { view: View }) {
switch (view) {
case "task": return <Svg><path d="M21 11.5a8.5 8.5 0 0 1-12.4 7.5L3 21l2-5.6A8.5 8.5 0 1 1 21 11.5Z" /></Svg>;
case "projects": return <Svg><path d="M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8Z" /><path d="M14 3v5h5" /><path d="M9 13h6M9 17h6" /></Svg>;
case "env": return <Svg><path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z" /></Svg>;
case "workers": return <Svg><rect x="3" y="3" width="7" height="7" rx="1.5" /><rect x="14" y="3" width="7" height="7" rx="1.5" /><rect x="3" y="14" width="7" height="7" rx="1.5" /><rect x="14" y="14" width="7" height="7" rx="1.5" /></Svg>;
case "skills": return <Svg><path d="M9 18h6M10 21h4" /><path d="M12 3a6 6 0 0 0-3.5 10.8c.8.6 1.5 1.4 1.5 2.2h4c0-.8.7-1.6 1.5-2.2A6 6 0 0 0 12 3Z" /></Svg>;
case "automations": return <Svg><circle cx="12" cy="12" r="9" /><path d="M12 7v5l3 2" /></Svg>;
case "triage": return <Svg><circle cx="12" cy="12" r="9" /><path d="M8 12.5l2.5 2.5L16 9.5" /></Svg>;
case "admin": return <Svg><path d="M12 3l7 3v5c0 5-3.5 8-7 9-3.5-1-7-4-7-9V6Z" /><path d="M9 12l2 2 4-4" /></Svg>;
case "key": return <Svg><circle cx="8" cy="15" r="4" /><path d="M11.5 11.5L20 3" /><path d="M17 6l2 2M20 3l-1 3" /></Svg>;
default: return <Svg><circle cx="12" cy="12" r="9" /></Svg>;
}
}
const ITEMS: Array<[View, string]> = [
["task", "任务"], ["projects", "项目"], ["env", "环境"], ["workers", "Workers"],
["skills", "技能与 MCP"], ["automations", "自动化"], ["triage", "分诊"],
["admin", "管理区"], ["key", "API Key"],
];
export default function IconRail({ view, onSelect }: { view: View; onSelect: (v: View) => void }) {
return (
<nav className="icon-rail" aria-label="模块快捷方式">
{ITEMS.map(([v, label]) => (
<button key={v} type="button" title={label} aria-label={label} className={view === v ? "active" : ""} onClick={() => onSelect(v)}>
<ModuleIcon view={v} />
</button>
))}
</nav>
);
}
@@ -1,17 +0,0 @@
export type View = "task" | "projects" | "env" | "workers" | "skills" | "automations" | "triage" | "admin" | "key";
const ITEMS: Array<[View, string]> = [
["task", "任务"], ["projects", "项目"], ["env", "环境"], ["workers", "Workers"],
["skills", "技能与 MCP"], ["automations", "自动化"], ["triage", "分诊"],
["admin", "管理区"], ["key", "API Key"],
];
export default function LeftNav({ view, onSelect }: { view: View; onSelect: (v: View) => void }) {
return (
<nav className="left-nav" aria-label="模块导航">
{ITEMS.map(([v, label]) => (
<button key={v} className={view === v ? "active" : ""} onClick={() => onSelect(v)}>{label}</button>
))}
</nav>
);
}
@@ -54,19 +54,25 @@ export function ChatInput({ onSend, disabled, placeholder }: {
onSend(v); onSend(v);
setText(""); setText("");
}; };
// Pill input bar, Muse screenshot style: the textarea is the pill
// itself, and send is a light-blue circular arrow. No mic or
// attachment button here: the continue chat has no voice or
// attachment API (attachments live in Dispatch), so a mic/+ icon
// would be a dead button; the left list header's + is the new-task
// entry instead.
return ( return (
<div className="chat-input-bar"> <div className="chat-input-bar">
<textarea <textarea
aria-label="会话输入" aria-label="会话输入"
className="chat-input" className="chat-input"
rows={1} rows={1}
placeholder={placeholder || "输入消息,回车发送,Shift+回车换行"} placeholder={placeholder || "消息"}
value={text} value={text}
disabled={disabled} disabled={disabled}
onChange={(e) => setText(e.target.value)} onChange={(e) => setText(e.target.value)}
onKeyDown={(e) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); send(); } }} onKeyDown={(e) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); send(); } }}
/> />
<button className="primary chat-send" disabled={disabled || !text.trim()} onClick={send}>发送</button> <button type="button" className="chat-send" aria-label="发送" disabled={disabled || !text.trim()} onClick={send}>↑</button>
</div> </div>
); );
} }
@@ -19,7 +19,7 @@ export default function ConversationSection() {
return ( return (
<div className="conversation"> <div className="conversation">
<TracePanel /> <TracePanel />
<h3>继续会话</h3> <div className="conv-divider" />
<ContinuePanel /> <ContinuePanel />
</div> </div>
); );
@@ -0,0 +1,86 @@
import { useConsole } from "../context";
import { ModuleIcon, type View } from "../components/IconRail";
import { shortId } from "../api/client";
import TaskDetailPanel from "./TaskDetailPanel";
import MembersPanel from "./MembersPanel";
import EnvContextPanel from "./EnvContextPanel";
import SkillsToolsPanel from "./SkillsToolsPanel";
import HealthPanel from "./HealthPanel";
import AutomationsSection from "./AutomationsSection";
import TriageSection from "./TriageSection";
// Right panel, modelled on the Muse screenshot: profile header with a
// real connection status (API key / health, never a fake user), an icon
// row that switches modules, a 今天 list of recent tasks, and below it
// the selected task's detail (or the current module's context) as a
// collapsible section. Nothing that was in the old right column is
// dropped: the detail/context panels are the same components, only
// rendered inside <details> under the today list.
export default function RightPanel({ view, onSelect, onClose }: {
view: View; onSelect: (v: View) => void; onClose: () => void;
}) {
const ctx = useConsole();
const connected = ctx.keySaved;
const today = ctx.tasks.slice().reverse().slice(0, 10);
const context = (() => {
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 />;
}
})();
const iconRow: Array<[View, string]> = [["task", "任务"], ["admin", "管理区"], ["automations", "自动化"], ["key", "API Key"]];
return (
<div>
<div className="right-profile">
<button type="button" className="icon-btn" aria-label="关闭右侧栏" onClick={onClose}>×</button>
<div className="right-avatar" aria-hidden="true">C</div>
<div className="right-name">Codex 命令台</div>
<div className={connected ? "right-status" : "right-status off"}>
{connected ? "● 已连接" : "○ 未连接(先在 API Key 里保存 key)"}
</div>
<div className="muted">{ctx.healthText}</div>
<div className="muted">{ctx.quotaText}</div>
<div className="muted">自动刷新 · 每 10 秒 · 已刷新 {ctx.refreshStamp}</div>
</div>
<div className="right-icon-row" aria-label="快捷方式">
{iconRow.map(([v, label]) => (
<button key={v} type="button" title={label} aria-label={label} className={view === v ? "active" : ""} onClick={() => onSelect(v)}>
<ModuleIcon view={v} />
</button>
))}
</div>
<div>
<div className="list-section-head"><span>今天</span></div>
{today.length === 0 ? (
<div className="muted">今天暂无任务</div>
) : (
<ul className="today-list">
{today.map((t) => {
const done = t.status === "completed" || t.status === "merged";
const time = t.updated_at ? new Date(t.updated_at * 1000).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) : "";
return (
<li key={t.id} className="today-item" onClick={() => { ctx.showDetail(t.id); onSelect("task"); }}>
<span className={"today-check" + (done ? " done" : "")}>{done ? "✓" : ""}</span>
<span className="today-item-main">
<span className="today-item-title">{String(t.prompt || shortId(t.id)).slice(0, 60) || shortId(t.id)}</span>
<span className="today-item-sub">{shortId(t.id)} · <span className={"st-" + t.status}>{t.status}</span> · {t.executor || ""}</span>
</span>
<span className="today-item-time">{time}</span>
</li>
);
})}
</ul>
)}
</div>
<details className="right-detail" open>
<summary>{view === "task" ? "任务详情" : "模块详情"}</summary>
{context}
</details>
</div>
);
}
@@ -1,15 +1,28 @@
import { useConsole } from "../context"; import { useConsole } from "../context";
import { DataListRaw } from "../components/ui";
import { shortId } from "../api/client"; import { shortId } from "../api/client";
// Left-rail compact task list. The live 9-column table does not fit a // Left list panel, Muse screenshot style: rounded search on top, a
// 300px rail, so the rail shows id + status + prompt + executor; the // 主要聊天 section header with a + button, then the task list. The
// full metadata (turn, root turn, host, PR, updated) lives in the right // search input IS the existing task search (id/prompt); the status and
// detail panel for the selected task. Filters/search are the live ones. // executor filters are kept as a compact row below it — the screenshot
export default function TaskListSection() { // has no filters, but dropping them would cut functionality, so they
// stay, just compact. List rows show the prompt truncated on one line
// with a status dot, short id, status and executor below it; the
// selected row is highlighted grey, as in the screenshot.
export default function TaskListSection({ onNew }: { onNew: () => void }) {
const ctx = useConsole(); const ctx = useConsole();
return ( return (
<div className="left-tasks"> <div>
<div className="search-box">
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" aria-hidden="true">
<circle cx="11" cy="11" r="7" /><path d="M21 21l-4.3-4.3" />
</svg>
<input type="text" placeholder="搜索" aria-label="搜索任务" value={ctx.searchText} onChange={(e) => ctx.setSearchText(e.target.value)} />
</div>
<div className="list-section-head">
<span>主要聊天</span>
<button type="button" aria-label="派发新任务" title="派发新任务" onClick={onNew}>+</button>
</div>
<div className="bar"> <div className="bar">
<select aria-label="状态筛选" value={ctx.statusFilter} onChange={(e) => ctx.setStatusFilter(e.target.value)}> <select aria-label="状态筛选" value={ctx.statusFilter} onChange={(e) => ctx.setStatusFilter(e.target.value)}>
<option value="">状态:全部</option> <option value="">状态:全部</option>
@@ -19,7 +32,6 @@ export default function TaskListSection() {
<option value="">执行器:全部</option><option value="local">local</option><option value="docker">docker</option><option value="cloud">cloud</option> <option value="">执行器:全部</option><option value="local">local</option><option value="docker">docker</option><option value="cloud">cloud</option>
</select> </select>
</div> </div>
<input type="text" placeholder="搜索任务 id / prompt" value={ctx.searchText} onChange={(e) => ctx.setSearchText(e.target.value)} />
<div className="bar"> <div className="bar">
<button onClick={ctx.refreshTasks}>刷新</button> <button onClick={ctx.refreshTasks}>刷新</button>
<span className="muted">{ctx.taskCountText}</span> <span className="muted">{ctx.taskCountText}</span>
@@ -28,18 +40,21 @@ export default function TaskListSection() {
: !ctx.projectId ? <div className="muted">先选项目</div> : !ctx.projectId ? <div className="muted">先选项目</div>
: ctx.filteredTasks.length === 0 ? <div className="muted">{ctx.tasks.length ? "没有符合筛选条件的任务" : "该项目暂无任务"}</div> : ctx.filteredTasks.length === 0 ? <div className="muted">{ctx.tasks.length ? "没有符合筛选条件的任务" : "该项目暂无任务"}</div>
: ( : (
<DataListRaw> <ul className="muse-list">
{ctx.filteredTasks.slice().reverse().map((t) => ( {ctx.filteredTasks.slice().reverse().map((t) => (
<li key={t.id} className={ctx.currentTask?.id === t.id ? "selected-task" : ""} onClick={() => ctx.showDetail(t.id)} style={{ cursor: "pointer" }}> <li key={t.id} className={"muse-item" + (ctx.currentTask?.id === t.id ? " selected" : "")} onClick={() => ctx.showDetail(t.id)}>
<span className="row-main"> <div className="muse-item-title">
<b>{shortId(t.id)}</b> <span className={"st-" + t.status}>{t.status}</span> {t.plan ? "[计划] " : ""}{t.forked_from ? "[分支] " : ""}{t.coordinator_parts ? "[协调] " : ""}{t.parent_task_id ? "[协调子任务] " : ""}{String(t.prompt || shortId(t.id)).slice(0, 60)}
<br /> </div>
{t.plan ? "[计划] " : ""}{t.forked_from ? "[分支] " : ""}{t.coordinator_parts ? "[协调] " : ""}{t.parent_task_id ? "[协调子任务] " : ""}{String(t.prompt || "").slice(0, 60)} <div className="muse-item-sub">
<br /><span className="muted">{t.executor || ""}</span> <span className={"task-dot st-" + t.status} />
</span> <span>{shortId(t.id)}</span>
<span className={"st-" + t.status}>{t.status}</span>
<span>{t.executor || ""}</span>
</div>
</li> </li>
))} ))}
</DataListRaw> </ul>
)} )}
</div> </div>
); );
@@ -38,7 +38,7 @@ export default function ContinuePanel() {
<ChatList messages={messages} empty="(暂无会话消息)" /> <ChatList messages={messages} empty="(暂无会话消息)" />
<ChatInput <ChatInput
disabled={!canSend} disabled={!canSend}
placeholder={hint + ",回车发送,Shift+回车换行"} placeholder="消息"
onSend={(text) => void ctx.sendChatMessage(text)} onSend={(text) => void ctx.sendChatMessage(text)}
/> />
<div className="muted">{hint}。{ctx.chatMsg}</div> <div className="muted">{hint}。{ctx.chatMsg}</div>
@@ -16,7 +16,7 @@ export default function TracePanel() {
}, [ctx.currentTask, ctx.traceEntries, ctx.traceKind, ctx.traceDone]); }, [ctx.currentTask, ctx.traceEntries, ctx.traceKind, ctx.traceDone]);
return ( return (
<> <>
<h3>实时链路</h3> <div className="muted">实时链路</div>
<Bar> <Bar>
<select aria-label="链路类型" value={ctx.traceKind} onChange={(e) => ctx.setTraceKind(e.target.value)}> <select aria-label="链路类型" value={ctx.traceKind} onChange={(e) => ctx.setTraceKind(e.target.value)}>
<option value="">链路类型:全部</option> <option value="">链路类型:全部</option>
+137 -106
View File
@@ -1,146 +1,177 @@
/* Single token source. Colours are the v3 porcelain/ink/seal set only: /* Single token source — Muse web/desktop palette (2026-10-29 redesign).
ink, paper, white cards, pine #14544a, seal #be2a1e as accent. This supersedes the previous v3 porcelain/ink/seal palette: white page,
No other coloured backgrounds. Spacing is an 8px grid. */ light-grey hairlines, grey assistant bubbles, light-blue user bubbles,
blue accent, green only for 已连接. The old pine/seal colours are gone;
the button class name "seal" is retained only so Dispatch/DetailActions
need no change — it now renders in screenshot blue. No coloured page
backgrounds, no big header bar, no shadows. Sans-serif only. */
:root{ :root{
--ink:#1c2220; --ink-soft:#4a554f; --paper:#f5f3ee; --card:#ffffff; --text:#1d2129; --muted:#667085; --line:#e4e7ec; --line-strong:#d0d5dd;
--line:#e6e1d6; --line-strong:#d3ccbc; --paper:#ffffff; --card:#ffffff;
--seal:#be2a1e; --seal-soft:#fdeeeb; --seal-dark:#9c2118; --bubble-assistant:#f2f2f2; --bubble-user:#bfe0ff;
--pine:#14544a; --pine-soft:#e2efea; --accent:#3b82f6; --accent-dark:#2563eb; --accent-soft:#eef4ff;
--amber:#92400e; --amber-soft:#fef3c7; --green:#22c55e; --success:#16a34a; --danger:#b42318; --danger-soft:#fef3f2;
--success:#15803d; --danger:#b42318; --danger-soft:#fef3f2; --purple:#6941c6; --amber:#b54708; --purple:#6941c6;
--radius:16px; --radius-sm:10px; --radius:12px; --radius-sm:10px; --shadow:none;
--shadow:0 1px 2px rgba(28,34,32,.05), 0 12px 32px rgba(28,34,32,.06);
--serif:"Songti SC","Noto Serif SC","SimSun",serif;
--sans:-apple-system,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif; --sans:-apple-system,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
--mono:"IBM Plex Mono",Menlo,Consolas,monospace; --mono:"IBM Plex Mono",Menlo,Consolas,monospace;
--ctl:40px; --ctl:40px;
} }
*{box-sizing:border-box} *{box-sizing:border-box}
body{font-family:var(--sans);margin:0;color:var(--ink);background:var(--paper);line-height:1.6;font-size:15px} html,body,#root{height:100%}
a{color:var(--pine);text-underline-offset:3px} body{font-family:var(--sans);margin:0;color:var(--text);background:#fff;line-height:1.6;font-size:14px}
:focus-visible{outline:3px solid var(--seal);outline-offset:2px} a{color:var(--accent);text-underline-offset:3px}
:focus-visible{outline:3px solid var(--accent);outline-offset:2px}
@media (prefers-reduced-motion:reduce){*{scroll-behavior:auto!important;transition:none!important}} @media (prefers-reduced-motion:reduce){*{scroll-behavior:auto!important;transition:none!important}}
.muted{color:#7a857e;font-size:13px;line-height:1.6} .muted{color:var(--muted);font-size:13px;line-height:1.6}
.err{color:var(--danger)} .ok{color:var(--success)} .err{color:var(--danger)} .ok{color:var(--success)}
/* Top bar + fixed nav */ button{cursor:pointer;font-weight:600;border-radius:999px}
.site-header{position:sticky;top:0;z-index:30;background:#fff} button:disabled{opacity:.45;cursor:not-allowed;box-shadow:none}
.topbar{display:flex;align-items:center;gap:16px;padding:16px 28px;background:#fff;border-bottom:1px solid var(--line)} button.primary{background:var(--accent);border-color:var(--accent);color:#fff}
.seal-mark{flex:none;width:38px;height:38px;background:var(--seal);color:#fff;display:grid;place-items:center;font-family:var(--serif);font-size:20px;font-weight:700;border-radius:8px} button.primary:hover{background:var(--accent-dark)}
.topbar h1{font-family:var(--serif);font-size:25px;line-height:1.15;margin:0;font-weight:700;letter-spacing:1px} /* "seal" is a legacy class name only; its colour is screenshot blue now. */
.topbar .subtitle{font-size:13px;color:#7a857e;margin:1px 0 0;letter-spacing:2px} button.seal{background:var(--accent);border-color:var(--accent);color:#fff}
.version{font-size:12px;color:#7a857e;border:1px solid var(--line);background:#fff;border-radius:999px;padding:6px 11px;white-space:nowrap} button.seal:hover{background:var(--accent-dark)}
.topnav{display:flex;gap:4px;flex-wrap:wrap;align-items:center;padding:8px 28px;background:#fff;border-bottom:1px solid var(--line);overflow-x:auto;scroll-margin-top:0} button.danger{color:var(--danger);border-color:#fecdca;background:var(--danger-soft)}
.topnav a{color:var(--ink-soft);text-decoration:none;font-size:13.5px;font-weight:600;padding:6px 10px;border-radius:999px;white-space:nowrap} button.danger:hover{background:#fee4e2}
.topnav a:hover{color:var(--ink);background:var(--pine-soft)} .icon-btn{width:32px;height:32px;padding:0;display:grid;place-items:center;border:1px solid var(--line);border-radius:50%;background:#fff;color:var(--text);font-size:16px;line-height:1}
.topnav a.active{color:var(--ink);font-weight:700} .icon-btn:hover{background:#f9fafb}
.topnav .auto-refresh{margin-left:auto;color:#7a857e;font-size:12px;white-space:nowrap}
section[id],div[id]{scroll-margin-top:130px} /* App shell: icon rail + list + conversation + right panel, full viewport.
/* Layout: three columns, ChatGPT/Claude style. Columns are separated by hairlines, not gaps or cards. */
Left 300px (nav + task list), centre elastic (content centred to .muse-app{display:grid;grid-template-columns:56px 260px minmax(0,1fr) 300px;height:100vh;background:#fff}
~800px), right 340px (detail/context). */ .muse-app.no-right{grid-template-columns:56px 260px minmax(0,1fr)}
.shell{display:grid;grid-template-columns:300px minmax(0,1fr) 340px;gap:20px;align-items:start;padding:24px 28px 48px} .icon-rail{border-right:1px solid var(--line);display:flex;flex-direction:column;align-items:center;gap:4px;padding:12px 0;overflow-y:auto}
.rail{display:flex;flex-direction:column;gap:20px;min-width:0} .icon-rail button{width:40px;height:40px;border:0;border-radius:12px;background:transparent;display:grid;place-items:center;color:var(--text);padding:0;flex:none}
.center-col{min-width:0} .icon-rail button:hover{background:#f2f2f2}
.center-inner{max-width:800px;margin:0 auto;width:100%;display:flex;flex-direction:column;gap:20px} .icon-rail button.active{background:var(--accent-soft);color:var(--accent)}
.detail-col{display:flex;flex-direction:column;gap:20px;min-width:0} .icon-rail svg{width:22px;height:22px}
.left-nav{display:flex;flex-direction:column;gap:8px} .list-col{border-right:1px solid var(--line);overflow-y:auto;padding:16px 12px;min-width:0}
.left-nav button{text-align:left;border-radius:12px;background:#fff} .search-box{display:flex;align-items:center;gap:8px;border:1px solid var(--line);border-radius:999px;padding:8px 12px;background:#fff}
.left-nav button.active{background:var(--ink);color:#fff;border-color:var(--ink)} .search-box svg{flex:none;color:var(--muted)}
.left-tasks input[type="text"]{width:100%} .search-box input{border:0;padding:0;flex:1;min-width:0;font-size:14px;background:transparent}
.selected-task{border-color:var(--seal)!important;background:var(--seal-soft)!important} .search-box input:focus{box-shadow:none;outline:none}
.conversation{display:flex;flex-direction:column;gap:20px} .list-section-head{display:flex;align-items:center;justify-content:space-between;padding:16px 4px 8px;font-weight:600;font-size:14px}
/* Cards: every module is one rounded independent white card */ .list-section-head button{width:28px;height:28px;padding:0;display:grid;place-items:center;border-radius:50%}
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow);padding:24px} .muse-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}
.card h2{font-family:var(--serif);font-size:18px;margin:0 0 12px;letter-spacing:.5px} .muse-item{padding:10px 12px;border-radius:12px;cursor:pointer;overflow:hidden}
.card h3{font-family:var(--serif);font-size:15px;margin:24px 0 12px;padding-top:20px;border-top:1px solid var(--line)} .muse-item:hover{background:#f9fafb}
.muse-item.selected{background:#f2f2f2}
.muse-item-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:14px}
.muse-item-sub{display:flex;gap:6px;align-items:center;color:var(--muted);font-size:12px;margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.task-dot{width:8px;height:8px;border-radius:50%;background:currentColor;flex:none}
.center-col{min-width:0;display:flex;flex-direction:column;overflow-y:auto;background:#fff}
.center-topbar{position:sticky;top:0;z-index:5;display:flex;align-items:center;justify-content:space-between;padding:12px 16px;background:#fff;border-bottom:1px solid var(--line)}
.center-inner{max-width:760px;margin:0 auto;width:100%;padding:24px 20px 16px;display:flex;flex-direction:column;gap:20px;flex:1}
.right-col{border-left:1px solid var(--line);overflow-y:auto;padding:20px 16px;display:flex;flex-direction:column;gap:20px;min-width:0}
.right-profile{text-align:center;position:relative}
.right-profile .icon-btn{position:absolute;top:0;right:0}
.right-avatar{width:72px;height:72px;border-radius:50%;background:var(--accent-soft);color:var(--accent);display:grid;place-items:center;font-size:28px;font-weight:700;margin:0 auto}
.right-name{font-weight:700;font-size:17px;margin-top:10px}
.right-status{color:var(--green);font-size:13px;font-weight:600}
.right-status.off{color:var(--muted)}
.right-icon-row{display:flex;gap:4px;justify-content:space-between;border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding:10px 4px}
.right-icon-row button{width:36px;height:36px;border:0;border-radius:12px;background:transparent;display:grid;place-items:center;color:var(--text);padding:0}
.right-icon-row button:hover{background:#f2f2f2}
.right-icon-row button.active{background:var(--accent-soft);color:var(--accent)}
.right-icon-row svg{width:20px;height:20px}
.today-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:14px}
.today-item{display:flex;gap:10px;cursor:pointer;align-items:flex-start}
.today-check{width:22px;height:22px;border-radius:50%;border:1.5px solid var(--line-strong);display:grid;place-items:center;flex:none;font-size:13px;color:var(--muted)}
.today-check.done{border-color:var(--green);background:var(--green);color:#fff}
.today-item-main{flex:1;min-width:0;display:block}
.today-item-title{display:block;font-weight:600;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.today-item-sub{display:block;color:var(--muted);font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.today-item-time{color:var(--muted);font-size:12px;flex:none;white-space:nowrap}
.right-detail summary{font-weight:600;font-size:14px;cursor:pointer;padding:8px 0}
.right-detail .card{border:0;padding:0;box-shadow:none}
.right-detail .card h2{font-size:16px}
/* Cards: flat white sections with a hairline border, no shadow. */
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:none;padding:20px}
.card h2{font-size:17px;margin:0 0 12px;font-weight:600}
.card h3{font-size:15px;margin:24px 0 12px;padding-top:20px;border-top:1px solid var(--line);font-weight:600}
.card h3:first-of-type{border-top:0;padding-top:0} .card h3:first-of-type{border-top:0;padding-top:0}
.composer h2{font-size:22px} .composer h2{font-size:20px}
.composer textarea#prompt,.composer textarea.prompt{ min-height:148px;font-size:16px;padding:16px 18px;border-radius:12px} .composer textarea.prompt{min-height:148px;font-size:16px;padding:16px 18px;border-radius:12px}
.composer textarea.coord{font-family:var(--mono);font-size:13px} .composer textarea.coord{font-family:var(--mono);font-size:13px}
/* Unified controls: same-row controls are all 40px */ /* Unified controls: same-row controls are all 40px */
.bar{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin:12px 0} .bar{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin:12px 0}
.bar > button,.bar > label{display:inline-flex;align-items:center;height:var(--ctl);min-height:var(--ctl);padding:0 16px;box-sizing:border-box;white-space:nowrap} .bar > button,.bar > label{display:inline-flex;align-items:center;height:var(--ctl);min-height:var(--ctl);padding:0 16px;box-sizing:border-box;white-space:nowrap}
.bar > input,.bar > select{height:var(--ctl);min-height:var(--ctl)} .bar > input,.bar > select{height:var(--ctl);min-height:var(--ctl)}
input,select,textarea,button{font:inherit;font-size:14px;padding:10px 13px;border-radius:var(--radius-sm);border:1px solid var(--line-strong);background:#fff;color:var(--ink)} input,select,textarea,button{font:inherit;font-size:14px;padding:10px 13px;border-radius:var(--radius-sm);border:1px solid var(--line-strong);background:#fff;color:var(--text)}
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--ink);box-shadow:0 0 0 3px rgba(28,34,32,.08)} input:focus,select:focus,textarea:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px rgba(59,130,246,.15)}
button{cursor:pointer;font-weight:600;border-radius:999px;padding:9px 16px} button:hover{box-shadow:none}
button:hover{box-shadow:0 4px 14px rgba(28,34,32,.10)} select{appearance:none;-webkit-appearance:none;cursor:pointer;padding-right:34px;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' fill='none' stroke='%23667085' stroke-width='1.5' stroke-linecap='round'/></svg>");background-repeat:no-repeat;background-position:right 12px center}
button:disabled{opacity:.45;cursor:not-allowed;box-shadow:none}
button.primary{background:var(--ink);border-color:var(--ink);color:#fff}
button.primary:hover{background:#000}
button.seal{background:var(--seal);border-color:var(--seal);color:#fff}
button.seal:hover{background:var(--seal-dark)}
button.danger{color:var(--danger);border-color:#fecdca;background:var(--danger-soft)}
button.danger:hover{background:#fee4e2}
select{appearance:none;-webkit-appearance:none;cursor:pointer;padding-right:34px;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' fill='none' stroke='%23737373' stroke-width='1.5' stroke-linecap='round'/></svg>");background-repeat:no-repeat;background-position:right 12px center}
select::-ms-expand{display:none} select::-ms-expand{display:none}
select:disabled,input:disabled{color:#7a857e;background:var(--paper);cursor:not-allowed} select:disabled,input:disabled{color:var(--muted);background:#f9fafb;cursor:not-allowed}
input[type="checkbox"]{width:16px;height:16px;accent-color:var(--seal)} input[type="checkbox"]{width:16px;height:16px;accent-color:var(--accent)}
input[type="file"]{height:var(--ctl);display:inline-flex;align-items:center;padding:0 12px;border:1px dashed var(--line-strong);border-radius:999px;background:#fff} input[type="file"]{height:var(--ctl);display:inline-flex;align-items:center;padding:0 12px;border:1px dashed var(--line-strong);border-radius:999px;background:#fff}
input[type="file"]::file-selector-button{height:28px;padding:0 12px;margin-right:10px;border:0;border-radius:999px;background:var(--paper);color:var(--ink);font:inherit;font-size:13px;cursor:pointer} input[type="file"]::file-selector-button{height:28px;padding:0 12px;margin-right:10px;border:0;border-radius:999px;background:#f2f2f2;color:var(--text);font:inherit;font-size:13px;cursor:pointer}
textarea{width:100%;min-height:84px;resize:vertical;line-height:1.65;padding:12px 14px;border-radius:12px} textarea{width:100%;min-height:84px;resize:vertical;line-height:1.65;padding:12px 14px;border-radius:12px}
.composer .bar label{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--line-strong);border-radius:999px;padding:7px 13px;background:#fff;cursor:pointer;font-size:13px;font-weight:600} .composer .bar label{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--line-strong);border-radius:999px;padding:7px 13px;background:#fff;cursor:pointer;font-size:13px;font-weight:600}
.composer .bar label:has(input:checked){background:var(--ink);color:#fff;border-color:var(--ink)} .composer .bar label:has(input:checked){background:var(--text);color:#fff;border-color:var(--text)}
.rail .bar > input,.rail .bar > select{flex:1 1 120px;min-width:0}
.rail .bar > button,.rail .bar > label{flex:none}
.stacked{margin-bottom:12px} .stacked{margin-bottom:12px}
.stacked + .bar{margin-top:0} .stacked + .bar{margin-top:0}
/* Data lists: one shared list style, no per-section inline styles */ /* Data lists: one shared list style, no per-section inline styles */
.data-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px} .data-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px}
.data-list li{position:relative;margin:0;padding:10px 12px;background:var(--paper);border:1px solid var(--line);border-radius:12px;line-height:1.6;display:flex;flex-wrap:wrap;align-items:center;gap:8px;overflow-wrap:anywhere} .data-list li{position:relative;margin:0;padding:10px 12px;background:#f9fafb;border:1px solid var(--line);border-radius:12px;line-height:1.6;display:flex;flex-wrap:wrap;align-items:center;gap:8px;overflow-wrap:anywhere}
.data-list li .row-main{flex:1 1 200px;min-width:0} .data-list li .row-main{flex:1 1 200px;min-width:0}
.data-list li button{flex:none} .data-list li button{flex:none}
.data-list li.is-online,.data-list li.is-offline{padding-left:26px} .data-list li.is-online,.data-list li.is-offline{padding-left:26px}
.data-list li.is-online::before,.data-list li.is-offline::before{content:"";position:absolute;left:12px;top:17px;width:8px;height:8px;border-radius:50%} .data-list li.is-online::before,.data-list li.is-offline::before{content:"";position:absolute;left:12px;top:17px;width:8px;height:8px;border-radius:50%}
.data-list li.is-online::before{background:var(--pine)} .data-list li.is-online::before{background:var(--green)}
.data-list li.is-offline::before{background:var(--seal)} .data-list li.is-offline::before{background:var(--danger)}
.data-group{margin-bottom:12px}.data-group:last-child{margin-bottom:0}.data-group > b{display:block;margin-bottom:8px} .data-group{margin-bottom:12px}.data-group:last-child{margin-bottom:0}.data-group > b{display:block;margin-bottom:8px}
/* Status pills / dots */ /* Status colours (text only; dots use currentColor) */
.st-queued{color:#7a857e}.st-running{color:var(--amber);font-weight:700}.st-completed{color:var(--success)}.st-failed,.st-merge-failed{color:var(--danger)}.st-merged{color:var(--purple)}.st-interrupted{color:var(--amber)} .st-queued{color:var(--muted)}.st-running{color:var(--amber);font-weight:700}.st-completed{color:var(--success)}.st-failed,.st-merge-failed{color:var(--danger)}.st-merged{color:var(--purple)}.st-interrupted{color:var(--amber)}
/* Task table */ /* Task table (kept for any table view; the left list is the primary list) */
.table-wrap{border:0;border-top:1px solid var(--line);overflow:auto;background:var(--card)} .table-wrap{border:0;border-top:1px solid var(--line);overflow:auto;background:var(--card)}
table{border-collapse:collapse;width:100%;font-size:13px} table{border-collapse:collapse;width:100%;font-size:13px}
th,td{padding:12px 16px;text-align:left;vertical-align:top;border-bottom:1px solid var(--line)} th,td{padding:12px 16px;text-align:left;vertical-align:top;border-bottom:1px solid var(--line)}
th{background:#faf9f6;color:#7a857e;font-size:12px;font-weight:600;white-space:nowrap;letter-spacing:.3px} th{background:#f9fafb;color:var(--muted);font-size:12px;font-weight:600;white-space:nowrap;letter-spacing:.3px}
tbody tr{cursor:pointer;border-left:3px solid transparent} tbody tr{cursor:pointer}
tbody tr:hover{background:#faf9f6} tbody tr:hover{background:#f9fafb}
tr.selected{background:var(--seal-soft);border-left-color:var(--seal)} tr.selected{background:#f2f2f2}
td.prompt-col{font-family:var(--serif);font-size:15px;line-height:1.55} td.prompt-col{font-size:15px;line-height:1.55}
td.st-queued::before,td.st-running::before,td.st-completed::before,td.st-failed::before,td.st-merge-failed::before,td.st-merged::before,td.st-interrupted::before{content:"";display:inline-block;width:8px;height:8px;border-radius:50%;background:currentColor;margin-right:7px;vertical-align:1px} /* Result / error blocks: light, not dark — the screenshot has no dark log block */
/* Dark result / trace block: the one dark element */ pre{background:#f9fafb;color:var(--text);border:1px solid var(--line);border-radius:12px;padding:16px 18px;overflow:auto;max-height:420px;white-space:pre-wrap;word-break:break-word;font-size:13px;font-family:var(--mono);line-height:1.7}
pre{background:var(--ink);color:#ece7db;border:1px solid var(--ink);border-radius:12px;padding:16px 18px;overflow:auto;max-height:420px;white-space:pre-wrap;word-break:break-word;font-size:13px;font-family:var(--mono);line-height:1.7} .trace-box{background:#f9fafb;color:var(--text);border:1px solid var(--line);border-radius:12px;padding:16px 18px;max-height:520px;overflow:auto;font-size:13px;line-height:1.9;font-family:var(--mono)}
.trace-box{background:var(--ink);color:#ece7db;border:1px solid var(--ink);border-left:4px solid var(--seal);border-radius:12px;padding:16px 18px;max-height:520px;overflow:auto;font-size:13px;line-height:1.9;font-family:var(--mono)} .trace-box .muted{color:var(--muted)}
.trace-box .muted{color:#a8b0aa} /* Chat: Muse screenshot bubbles. Assistant grey left, user light-blue
/* Chat: one shared conversation style for trace timeline and continue. right, dark text on both, rounded ~16px, max-width ~75%. One shared
Centred column, user right, assistant left, tool mono, status centred. style for the trace timeline and the continue chat. */
Colours are v3 tokens only; seal is only the follow-back dot. */ .conversation{display:flex;flex-direction:column;gap:20px}
.chat-column{max-width:680px;margin:0 auto;width:100%} .chat-column{max-width:100%;margin:0 auto;width:100%}
.chat-list{position:relative;display:flex;flex-direction:column;gap:12px;max-height:520px;overflow:auto;padding:8px 4px} .chat-list{position:relative;display:flex;flex-direction:column;gap:12px;max-height:none;overflow:visible;padding:8px 0}
.chat-row{display:flex}.chat-row.user{justify-content:flex-end}.chat-row.assistant,.chat-row.tool{justify-content:flex-start} .chat-row{display:flex}.chat-row.user{justify-content:flex-end}.chat-row.assistant,.chat-row.tool{justify-content:flex-start}
.chat-bubble{max-width:85%;padding:10px 14px;border-radius:16px;line-height:1.65;white-space:pre-wrap;word-break:break-word} .chat-bubble{max-width:75%;padding:10px 14px;border-radius:16px;line-height:1.65;white-space:pre-wrap;word-break:break-word;color:var(--text)}
.chat-bubble.user{background:var(--pine);color:#fff;border-bottom-right-radius:4px} .chat-bubble.user{background:var(--bubble-user);border-bottom-right-radius:4px}
.chat-bubble.assistant{background:#fff;border:1px solid var(--line);border-bottom-left-radius:4px} .chat-bubble.assistant{background:var(--bubble-assistant);border-bottom-left-radius:4px}
.chat-bubble.tool{background:var(--paper);border:1px solid var(--line);font-family:var(--mono);font-size:13px;border-bottom-left-radius:4px} .chat-bubble.tool{background:var(--bubble-assistant);font-family:var(--mono);font-size:13px;border-bottom-left-radius:4px}
.chat-label{font-size:12px;color:#7a857e;margin-bottom:4px} .chat-label{font-size:12px;color:var(--muted);margin-bottom:4px}
.chat-bubble.user .chat-label{color:#cfe3dd} .chat-status{text-align:center;font-size:12px;color:var(--muted)}
.chat-status{text-align:center;font-size:12px;color:#7a857e} .chat-follow{position:sticky;bottom:8px;align-self:center;background:var(--accent);border-color:var(--accent);color:#fff;z-index:2}
.chat-follow{position:sticky;bottom:8px;align-self:center;background:var(--seal);border-color:var(--seal);color:#fff;z-index:2} .chat-input-bar{position:sticky;bottom:0;display:flex;gap:8px;align-items:center;background:#fff;border:1px solid var(--line);border-radius:999px;padding:6px 6px 6px 16px;box-shadow:0 1px 4px rgba(0,0,0,.06);z-index:2}
.chat-input-bar{position:sticky;bottom:0;display:flex;gap:8px;align-items:center;background:#fff;padding:12px 0;border-top:1px solid var(--line);z-index:2} .chat-input{flex:1;height:var(--ctl);min-height:var(--ctl);resize:none;border:0;background:transparent;padding:8px 0}
.chat-input{flex:1;height:var(--ctl);min-height:var(--ctl);resize:none} .chat-input:focus{box-shadow:none;outline:none}
.chat-send{height:var(--ctl);flex:none} .chat-send{width:36px;height:36px;border-radius:50%;background:var(--bubble-user);border:0;color:var(--accent-dark);padding:0;display:grid;place-items:center;font-size:18px;line-height:1;flex:none}
.chat-send:disabled{opacity:.45;background:#f2f2f2;color:var(--muted)}
.conv-divider{border-top:1px solid var(--line);margin:4px 0}
@media (max-width:1240px){ @media (max-width:1240px){
.shell{grid-template-columns:280px minmax(0,1fr)} .muse-app{grid-template-columns:56px 260px minmax(0,1fr)}
.detail-col{grid-column:1 / -1} .muse-app.no-right{grid-template-columns:56px 260px minmax(0,1fr)}
.right-col{grid-column:1 / -1;border-left:0;border-top:1px solid var(--line)}
} }
@media (max-width:900px){ @media (max-width:900px){
.shell{grid-template-columns:1fr;padding:16px 14px 32px;gap:16px} .muse-app,.muse-app.no-right{grid-template-columns:1fr}
.topbar{padding:12px 16px}.topbar h1{font-size:19px}.topbar .subtitle{display:none} .icon-rail{display:none}
.topnav{flex-wrap:nowrap;overflow-x:auto;padding:8px 16px}.topnav a{flex:none}.topnav .auto-refresh{margin-left:0;flex:none} .center-inner{padding:16px 14px}
.card{padding:20px} .card{padding:16px}
th:nth-child(2),td:nth-child(2),th:nth-child(3),td:nth-child(3),th:nth-child(7),td:nth-child(7){display:none} th:nth-child(2),td:nth-child(2),th:nth-child(3),td:nth-child(3),th:nth-child(7),td:nth-child(7){display:none}
} }
@media (max-width:560px){ @media (max-width:560px){
.version{display:none}.card{padding:16px} .card{padding:16px}
th:nth-child(6),td:nth-child(6),th:nth-child(9),td:nth-child(9){display:none} th:nth-child(6),td:nth-child(6),th:nth-child(9),td:nth-child(9){display:none}
.bar > input[type="text"],.bar > input[type="password"],.bar > select{flex:1 1 100%} .bar > input[type="text"],.bar > input[type="password"],.bar > select{flex:1 1 100%}
th,td{padding:10px 12px} th,td{padding:10px 12px}
+21 -21
View File
@@ -4,7 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Codex 命令台</title> <title>Codex 命令台</title>
<script type="module" crossorigin>(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const _ of document.querySelectorAll('link[rel="modulepreload"]'))o(_);new MutationObserver(_=>{for(const O of _)if(O.type==="childList")for(const A of O.addedNodes)A.tagName==="LINK"&&A.rel==="modulepreload"&&o(A)}).observe(document,{childList:!0,subtree:!0});function g(_){const O={};return _.integrity&&(O.integrity=_.integrity),_.referrerPolicy&&(O.referrerPolicy=_.referrerPolicy),_.crossOrigin==="use-credentials"?O.credentials="include":_.crossOrigin==="anonymous"?O.credentials="omit":O.credentials="same-origin",O}function o(_){if(_.ep)return;_.ep=!0;const O=g(_);fetch(_.href,O)}})();function Yv(i){return i&&i.__esModule&&Object.prototype.hasOwnProperty.call(i,"default")?i.default:i}var Pf={exports:{}},Iu={};/** <script type="module" crossorigin>(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const _ of document.querySelectorAll('link[rel="modulepreload"]'))o(_);new MutationObserver(_=>{for(const M of _)if(M.type==="childList")for(const N of M.addedNodes)N.tagName==="LINK"&&N.rel==="modulepreload"&&o(N)}).observe(document,{childList:!0,subtree:!0});function m(_){const M={};return _.integrity&&(M.integrity=_.integrity),_.referrerPolicy&&(M.referrerPolicy=_.referrerPolicy),_.crossOrigin==="use-credentials"?M.credentials="include":_.crossOrigin==="anonymous"?M.credentials="omit":M.credentials="same-origin",M}function o(_){if(_.ep)return;_.ep=!0;const M=m(_);fetch(_.href,M)}})();function qh(i){return i&&i.__esModule&&Object.prototype.hasOwnProperty.call(i,"default")?i.default:i}var tr={exports:{}},Pu={};/**
* @license React * @license React
* react-jsx-runtime.production.js * react-jsx-runtime.production.js
* *
@@ -12,7 +12,7 @@
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/var _v;function Ny(){if(_v)return Iu;_v=1;var i=Symbol.for("react.transitional.element"),r=Symbol.for("react.fragment");function g(o,_,O){var A=null;if(O!==void 0&&(A=""+O),_.key!==void 0&&(A=""+_.key),"key"in _){O={};for(var E in _)E!=="key"&&(O[E]=_[E])}else O=_;return _=O.ref,{$$typeof:i,type:o,key:A,ref:_!==void 0?_:null,props:O}}return Iu.Fragment=r,Iu.jsx=g,Iu.jsxs=g,Iu}var Nv;function Ay(){return Nv||(Nv=1,Pf.exports=Ny()),Pf.exports}var s=Ay(),tr={exports:{}},ct={};/** */var Nh;function Ay(){if(Nh)return Pu;Nh=1;var i=Symbol.for("react.transitional.element"),r=Symbol.for("react.fragment");function m(o,_,M){var N=null;if(M!==void 0&&(N=""+M),_.key!==void 0&&(N=""+_.key),"key"in _){M={};for(var j in _)j!=="key"&&(M[j]=_[j])}else M=_;return _=M.ref,{$$typeof:i,type:o,key:N,ref:_!==void 0?_:null,props:M}}return Pu.Fragment=r,Pu.jsx=m,Pu.jsxs=m,Pu}var Ch;function My(){return Ch||(Ch=1,tr.exports=Ay()),tr.exports}var s=My(),er={exports:{}},ct={};/**
* @license React * @license React
* react.production.js * react.production.js
* *
@@ -20,7 +20,7 @@
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/var Av;function Cy(){if(Av)return ct;Av=1;var i=Symbol.for("react.transitional.element"),r=Symbol.for("react.portal"),g=Symbol.for("react.fragment"),o=Symbol.for("react.strict_mode"),_=Symbol.for("react.profiler"),O=Symbol.for("react.consumer"),A=Symbol.for("react.context"),E=Symbol.for("react.forward_ref"),Z=Symbol.for("react.suspense"),U=Symbol.for("react.memo"),w=Symbol.for("react.lazy"),x=Symbol.for("react.activity"),J=Symbol.for("react.view_transition"),ut=Symbol.iterator;function K(v){return v===null||typeof v!="object"?null:(v=ut&&v[ut]||v["@@iterator"],typeof v=="function"?v:null)}var P={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},it=Object.assign,jt={};function Vt(v,R,F){this.props=v,this.context=R,this.refs=jt,this.updater=F||P}Vt.prototype.isReactComponent={},Vt.prototype.setState=function(v,R){if(typeof v!="object"&&typeof v!="function"&&v!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,v,R,"setState")},Vt.prototype.forceUpdate=function(v){this.updater.enqueueForceUpdate(this,v,"forceUpdate")};function pe(){}pe.prototype=Vt.prototype;function Ce(v,R,F){this.props=v,this.context=R,this.refs=jt,this.updater=F||P}var Ft=Ce.prototype=new pe;Ft.constructor=Ce,it(Ft,Vt.prototype),Ft.isPureReactComponent=!0;var oe=Array.isArray;function st(){}var vt={H:null,A:null,T:null,S:null},Wt=Object.prototype.hasOwnProperty;function te(v,R,F){var k=F.ref;return{$$typeof:i,type:v,key:R,ref:k!==void 0?k:null,props:F}}function Lt(v,R){return te(v.type,R,v.props)}function de(v){return typeof v=="object"&&v!==null&&v.$$typeof===i}function Dt(v){var R={"=":"=0",":":"=2"};return"$"+v.replace(/[=:]/g,function(F){return R[F]})}var Pe=/\/+/g;function H(v,R){return typeof v=="object"&&v!==null&&v.key!=null?Dt(""+v.key):R.toString(36)}function q(v){switch(v.status){case"fulfilled":return v.value;case"rejected":throw v.reason;default:switch(typeof v.status=="string"?v.then(st,st):(v.status="pending",v.then(function(R){v.status==="pending"&&(v.status="fulfilled",v.value=R)},function(R){v.status==="pending"&&(v.status="rejected",v.reason=R)})),v.status){case"fulfilled":return v.value;case"rejected":throw v.reason}}throw v}function L(v,R,F,k,yt){var dt=typeof v;(dt==="undefined"||dt==="boolean")&&(v=null);var Tt=!1;if(v===null)Tt=!0;else switch(dt){case"bigint":case"string":case"number":Tt=!0;break;case"object":switch(v.$$typeof){case i:case r:Tt=!0;break;case w:return Tt=v._init,L(Tt(v._payload),R,F,k,yt)}}if(Tt)return yt=yt(v),Tt=k===""?"."+H(v,0):k,oe(yt)?(F="",Tt!=null&&(F=Tt.replace(Pe,"$&/")+"/"),L(yt,R,F,"",function(be){return be})):yt!=null&&(de(yt)&&(yt=Lt(yt,F+(yt.key==null||v&&v.key===yt.key?"":(""+yt.key).replace(Pe,"$&/")+"/")+Tt)),R.push(yt)),1;Tt=0;var G=k===""?".":k+":";if(oe(v))for(var at=0;at<v.length;at++)k=v[at],dt=G+H(k,at),Tt+=L(k,R,F,dt,yt);else if(at=K(v),typeof at=="function")for(v=at.call(v),at=0;!(k=v.next()).done;)k=k.value,dt=G+H(k,at++),Tt+=L(k,R,F,dt,yt);else if(dt==="object"){if(typeof v.then=="function")return L(q(v),R,F,k,yt);throw R=String(v),Error("Objects are not valid as a React child (found: "+(R==="[object Object]"?"object with keys {"+Object.keys(v).join(", ")+"}":R)+"). If you meant to render a collection of children, use an array instead.")}return Tt}function tt(v,R,F){if(v==null)return v;var k=[],yt=0;return L(v,k,"","",function(dt){return R.call(F,dt,yt++)}),k}function xt(v){if(v._status===-1){var R=v._result,F=R();F.then(function(k){(v._status===0||v._status===-1)&&(v._status=1,v._result=k,F.status===void 0&&(F.status="fulfilled",F.value=k))},function(k){(v._status===0||v._status===-1)&&(v._status=2,v._result=k,F.status===void 0&&(F.status="rejected",F.reason=k))}),v._status===-1&&(v._status=0,v._result=F)}if(v._status===1)return v._result.default;throw v._result}var ht=typeof reportError=="function"?reportError:function(v){if(typeof window=="object"&&typeof window.ErrorEvent=="function"){var R=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:typeof v=="object"&&v!==null&&typeof v.message=="string"?String(v.message):String(v),error:v});if(!window.dispatchEvent(R))return}else if(typeof process=="object"&&typeof process.emit=="function"){process.emit("uncaughtException",v);return}console.error(v)};function ee(v){var R=vt.T,F={};F.types=R!==null?R.types:null,vt.T=F;try{var k=v(),yt=vt.S;yt!==null&&yt(F,k),typeof k=="object"&&k!==null&&typeof k.then=="function"&&k.then(st,ht)}catch(dt){ht(dt)}finally{R!==null&&F.types!==null&&(R.types=F.types),vt.T=R}}function Oe(v){var R=vt.T;if(R!==null){var F=R.types;F===null?R.types=[v]:F.indexOf(v)===-1&&F.push(v)}else ee(Oe.bind(null,v))}var ue={map:tt,forEach:function(v,R,F){tt(v,function(){R.apply(this,arguments)},F)},count:function(v){var R=0;return tt(v,function(){R++}),R},toArray:function(v){return tt(v,function(R){return R})||[]},only:Line truncated */var Ah;function Oy(){if(Ah)return ct;Ah=1;var i=Symbol.for("react.transitional.element"),r=Symbol.for("react.portal"),m=Symbol.for("react.fragment"),o=Symbol.for("react.strict_mode"),_=Symbol.for("react.profiler"),M=Symbol.for("react.consumer"),N=Symbol.for("react.context"),j=Symbol.for("react.forward_ref"),B=Symbol.for("react.suspense"),R=Symbol.for("react.memo"),G=Symbol.for("react.lazy"),E=Symbol.for("react.activity"),J=Symbol.for("react.view_transition"),ut=Symbol.iterator;function k(v){return v===null||typeof v!="object"?null:(v=ut&&v[ut]||v["@@iterator"],typeof v=="function"?v:null)}var P={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},it=Object.assign,Tt={};function Vt(v,D,F){this.props=v,this.context=D,this.refs=Tt,this.updater=F||P}Vt.prototype.isReactComponent={},Vt.prototype.setState=function(v,D){if(typeof v!="object"&&typeof v!="function"&&v!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,v,D,"setState")},Vt.prototype.forceUpdate=function(v){this.updater.enqueueForceUpdate(this,v,"forceUpdate")};function be(){}be.prototype=Vt.prototype;function Me(v,D,F){this.props=v,this.context=D,this.refs=Tt,this.updater=F||P}var Ft=Me.prototype=new be;Ft.constructor=Me,it(Ft,Vt.prototype),Ft.isPureReactComponent=!0;var oe=Array.isArray;function st(){}var ht={H:null,A:null,T:null,S:null},Wt=Object.prototype.hasOwnProperty;function te(v,D,F){var K=F.ref;return{$$typeof:i,type:v,key:D,ref:K!==void 0?K:null,props:F}}function Lt(v,D){return te(v.type,D,v.props)}function de(v){return typeof v=="object"&&v!==null&&v.$$typeof===i}function Dt(v){var D={"=":"=0",":":"=2"};return"$"+v.replace(/[=:]/g,function(F){return D[F]})}var Pe=/\/+/g;function H(v,D){return typeof v=="object"&&v!==null&&v.key!=null?Dt(""+v.key):D.toString(36)}function w(v){switch(v.status){case"fulfilled":return v.value;case"rejected":throw v.reason;default:switch(typeof v.status=="string"?v.then(st,st):(v.status="pending",v.then(function(D){v.status==="pending"&&(v.status="fulfilled",v.value=D)},function(D){v.status==="pending"&&(v.status="rejected",v.reason=D)})),v.status){case"fulfilled":return v.value;case"rejected":throw v.reason}}throw v}function L(v,D,F,K,yt){var dt=typeof v;(dt==="undefined"||dt==="boolean")&&(v=null);var xt=!1;if(v===null)xt=!0;else switch(dt){case"bigint":case"string":case"number":xt=!0;break;case"object":switch(v.$$typeof){case i:case r:xt=!0;break;case G:return xt=v._init,L(xt(v._payload),D,F,K,yt)}}if(xt)return yt=yt(v),xt=K===""?"."+H(v,0):K,oe(yt)?(F="",xt!=null&&(F=xt.replace(Pe,"$&/")+"/"),L(yt,D,F,"",function(xe){return xe})):yt!=null&&(de(yt)&&(yt=Lt(yt,F+(yt.key==null||v&&v.key===yt.key?"":(""+yt.key).replace(Pe,"$&/")+"/")+xt)),D.push(yt)),1;xt=0;var Q=K===""?".":K+":";if(oe(v))for(var at=0;at<v.length;at++)K=v[at],dt=Q+H(K,at),xt+=L(K,D,F,dt,yt);else if(at=k(v),typeof at=="function")for(v=at.call(v),at=0;!(K=v.next()).done;)K=K.value,dt=Q+H(K,at++),xt+=L(K,D,F,dt,yt);else if(dt==="object"){if(typeof v.then=="function")return L(w(v),D,F,K,yt);throw D=String(v),Error("Objects are not valid as a React child (found: "+(D==="[object Object]"?"object with keys {"+Object.keys(v).join(", ")+"}":D)+"). If you meant to render a collection of children, use an array instead.")}return xt}function tt(v,D,F){if(v==null)return v;var K=[],yt=0;return L(v,K,"","",function(dt){return D.call(F,dt,yt++)}),K}function jt(v){if(v._status===-1){var D=v._result,F=D();F.then(function(K){(v._status===0||v._status===-1)&&(v._status=1,v._result=K,F.status===void 0&&(F.status="fulfilled",F.value=K))},function(K){(v._status===0||v._status===-1)&&(v._status=2,v._result=K,F.status===void 0&&(F.status="rejected",F.reason=K))}),v._status===-1&&(v._status=0,v._result=F)}if(v._status===1)return v._result.default;throw v._result}var vt=typeof reportError=="function"?reportError:function(v){if(typeof window=="object"&&typeof window.ErrorEvent=="function"){var D=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:typeof v=="object"&&v!==null&&typeof v.message=="string"?String(v.message):String(v),error:v});if(!window.dispatchEvent(D))return}else if(typeof process=="object"&&typeof process.emit=="function"){process.emit("uncaughtException",v);return}console.error(v)};function ee(v){var D=ht.T,F={};F.types=D!==null?D.types:null,ht.T=F;try{var K=v(),yt=ht.S;yt!==null&&yt(F,K),typeof K=="object"&&K!==null&&typeof K.then=="function"&&K.then(st,vt)}catch(dt){vt(dt)}finally{D!==null&&F.types!==null&&(D.types=F.types),ht.T=D}}function Oe(v){var D=ht.T;if(D!==null){var F=D.types;F===null?D.types=[v]:F.indexOf(v)===-1&&F.push(v)}else ee(Oe.bind(null,v))}var ue={map:tt,forEach:function(v,D,F){tt(v,function(){D.apply(this,arguments)},F)},count:function(v){var D=0;return tt(v,function(){D++}),D},toArray:function(v){return tt(v,function(D){return D})||[]},only:Line truncated
* @license React * @license React
* scheduler.production.js * scheduler.production.js
* *
@@ -28,7 +28,7 @@
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/var Ov;function My(){return Ov||(Ov=1,(function(i){function r(q,L){var tt=q.length;q.push(L);t:for(;0<tt;){var xt=tt-1>>>1,ht=q[xt];if(0<_(ht,L))q[xt]=L,q[tt]=ht,tt=xt;else break t}}function g(q){return q.length===0?null:q[0]}function o(q){if(q.length===0)return null;var L=q[0],tt=q.pop();if(tt!==L){q[0]=tt;t:for(var xt=0,ht=q.length,ee=ht>>>1;xt<ee;){var Oe=2*(xt+1)-1,ue=q[Oe],v=Oe+1,R=q[v];if(0>_(ue,tt))v<ht&&0>_(R,ue)?(q[xt]=R,q[v]=tt,xt=v):(q[xt]=ue,q[Oe]=tt,xt=Oe);else if(v<ht&&0>_(R,tt))q[xt]=R,q[v]=tt,xt=v;else break t}}return L}function _(q,L){var tt=q.sortIndex-L.sortIndex;return tt!==0?tt:q.id-L.id}if(i.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var O=performance;i.unstable_now=function(){return O.now()}}else{var A=Date,E=A.now();i.unstable_now=function(){return A.now()-E}}var Z=[],U=[],w=1,x=null,J=3,ut=!1,K=!1,P=!1,it=!1,jt=typeof setTimeout=="function"?setTimeout:null,Vt=typeof clearTimeout=="function"?clearTimeout:null,pe=typeof setImmediate<"u"?setImmediate:null;function Ce(q){for(var L=g(U);L!==null;){if(L.callback===null)o(U);else if(L.startTime<=q)o(U),L.sortIndex=L.expirationTime,r(Z,L);else break;L=g(U)}}function Ft(q){if(P=!1,Ce(q),!K)if(g(Z)!==null)K=!0,oe||(oe=!0,de());else{var L=g(U);L!==null&&H(Ft,L.startTime-q)}}var oe=!1,st=-1,vt=5,Wt=-1;function te(){return it?!0:!(i.unstable_now()-Wt<vt)}function Lt(){if(it=!1,oe){var q=i.unstable_now();Wt=q;var L=!0;try{t:{K=!1,P&&(P=!1,Vt(st),st=-1),ut=!0;var tt=J;try{e:{for(Ce(q),x=g(Z);x!==null&&!(x.expirationTime>q&&te());){var xt=x.callback;if(typeof xt=="function"){x.callback=null,J=x.priorityLevel;var ht=xt(x.expirationTime<=q);if(q=i.unstable_now(),typeof ht=="function"){x.callback=ht,Ce(q),L=!0;break e}x===g(Z)&&o(Z),Ce(q)}else o(Z);x=g(Z)}if(x!==null)L=!0;else{var ee=g(U);ee!==null&&H(Ft,ee.startTime-q),L=!1}}break t}finally{x=null,J=tt,ut=!1}L=void 0}}finally{L?de():oe=!1}}}var de;if(typeof pe=="function")de=function(){pe(Lt)};else if(typeof MessageChannel<"u"){var Dt=new MessageChannel,Pe=Dt.port2;Dt.port1.onmessage=Lt,de=function(){Pe.postMessage(null)}}else de=function(){jt(Lt,0)};function H(q,L){st=jt(function(){q(i.unstable_now())},L)}i.unstable_IdlePriority=5,i.unstable_ImmediatePriority=1,i.unstable_LowPriority=4,i.unstable_NormalPriority=3,i.unstable_Profiling=null,i.unstable_UserBlockingPriority=2,i.unstable_cancelCallback=function(q){q.callback=null},i.unstable_forceFrameRate=function(q){0>q||125<q?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):vt=0<q?Math.floor(1e3/q):5},i.unstable_getCurrentPriorityLevel=function(){return J},i.unstable_next=function(q){switch(J){case 1:case 2:case 3:var L=3;break;default:L=J}var tt=J;J=L;try{return q()}finally{J=tt}},i.unstable_requestPaint=function(){it=!0},i.unstable_runWithPriority=function(q,L){switch(q){case 1:case 2:case 3:case 4:case 5:break;default:q=3}var tt=J;J=q;try{return L()}finally{J=tt}},i.unstable_scheduleCallback=function(q,L,tt){var xt=i.unstable_now();switch(typeof tt=="object"&&tt!==null?(tt=tt.delay,tt=typeof tt=="number"&&0<tt?xt+tt:xt):tt=xt,q){case 1:var ht=-1;break;case 2:ht=250;break;case 5:ht=1073741823;break;case 4:ht=1e4;break;default:ht=5e3}return ht=tt+ht,q={id:w++,callback:L,priorityLevel:q,startTime:tt,expirationTime:ht,sortIndex:-1},tt>xt?(q.sortIndex=tt,r(U,q),g(Z)===null&&q===g(U)&&(P?(Vt(st),st=-1):P=!0,H(Ft,tt-xt))):(q.sortIndex=ht,r(Z,q),K||ut||(K=!0,oe||(oe=!0,de()))),q},i.unstable_shouldYield=te,i.unstable_wrapCallback=function(q){var L=J;return function(){var tt=J;J=L;try{return q.apply(this,arguments)}finally{J=tt}}}})(ar)),ar}var Mv;function zy(){return Mv||(Mv=1,lr.exports=My()),lr.exports}var nr={exports:{}},Ae={};/** */var Oh;function Ry(){return Oh||(Oh=1,(function(i){function r(w,L){var tt=w.length;w.push(L);t:for(;0<tt;){var jt=tt-1>>>1,vt=w[jt];if(0<_(vt,L))w[jt]=L,w[tt]=vt,tt=jt;else break t}}function m(w){return w.length===0?null:w[0]}function o(w){if(w.length===0)return null;var L=w[0],tt=w.pop();if(tt!==L){w[0]=tt;t:for(var jt=0,vt=w.length,ee=vt>>>1;jt<ee;){var Oe=2*(jt+1)-1,ue=w[Oe],v=Oe+1,D=w[v];if(0>_(ue,tt))v<vt&&0>_(D,ue)?(w[jt]=D,w[v]=tt,jt=v):(w[jt]=ue,w[Oe]=tt,jt=Oe);else if(v<vt&&0>_(D,tt))w[jt]=D,w[v]=tt,jt=v;else break t}}return L}function _(w,L){var tt=w.sortIndex-L.sortIndex;return tt!==0?tt:w.id-L.id}if(i.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var M=performance;i.unstable_now=function(){return M.now()}}else{var N=Date,j=N.now();i.unstable_now=function(){return N.now()-j}}var B=[],R=[],G=1,E=null,J=3,ut=!1,k=!1,P=!1,it=!1,Tt=typeof setTimeout=="function"?setTimeout:null,Vt=typeof clearTimeout=="function"?clearTimeout:null,be=typeof setImmediate<"u"?setImmediate:null;function Me(w){for(var L=m(R);L!==null;){if(L.callback===null)o(R);else if(L.startTime<=w)o(R),L.sortIndex=L.expirationTime,r(B,L);else break;L=m(R)}}function Ft(w){if(P=!1,Me(w),!k)if(m(B)!==null)k=!0,oe||(oe=!0,de());else{var L=m(R);L!==null&&H(Ft,L.startTime-w)}}var oe=!1,st=-1,ht=5,Wt=-1;function te(){return it?!0:!(i.unstable_now()-Wt<ht)}function Lt(){if(it=!1,oe){var w=i.unstable_now();Wt=w;var L=!0;try{t:{k=!1,P&&(P=!1,Vt(st),st=-1),ut=!0;var tt=J;try{e:{for(Me(w),E=m(B);E!==null&&!(E.expirationTime>w&&te());){var jt=E.callback;if(typeof jt=="function"){E.callback=null,J=E.priorityLevel;var vt=jt(E.expirationTime<=w);if(w=i.unstable_now(),typeof vt=="function"){E.callback=vt,Me(w),L=!0;break e}E===m(B)&&o(B),Me(w)}else o(B);E=m(B)}if(E!==null)L=!0;else{var ee=m(R);ee!==null&&H(Ft,ee.startTime-w),L=!1}}break t}finally{E=null,J=tt,ut=!1}L=void 0}}finally{L?de():oe=!1}}}var de;if(typeof be=="function")de=function(){be(Lt)};else if(typeof MessageChannel<"u"){var Dt=new MessageChannel,Pe=Dt.port2;Dt.port1.onmessage=Lt,de=function(){Pe.postMessage(null)}}else de=function(){Tt(Lt,0)};function H(w,L){st=Tt(function(){w(i.unstable_now())},L)}i.unstable_IdlePriority=5,i.unstable_ImmediatePriority=1,i.unstable_LowPriority=4,i.unstable_NormalPriority=3,i.unstable_Profiling=null,i.unstable_UserBlockingPriority=2,i.unstable_cancelCallback=function(w){w.callback=null},i.unstable_forceFrameRate=function(w){0>w||125<w?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):ht=0<w?Math.floor(1e3/w):5},i.unstable_getCurrentPriorityLevel=function(){return J},i.unstable_next=function(w){switch(J){case 1:case 2:case 3:var L=3;break;default:L=J}var tt=J;J=L;try{return w()}finally{J=tt}},i.unstable_requestPaint=function(){it=!0},i.unstable_runWithPriority=function(w,L){switch(w){case 1:case 2:case 3:case 4:case 5:break;default:w=3}var tt=J;J=w;try{return L()}finally{J=tt}},i.unstable_scheduleCallback=function(w,L,tt){var jt=i.unstable_now();switch(typeof tt=="object"&&tt!==null?(tt=tt.delay,tt=typeof tt=="number"&&0<tt?jt+tt:jt):tt=jt,w){case 1:var vt=-1;break;case 2:vt=250;break;case 5:vt=1073741823;break;case 4:vt=1e4;break;default:vt=5e3}return vt=tt+vt,w={id:G++,callback:L,priorityLevel:w,startTime:tt,expirationTime:vt,sortIndex:-1},tt>jt?(w.sortIndex=tt,r(R,w),m(B)===null&&w===m(R)&&(P?(Vt(st),st=-1):P=!0,H(Ft,tt-jt))):(w.sortIndex=vt,r(B,w),k||ut||(k=!0,oe||(oe=!0,de()))),w},i.unstable_shouldYield=te,i.unstable_wrapCallback=function(w){var L=J;return function(){var tt=J;J=L;try{return w.apply(this,arguments)}finally{J=tt}}}})(nr)),nr}var zh;function Dy(){return zh||(zh=1,ar.exports=Ry()),ar.exports}var ur={exports:{}},Ae={};/**
* @license React * @license React
* react-dom.production.js * react-dom.production.js
* *
@@ -36,7 +36,7 @@
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/var zv;function Ry(){if(zv)return Ae;zv=1;var i=sr();function r(w){var x="https://react.dev/errors/"+w;if(1<arguments.length){x+="?args[]="+encodeURIComponent(arguments[1]);for(var J=2;J<arguments.length;J++)x+="&args[]="+encodeURIComponent(arguments[J])}return"Minified React error #"+w+"; visit "+x+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}function g(){}var o={d:{f:g,r:function(){throw Error(r(522))},D:g,C:g,L:g,m:g,X:g,S:g,M:g},p:0,findDOMNode:null},_=Symbol.for("react.portal"),O=Symbol.for("react.recoverable"),A=Symbol.for("react.optimistic_key");function E(w,x,J){var ut=3<arguments.length&&arguments[3]!==void 0?arguments[3]:null;return{$$typeof:_,key:ut==null?null:ut===A?A:""+ut,children:w,containerInfo:x,implementation:J}}var Z=i.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;function U(w,x){if(w==="font")return"";if(typeof x=="string")return x==="use-credentials"?x:""}return Ae.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=o,Ae.browser=function(w){return{$$typeof:O,_reason:w}},Ae.createPortal=function(w,x){var J=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null;if(!x||x.nodeType!==1&&x.nodeType!==9&&x.nodeType!==11)throw Error(r(299));return E(w,x,null,J)},Ae.flushSync=function(w){var x=Z.T,J=o.p;try{if(Z.T=null,o.p=2,w)return w()}finally{Z.T=x,o.p=J,o.d.f()}},Ae.preconnect=function(w,x){typeof w=="string"&&(x?(x=x.crossOrigin,x=typeof x=="string"?x==="use-credentials"?x:"":void 0):x=null,o.d.C(w,x))},Ae.prefetchDNS=function(w){typeof w=="string"&&o.d.D(w)},Ae.preinit=function(w,x){if(typeof w=="string"&&x&&typeof x.as=="string"){var J=x.as,ut=U(J,x.crossOrigin),K=typeof x.integrity=="string"?x.integrity:void 0,P=typeof x.fetchPriority=="string"?x.fetchPriority:void 0;J==="style"?o.d.S(w,typeof x.precedence=="string"?x.precedence:void 0,{crossOrigin:ut,integrity:K,fetchPriority:P}):J==="script"&&o.d.X(w,{crossOrigin:ut,integrity:K,fetchPriority:P,nonce:typeof x.nonce=="string"?x.nonce:void 0})}},Ae.preinitModule=function(w,x){if(typeof w=="string")if(typeof x=="object"&&x!==null){if(x.as==null||x.as==="script"){var J=U(x.as,x.crossOrigin);o.d.M(w,{crossOrigin:J,integrity:typeof x.integrity=="string"?x.integrity:void 0,nonce:typeof x.nonce=="string"?x.nonce:void 0,fetchPriority:typeof x.fetchPriority=="string"?x.fetchPriority:void 0})}}else x==null&&o.d.M(w)},Ae.preload=function(w,x){if(typeof w=="string"&&typeof x=="object"&&x!==null&&typeof x.as=="string"){var J=x.as,ut=U(J,x.crossOrigin);o.d.L(w,J,{crossOrigin:ut,integrity:typeof x.integrity=="string"?x.integrity:void 0,nonce:typeof x.nonce=="string"?x.nonce:void 0,type:typeof x.type=="string"?x.type:void 0,fetchPriority:typeof x.fetchPriority=="string"?x.fetchPriority:void 0,referrerPolicy:typeof x.referrerPolicy=="string"?x.referrerPolicy:void 0,imageSrcSet:typeof x.imageSrcSet=="string"?x.imageSrcSet:void 0,imageSizes:typeof x.imageSizes=="string"?x.imageSizes:void 0,media:typeof x.media=="string"?x.media:void 0})}},Ae.preloadModule=function(w,x){if(typeof w=="string")if(x){var J=U(x.as,x.crossOrigin);o.d.m(w,{as:typeof x.as=="string"&&x.as!=="script"?x.as:void 0,crossOrigin:J,integrity:typeof x.integrity=="string"?x.integrity:void 0,nonce:typeof x.nonce=="string"?x.nonce:void 0,fetchPriority:typeof x.fetchPriority=="string"?x.fetchPriority:void 0})}else o.d.m(w)},Ae.requestFormReset=function(w){o.d.r(w)},Ae.unstable_batchedUpdates=function(w,x){return w(x)},Ae.useFormState=function(w,x,J){return Z.H.useFormState(w,x,J)},Ae.useFormStatus=function(){return Z.H.useHostTransitionStatus()},Ae.version="19.3.1",Ae}var Rv;function Dy(){if(Rv)return nr.exports;Rv=1;function i(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(i)}catch(r){console.error(r)}}return i(),nr.exports=Ry(),nr.exports}/** */var Rh;function Uy(){if(Rh)return Ae;Rh=1;var i=fr();function r(G){var E="https://react.dev/errors/"+G;if(1<arguments.length){E+="?args[]="+encodeURIComponent(arguments[1]);for(var J=2;J<arguments.length;J++)E+="&args[]="+encodeURIComponent(arguments[J])}return"Minified React error #"+G+"; visit "+E+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}function m(){}var o={d:{f:m,r:function(){throw Error(r(522))},D:m,C:m,L:m,m,X:m,S:m,M:m},p:0,findDOMNode:null},_=Symbol.for("react.portal"),M=Symbol.for("react.recoverable"),N=Symbol.for("react.optimistic_key");function j(G,E,J){var ut=3<arguments.length&&arguments[3]!==void 0?arguments[3]:null;return{$$typeof:_,key:ut==null?null:ut===N?N:""+ut,children:G,containerInfo:E,implementation:J}}var B=i.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;function R(G,E){if(G==="font")return"";if(typeof E=="string")return E==="use-credentials"?E:""}return Ae.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=o,Ae.browser=function(G){return{$$typeof:M,_reason:G}},Ae.createPortal=function(G,E){var J=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null;if(!E||E.nodeType!==1&&E.nodeType!==9&&E.nodeType!==11)throw Error(r(299));return j(G,E,null,J)},Ae.flushSync=function(G){var E=B.T,J=o.p;try{if(B.T=null,o.p=2,G)return G()}finally{B.T=E,o.p=J,o.d.f()}},Ae.preconnect=function(G,E){typeof G=="string"&&(E?(E=E.crossOrigin,E=typeof E=="string"?E==="use-credentials"?E:"":void 0):E=null,o.d.C(G,E))},Ae.prefetchDNS=function(G){typeof G=="string"&&o.d.D(G)},Ae.preinit=function(G,E){if(typeof G=="string"&&E&&typeof E.as=="string"){var J=E.as,ut=R(J,E.crossOrigin),k=typeof E.integrity=="string"?E.integrity:void 0,P=typeof E.fetchPriority=="string"?E.fetchPriority:void 0;J==="style"?o.d.S(G,typeof E.precedence=="string"?E.precedence:void 0,{crossOrigin:ut,integrity:k,fetchPriority:P}):J==="script"&&o.d.X(G,{crossOrigin:ut,integrity:k,fetchPriority:P,nonce:typeof E.nonce=="string"?E.nonce:void 0})}},Ae.preinitModule=function(G,E){if(typeof G=="string")if(typeof E=="object"&&E!==null){if(E.as==null||E.as==="script"){var J=R(E.as,E.crossOrigin);o.d.M(G,{crossOrigin:J,integrity:typeof E.integrity=="string"?E.integrity:void 0,nonce:typeof E.nonce=="string"?E.nonce:void 0,fetchPriority:typeof E.fetchPriority=="string"?E.fetchPriority:void 0})}}else E==null&&o.d.M(G)},Ae.preload=function(G,E){if(typeof G=="string"&&typeof E=="object"&&E!==null&&typeof E.as=="string"){var J=E.as,ut=R(J,E.crossOrigin);o.d.L(G,J,{crossOrigin:ut,integrity:typeof E.integrity=="string"?E.integrity:void 0,nonce:typeof E.nonce=="string"?E.nonce:void 0,type:typeof E.type=="string"?E.type:void 0,fetchPriority:typeof E.fetchPriority=="string"?E.fetchPriority:void 0,referrerPolicy:typeof E.referrerPolicy=="string"?E.referrerPolicy:void 0,imageSrcSet:typeof E.imageSrcSet=="string"?E.imageSrcSet:void 0,imageSizes:typeof E.imageSizes=="string"?E.imageSizes:void 0,media:typeof E.media=="string"?E.media:void 0})}},Ae.preloadModule=function(G,E){if(typeof G=="string")if(E){var J=R(E.as,E.crossOrigin);o.d.m(G,{as:typeof E.as=="string"&&E.as!=="script"?E.as:void 0,crossOrigin:J,integrity:typeof E.integrity=="string"?E.integrity:void 0,nonce:typeof E.nonce=="string"?E.nonce:void 0,fetchPriority:typeof E.fetchPriority=="string"?E.fetchPriority:void 0})}else o.d.m(G)},Ae.requestFormReset=function(G){o.d.r(G)},Ae.unstable_batchedUpdates=function(G,E){return G(E)},Ae.useFormState=function(G,E,J){return B.H.useFormState(G,E,J)},Ae.useFormStatus=function(){return B.H.useHostTransitionStatus()},Ae.version="19.3.1",Ae}var Dh;function Hy(){if(Dh)return ur.exports;Dh=1;function i(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(i)}catch(r){console.error(r)}}return i(),ur.exports=Uy(),ur.exports}/**
* @license React * @license React
* react-dom-client.production.js * react-dom-client.production.js
* *
@@ -44,32 +44,32 @@
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/var Dv;function Uy(){if(Dv)return Pu;Dv=1;var i=zy(),r=sr(),g=Dy();function o(t){var e="https://react.dev/errors/"+t;if(1<arguments.length){e+="?args[]="+encodeURIComponent(arguments[1]);for(var l=2;l<arguments.length;l++)e+="&args[]="+encodeURIComponent(arguments[l])}return"Minified React error #"+t+"; visit "+e+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}function _(t){return!(!t||t.nodeType!==1&&t.nodeType!==9&&t.nodeType!==11)}function O(t){for(var e=t,l=e;l&&!l.alternate;)e=l,(e.flags&4098)!==0&&(t=e.return),l=e.return;for(;e.return;)e=e.return;return e.tag===3?t:null}function A(t){if(t.tag===13){var e=t.memoizedState;if(e===null&&(t=t.alternate,t!==null&&(e=t.memoizedState)),e!==null)return e.dehydrated}return null}function E(t){if(t.tag===31){var e=t.memoizedState;if(e===null&&(t=t.alternate,t!==null&&(e=t.memoizedState)),e!==null)return e.dehydrated}return null}function Z(t){if(O(t)!==t)throw Error(o(188))}function U(t){var e=t.alternate;if(!e){if(e=O(t),e===null)throw Error(o(188));return e!==t?null:t}for(var l=t,a=e;;){var n=l.return;if(n===null)break;var u=n.alternate;if(u===null){if(a=n.return,a!==null){l=a;continue}break}if(n.child===u.child){for(u=n.child;u;){if(u===l)return Z(n),t;if(u===a)return Z(n),e;u=u.sibling}throw Error(o(188))}if(l.return!==a.return)l=n,a=u;else{for(var c=!1,f=n.child;f;){if(f===l){c=!0,l=n,a=u;break}if(f===a){c=!0,a=n,l=u;break}f=f.sibling}if(!c){for(f=u.child;f;){if(f===l){c=!0,l=u,a=n;break}if(f===a){c=!0,a=u,l=n;break}f=f.sibling}if(!c)throw Error(o(189))}}if(l.alternate!==a)throw Error(o(190))}if(l.tag!==3)throw Error(o(188));return l.stateNode.current===l?t:e}function w(t){var e=t.tag;if(e===5||e===26||e===27||e===6)return t;for(t=t.child;t!==null;){if(e=w(t),e!==null)return e;t=t.sibling}return null}function x(t,e,l,a,n,u){for(;t!==null;){if((t.tag===5||t.tag===27||t.tag===6)&&l(t,a,n,u)||(t.tag!==22||t.memoizedState===null)&&(e||t.tag!==5&&t.tag!==27)&&x(t.child,e,l,a,n,u))return!0;t=t.sibling}return!1}function J(t){for(t=t.return;t!==null;){if(t.tag===3||t.tag===5||t.tag===27)return t;t=t.return}return null}function ut(t){var e=!1;for(t=t.return;t!==null&&(t.tag===4&&(e=!0),!(t.tag===3||t.tag===5||t.tag===27));)t=t.return;return e}function K(t){var e=[null,null],l=J(t);return l===null||P(e,t,l.child,{foundSelf:!1}),e}function P(t,e,l,a){for(;l!==null;){if(l===e)a.foundSelf=!0;else if(l.tag===5||l.tag===27||l.tag===6){if(a.foundSelf)return t[1]=l,!0;t[0]=l}else if((l.tag!==22||l.memoizedState===null)&&P(t,e,l.child,a))return!0;l=l.sibling}return!1}function it(t){switch(t.tag){case 5:case 27:case 6:return t.stateNode;case 3:return t.stateNode.containerInfo;default:throw Error(o(559))}}var jt=null,Vt=null;function pe(t,e,l){return t===l?!0:t===e?(jt=t,!0):!1}function Ce(t,e,l){return t===l?(Vt=t,!1):t===e?(Vt!==null&&(jt=t),!0):!1}function Ft(t){if(t===null)return null;do t=t===null?null:t.return;while(t&&t.tag!==5&&t.tag!==27&&t.tag!==3);return t||null}function oe(t,e,l){for(var a=0,n=t;n;n=l(n))a++;n=0;for(var u=e;u;u=l(u))n++;for(;0<a-n;)t=l(t),a--;for(;0<n-a;)e=l(e),n--;for(;a--;){if(t===e||e!==null&&t===e.alternate)return t;t=l(t),e=l(e)}return null}var st=Object.assign,vt=Symbol.for("react.element"),Wt=Symbol.for("react.transitional.element"),te=Symbol.for("react.portal"),Lt=Symbol.for("react.fragment"),de=Symbol.for("react.strict_mode"),Dt=Symbol.for("react.profiler"),Pe=Symbol.for("react.consumer"),H=Symbol.for("react.context"),q=Symbol.for("react.forward_ref"),L=Symbol.for("react.suspense"),tt=Symbol.for("react.suspense_list"),xt=Symbol.for("react.memo"),ht=Symbol.for("react.lazy"),ee=Symbol.for("react.activity"),Oe=Symbol.for("react.legacy_hidden"),ue=Symbol.for("react.memo_cache_sentinel"),v=Symbol.for("react.view_transition"),R=Symbol.for("react.recoverable"),F=Symbol.iterator;function k(t){return t===null||typeof t!="object"?null:(t=F&&t[F]||t["@@iterator"],typeof t=="function"?t:null)}var yt=Symbol.for("react.client.reference");function dt(t){if(t==null)return null;if(typeof t=="function")return t.$$typeof===yt?null:t.displayName||t.name||null;if(typeof t=="string")return t;switch(t){case Lt:return"Fragment";case Dt:return"Profiler";case de:return"StrictMode";case L:return"Suspense";case tt:return"SuspenseList";case ee:return"Activity";case v:return"ViewTransition"}if(typeof t=="object")switch(t.$$typeof){case te:return"Portal";case H:return t.displayName||"Context";case Pe:return(t._context.displayName||"Context")+".Consumer";case q:var e=t.render;return t=t.displayName,t||(t=e.displayName||e.name||"",t=t!==""?"ForwardRef("+t+")":"ForwardRef"),t;case xt:return e=t.displayName||null,e!==null?e:dt(t.type)||"Memo";case ht:e=t._payload,t=t._init;try{return dt(t(e))}catch{}}return null}var Tt=Array.isArray,G=r.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,at=g.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,be={pending:!1,data:null,method:null,action:Line truncated */var Uh;function By(){if(Uh)return ti;Uh=1;var i=Dy(),r=fr(),m=Hy();function o(t){var e="https://react.dev/errors/"+t;if(1<arguments.length){e+="?args[]="+encodeURIComponent(arguments[1]);for(var l=2;l<arguments.length;l++)e+="&args[]="+encodeURIComponent(arguments[l])}return"Minified React error #"+t+"; visit "+e+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}function _(t){return!(!t||t.nodeType!==1&&t.nodeType!==9&&t.nodeType!==11)}function M(t){for(var e=t,l=e;l&&!l.alternate;)e=l,(e.flags&4098)!==0&&(t=e.return),l=e.return;for(;e.return;)e=e.return;return e.tag===3?t:null}function N(t){if(t.tag===13){var e=t.memoizedState;if(e===null&&(t=t.alternate,t!==null&&(e=t.memoizedState)),e!==null)return e.dehydrated}return null}function j(t){if(t.tag===31){var e=t.memoizedState;if(e===null&&(t=t.alternate,t!==null&&(e=t.memoizedState)),e!==null)return e.dehydrated}return null}function B(t){if(M(t)!==t)throw Error(o(188))}function R(t){var e=t.alternate;if(!e){if(e=M(t),e===null)throw Error(o(188));return e!==t?null:t}for(var l=t,a=e;;){var n=l.return;if(n===null)break;var u=n.alternate;if(u===null){if(a=n.return,a!==null){l=a;continue}break}if(n.child===u.child){for(u=n.child;u;){if(u===l)return B(n),t;if(u===a)return B(n),e;u=u.sibling}throw Error(o(188))}if(l.return!==a.return)l=n,a=u;else{for(var c=!1,f=n.child;f;){if(f===l){c=!0,l=n,a=u;break}if(f===a){c=!0,a=n,l=u;break}f=f.sibling}if(!c){for(f=u.child;f;){if(f===l){c=!0,l=u,a=n;break}if(f===a){c=!0,a=u,l=n;break}f=f.sibling}if(!c)throw Error(o(189))}}if(l.alternate!==a)throw Error(o(190))}if(l.tag!==3)throw Error(o(188));return l.stateNode.current===l?t:e}function G(t){var e=t.tag;if(e===5||e===26||e===27||e===6)return t;for(t=t.child;t!==null;){if(e=G(t),e!==null)return e;t=t.sibling}return null}function E(t,e,l,a,n,u){for(;t!==null;){if((t.tag===5||t.tag===27||t.tag===6)&&l(t,a,n,u)||(t.tag!==22||t.memoizedState===null)&&(e||t.tag!==5&&t.tag!==27)&&E(t.child,e,l,a,n,u))return!0;t=t.sibling}return!1}function J(t){for(t=t.return;t!==null;){if(t.tag===3||t.tag===5||t.tag===27)return t;t=t.return}return null}function ut(t){var e=!1;for(t=t.return;t!==null&&(t.tag===4&&(e=!0),!(t.tag===3||t.tag===5||t.tag===27));)t=t.return;return e}function k(t){var e=[null,null],l=J(t);return l===null||P(e,t,l.child,{foundSelf:!1}),e}function P(t,e,l,a){for(;l!==null;){if(l===e)a.foundSelf=!0;else if(l.tag===5||l.tag===27||l.tag===6){if(a.foundSelf)return t[1]=l,!0;t[0]=l}else if((l.tag!==22||l.memoizedState===null)&&P(t,e,l.child,a))return!0;l=l.sibling}return!1}function it(t){switch(t.tag){case 5:case 27:case 6:return t.stateNode;case 3:return t.stateNode.containerInfo;default:throw Error(o(559))}}var Tt=null,Vt=null;function be(t,e,l){return t===l?!0:t===e?(Tt=t,!0):!1}function Me(t,e,l){return t===l?(Vt=t,!1):t===e?(Vt!==null&&(Tt=t),!0):!1}function Ft(t){if(t===null)return null;do t=t===null?null:t.return;while(t&&t.tag!==5&&t.tag!==27&&t.tag!==3);return t||null}function oe(t,e,l){for(var a=0,n=t;n;n=l(n))a++;n=0;for(var u=e;u;u=l(u))n++;for(;0<a-n;)t=l(t),a--;for(;0<n-a;)e=l(e),n--;for(;a--;){if(t===e||e!==null&&t===e.alternate)return t;t=l(t),e=l(e)}return null}var st=Object.assign,ht=Symbol.for("react.element"),Wt=Symbol.for("react.transitional.element"),te=Symbol.for("react.portal"),Lt=Symbol.for("react.fragment"),de=Symbol.for("react.strict_mode"),Dt=Symbol.for("react.profiler"),Pe=Symbol.for("react.consumer"),H=Symbol.for("react.context"),w=Symbol.for("react.forward_ref"),L=Symbol.for("react.suspense"),tt=Symbol.for("react.suspense_list"),jt=Symbol.for("react.memo"),vt=Symbol.for("react.lazy"),ee=Symbol.for("react.activity"),Oe=Symbol.for("react.legacy_hidden"),ue=Symbol.for("react.memo_cache_sentinel"),v=Symbol.for("react.view_transition"),D=Symbol.for("react.recoverable"),F=Symbol.iterator;function K(t){return t===null||typeof t!="object"?null:(t=F&&t[F]||t["@@iterator"],typeof t=="function"?t:null)}var yt=Symbol.for("react.client.reference");function dt(t){if(t==null)return null;if(typeof t=="function")return t.$$typeof===yt?null:t.displayName||t.name||null;if(typeof t=="string")return t;switch(t){case Lt:return"Fragment";case Dt:return"Profiler";case de:return"StrictMode";case L:return"Suspense";case tt:return"SuspenseList";case ee:return"Activity";case v:return"ViewTransition"}if(typeof t=="object")switch(t.$$typeof){case te:return"Portal";case H:return t.displayName||"Context";case Pe:return(t._context.displayName||"Context")+".Consumer";case w:var e=t.render;return t=t.displayName,t||(t=e.displayName||e.name||"",t=t!==""?"ForwardRef("+t+")":"ForwardRef"),t;case jt:return e=t.displayName||null,e!==null?e:dt(t.type)||"Memo";case vt:e=t._payload,t=t._init;try{return dt(t(e))}catch{}}return null}var xt=Array.isArray,Q=r.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,at=m.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,xe={pending:!1,data:null,method:null,action:Line truncated
at`)?" (<anonymous>)":-1<l.stack.indexOf("@")?"@unknown:0:0":""}return` at`)?" (<anonymous>)":-1<l.stack.indexOf("@")?"@unknown:0:0":""}return`
`+ol+t+Dl}var De=!1;function el(t,e){if(!t||De)return"";De=!0;var l=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{var a={DetermineComponentFrameRoot:function(){try{if(e){var C=function(){throw Error()};if(Object.defineProperty(C.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(C,[])}catch(B){var y=B}Reflect.construct(t,[],C)}else{try{C.call()}catch(B){y=B}C=!1;try{var T=Object.getOwnPropertyDescriptor(t.prototype,"props");Object.defineProperty(t.prototype,"props",{configurable:!0,set:function(){throw Error()}}),C=!0,new t}finally{C&&(T!==void 0?Object.defineProperty(t.prototype,"props",T):delete t.prototype.props)}}}else{try{throw Error()}catch(B){y=B}(C=t())&&typeof C.catch=="function"&&C.catch(function(){})}}catch(B){if(B&&y&&typeof B.stack=="string")return[B.stack,y.stack]}return[null,null]}};a.DetermineComponentFrameRoot.displayName="DetermineComponentFrameRoot";var n=Object.getOwnPropertyDescriptor(a.DetermineComponentFrameRoot,"name");n&&n.configurable&&Object.defineProperty(a.DetermineComponentFrameRoot,"name",{value:"DetermineComponentFrameRoot"});var u=a.DetermineComponentFrameRoot(),c=u[0],f=u[1];if(c&&f){var d=c.split(` `+ol+t+Dl}var Ue=!1;function el(t,e){if(!t||Ue)return"";Ue=!0;var l=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{var a={DetermineComponentFrameRoot:function(){try{if(e){var A=function(){throw Error()};if(Object.defineProperty(A.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(A,[])}catch(q){var g=q}Reflect.construct(t,[],A)}else{try{A.call()}catch(q){g=q}A=!1;try{var x=Object.getOwnPropertyDescriptor(t.prototype,"props");Object.defineProperty(t.prototype,"props",{configurable:!0,set:function(){throw Error()}}),A=!0,new t}finally{A&&(x!==void 0?Object.defineProperty(t.prototype,"props",x):delete t.prototype.props)}}}else{try{throw Error()}catch(q){g=q}(A=t())&&typeof A.catch=="function"&&A.catch(function(){})}}catch(q){if(q&&g&&typeof q.stack=="string")return[q.stack,g.stack]}return[null,null]}};a.DetermineComponentFrameRoot.displayName="DetermineComponentFrameRoot";var n=Object.getOwnPropertyDescriptor(a.DetermineComponentFrameRoot,"name");n&&n.configurable&&Object.defineProperty(a.DetermineComponentFrameRoot,"name",{value:"DetermineComponentFrameRoot"});var u=a.DetermineComponentFrameRoot(),c=u[0],f=u[1];if(c&&f){var d=c.split(`
`),p=f.split(` `),p=f.split(`
`);for(n=a=0;a<d.length&&!d[a].includes("DetermineComponentFrameRoot");)a++;for(;n<p.length&&!p[n].includes("DetermineComponentFrameRoot");)n++;if(a===d.length||n===p.length)for(a=d.length-1,n=p.length-1;1<=a&&0<=n&&d[a]!==p[n];)n--;for(;1<=a&&0<=n;a--,n--)if(d[a]!==p[n]){if(a!==1||n!==1)do if(a--,n--,0>n||d[a]!==p[n]){var j=` `);for(n=a=0;a<d.length&&!d[a].includes("DetermineComponentFrameRoot");)a++;for(;n<p.length&&!p[n].includes("DetermineComponentFrameRoot");)n++;if(a===d.length||n===p.length)for(a=d.length-1,n=p.length-1;1<=a&&0<=n&&d[a]!==p[n];)n--;for(;1<=a&&0<=n;a--,n--)if(d[a]!==p[n]){if(a!==1||n!==1)do if(a--,n--,0>n||d[a]!==p[n]){var T=`
`+d[a].replace(" at new "," at ");return t.displayName&&j.includes("<anonymous>")&&(j=j.replace("<anonymous>",t.displayName)),j}while(1<=a&&0<=n);break}}}finally{De=!1,Error.prepareStackTrace=l}return(l=t?t.displayName||t.name:"")?ie(l):""}function Ul(t,e){switch(t.tag){case 26:case 27:case 5:return ie(t.type);case 16:return ie("Lazy");case 13:return t.child!==e&&e!==null?ie("Suspense Fallback"):ie("Suspense");case 19:return ie("SuspenseList");case 0:case 15:return el(t.type,!1);case 11:return el(t.type.render,!1);case 1:return el(t.type,!0);case 31:return ie("Activity");case 30:return ie("ViewTransition");default:return""}}function dl(t){try{var e="",l=null;do e+=Ul(t,l),l=t,t=t.return;while(t);return e}catch(a){return` `+d[a].replace(" at new "," at ");return t.displayName&&T.includes("<anonymous>")&&(T=T.replace("<anonymous>",t.displayName)),T}while(1<=a&&0<=n);break}}}finally{Ue=!1,Error.prepareStackTrace=l}return(l=t?t.displayName||t.name:"")?ie(l):""}function Ul(t,e){switch(t.tag){case 26:case 27:case 5:return ie(t.type);case 16:return ie("Lazy");case 13:return t.child!==e&&e!==null?ie("Suspense Fallback"):ie("Suspense");case 19:return ie("SuspenseList");case 0:case 15:return el(t.type,!1);case 11:return el(t.type.render,!1);case 1:return el(t.type,!0);case 31:return ie("Activity");case 30:return ie("ViewTransition");default:return""}}function dl(t){try{var e="",l=null;do e+=Ul(t,l),l=t,t=t.return;while(t);return e}catch(a){return`
Error generating stack: `+a.message+` Error generating stack: `+a.message+`
`+a.stack}}var kt=Object.prototype.hasOwnProperty,ra=i.unstable_scheduleCallback,oa=i.unstable_cancelCallback,kl=i.unstable_shouldYield,Qa=i.unstable_requestPaint,ae=i.unstable_now,uu=i.unstable_getCurrentPriorityLevel,mn=i.unstable_ImmediatePriority,vn=i.unstable_UserBlockingPriority,Ze=i.unstable_NormalPriority,Xa=i.unstable_LowPriority,da=i.unstable_IdlePriority,iu=i.log,cu=i.unstable_setDisableYieldValue,Jl=null,D=null;function z(t){if(typeof iu=="function"&&cu(t),D&&typeof D.setStrictMode=="function")try{D.setStrictMode(Jl,t)}catch{}}var Y=Math.clz32?Math.clz32:ma,$=Math.log,Ut=Math.LN2;function ma(t){return t>>>=0,t===0?32:31-($(t)/Ut|0)|0}var ll=256,Ue=262144,me=4194304;function ml(t){var e=t&42;if(e!==0)return e;switch(t&-t){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return t&-t;case 262144:case 524288:case 1048576:case 2097152:return t&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return t&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return t}}function M(t,e,l){var a=t.pendingLanes;if(a===0)return 0;var n=0,u=t.suspendedLanes,c=t.pingedLanes;t=t.warmLanes;var f=a&134217727;return f!==0?(a=f&~u,a!==0?n=ml(a):(c&=f,c!==0?n=ml(c):l||(l=f&~t,l!==0&&(n=ml(l))))):(f=a&~u,f!==0?n=ml(f):c!==0?n=ml(c):l||(l=a&~t,l!==0&&(n=ml(l)))),n===0?0:e!==0&&e!==n&&(e&u)===0&&(u=n&-n,l=e&-e,u>=l||u===32&&(l&4194048)!==0)?e:n}function X(t,e){return(t.pendingLanes&~(t.suspendedLanes&~t.pingedLanes)&e)===0}function W(t,e){(e&8)!==0&&(e|=e&32);var l=t.entangledLanes;if(l!==0)for(t=t.entanglements,l&=e;0<l;){var a=31-Y(l),n=1<<a;e|=t[a],l&=~n}return e}function wt(t,e){switch(t){case 1:case 2:case 4:case 8:case 64:return e+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Ot(){var t=me;return me<<=1,(me&62914560)===0&&(me=4194304),t}function $t(t){for(var e=[],l=0;31>l;l++)e.push(t);return e}function Le(t,e){t.pendingLanes|=e,e!==268435456&&(t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0)}function ei(t,e,l,a,n,u){var c=t.pendingLanes;t.pendingLanes=l,t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0,t.expiredLanes&=l,t.entangledLanes&=l,t.errorRecoveryDisabledLanes&=l,t.shellSuspendCounter=0;var f=t.entanglements,d=t.expirationTimes,p=t.hiddenUpdates;for(l=c&~l;0<l;){var j=31-Y(l),C=1<<j;f[j]=0,d[j]=-1;var y=p[j];if(y!==null)for(p[j]=null,j=0;j<y.length;j++){var T=y[j];T!==null&&(T.lane&=-536870913)}l&=~C}a!==0&&Ke(t,a,0),u!==0&&n===0&&t.tag!==0&&(t.suspendedLanes|=u&~(c&~e))}function Ke(t,e,l){t.pendingLanes|=e,t.suspendedLanes&=~e;var a=31-Y(e);t.entangledLanes|=e,t.entanglements[a]=t.entanglements[a]|1073741824|l&261930}function He(t,e){var l=t.entangledLanes|=e;for(t=t.entanglements;l;){var a=31-Y(l),n=1<<a;n&e|t[a]&e&&(t[a]|=e),l&=~n}}function li(t,e){var l=e&-e;return l=(l&42)!==0?1:Nc(l),(l&(t.suspendedLanes|e))!==0?0:l}function Nc(t){switch(t){case 2:t=1;break;case 8:t=4;break;case 32:t=16;break;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:t=128;break;case 268435456:t=134217728;break;default:t=0}return t}function Ac(t){return t&=-t,2<t?8<t?(t&134217727)!==0?32:268435456:8:2}function rr(){var t=at.p;return t!==0?t:(t=window.event,t===void 0?32:Sv(t.type))}function or(t,e){var l=at.p;try{return at.p=t,e()}finally{at.p=l}}var Fl=Math.random().toString(36).slice(2),Te="__reactFiber$"+Fl,ke="__reactProps$"+Fl,hn="__reactContainer$"+Fl,dr="__reactEvents$"+Fl,Xv="__reactListeners$"+Fl,Vv="__reactHandles$"+Fl,mr="__reactResources$"+Fl,su="__reactMarker$"+Fl,ai="__reactLoad$"+Fl;function ni(t){delete t[Te],delete t[ke],delete t[Xv],delete t[Vv]}function Va(t){var e;if(e=t[Te])return e;for(var l=t.parentNode;l;){if(e=l[hn]||l[Te]){if(l=e.alternate,e.child!==null||l!==null&&l.child!==null)for(t=Im(t);t!==null;){if(l=t[Te])return l;t=Im(t)}return e}t=l,l=t.parentNode}return null}function yn(t){if(t=t[Te]||t[hn]){var e=t.tag;if(e===5||e===6||e===13||e===31||e===26||e===27||e===3)return t}return null}function fu(t){var e=t.tag;if(e===5||e===26||e===27||e===6)return t.stateNode;throw Error(o(33))}function gn(t){var e=t[mr];return e||(e=t[mr]={hoistableStyles:new Map,hoistableScripts:new Map}),e}function he(t){t[su]=!0}function vr(t){t[ai]=void 0}var hr=new Set,yr={};function Za(t,e){Sn(t,e),Sn(t+"Capture",e)}function Sn(t,e){forLine truncated `+a.stack}}var Kt=Object.prototype.hasOwnProperty,oa=i.unstable_scheduleCallback,da=i.unstable_cancelCallback,Jl=i.unstable_shouldYield,Xa=i.unstable_requestPaint,ae=i.unstable_now,iu=i.unstable_getCurrentPriorityLevel,mn=i.unstable_ImmediatePriority,hn=i.unstable_UserBlockingPriority,Ze=i.unstable_NormalPriority,Va=i.unstable_LowPriority,ma=i.unstable_IdlePriority,cu=i.log,su=i.unstable_setDisableYieldValue,Fl=null,U=null;function z(t){if(typeof cu=="function"&&su(t),U&&typeof U.setStrictMode=="function")try{U.setStrictMode(Fl,t)}catch{}}var Y=Math.clz32?Math.clz32:ha,$=Math.log,Ut=Math.LN2;function ha(t){return t>>>=0,t===0?32:31-($(t)/Ut|0)|0}var ll=256,He=262144,me=4194304;function ml(t){var e=t&42;if(e!==0)return e;switch(t&-t){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return t&-t;case 262144:case 524288:case 1048576:case 2097152:return t&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return t&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return t}}function O(t,e,l){var a=t.pendingLanes;if(a===0)return 0;var n=0,u=t.suspendedLanes,c=t.pingedLanes;t=t.warmLanes;var f=a&134217727;return f!==0?(a=f&~u,a!==0?n=ml(a):(c&=f,c!==0?n=ml(c):l||(l=f&~t,l!==0&&(n=ml(l))))):(f=a&~u,f!==0?n=ml(f):c!==0?n=ml(c):l||(l=a&~t,l!==0&&(n=ml(l)))),n===0?0:e!==0&&e!==n&&(e&u)===0&&(u=n&-n,l=e&-e,u>=l||u===32&&(l&4194048)!==0)?e:n}function V(t,e){return(t.pendingLanes&~(t.suspendedLanes&~t.pingedLanes)&e)===0}function W(t,e){(e&8)!==0&&(e|=e&32);var l=t.entangledLanes;if(l!==0)for(t=t.entanglements,l&=e;0<l;){var a=31-Y(l),n=1<<a;e|=t[a],l&=~n}return e}function Gt(t,e){switch(t){case 1:case 2:case 4:case 8:case 64:return e+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Mt(){var t=me;return me<<=1,(me&62914560)===0&&(me=4194304),t}function $t(t){for(var e=[],l=0;31>l;l++)e.push(t);return e}function Le(t,e){t.pendingLanes|=e,e!==268435456&&(t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0)}function li(t,e,l,a,n,u){var c=t.pendingLanes;t.pendingLanes=l,t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0,t.expiredLanes&=l,t.entangledLanes&=l,t.errorRecoveryDisabledLanes&=l,t.shellSuspendCounter=0;var f=t.entanglements,d=t.expirationTimes,p=t.hiddenUpdates;for(l=c&~l;0<l;){var T=31-Y(l),A=1<<T;f[T]=0,d[T]=-1;var g=p[T];if(g!==null)for(p[T]=null,T=0;T<g.length;T++){var x=g[T];x!==null&&(x.lane&=-536870913)}l&=~A}a!==0&&ke(t,a,0),u!==0&&n===0&&t.tag!==0&&(t.suspendedLanes|=u&~(c&~e))}function ke(t,e,l){t.pendingLanes|=e,t.suspendedLanes&=~e;var a=31-Y(e);t.entangledLanes|=e,t.entanglements[a]=t.entanglements[a]|1073741824|l&261930}function Be(t,e){var l=t.entangledLanes|=e;for(t=t.entanglements;l;){var a=31-Y(l),n=1<<a;n&e|t[a]&e&&(t[a]|=e),l&=~n}}function ai(t,e){var l=e&-e;return l=(l&42)!==0?1:Cc(l),(l&(t.suspendedLanes|e))!==0?0:l}function Cc(t){switch(t){case 2:t=1;break;case 8:t=4;break;case 32:t=16;break;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:t=128;break;case 268435456:t=134217728;break;default:t=0}return t}function Ac(t){return t&=-t,2<t?8<t?(t&134217727)!==0?32:268435456:8:2}function or(){var t=at.p;return t!==0?t:(t=window.event,t===void 0?32:ph(t.type))}function dr(t,e){var l=at.p;try{return at.p=t,e()}finally{at.p=l}}var Wl=Math.random().toString(36).slice(2),Te="__reactFiber$"+Wl,Ke="__reactProps$"+Wl,vn="__reactContainer$"+Wl,mr="__reactEvents$"+Wl,Zh="__reactListeners$"+Wl,Lh="__reactHandles$"+Wl,hr="__reactResources$"+Wl,fu="__reactMarker$"+Wl,ni="__reactLoad$"+Wl;function ui(t){delete t[Te],delete t[Ke],delete t[Zh],delete t[Lh]}function Za(t){var e;if(e=t[Te])return e;for(var l=t.parentNode;l;){if(e=l[vn]||l[Te]){if(l=e.alternate,e.child!==null||l!==null&&l.child!==null)for(t=Pm(t);t!==null;){if(l=t[Te])return l;t=Pm(t)}return e}t=l,l=t.parentNode}return null}function yn(t){if(t=t[Te]||t[vn]){var e=t.tag;if(e===5||e===6||e===13||e===31||e===26||e===27||e===3)return t}return null}function ru(t){var e=t.tag;if(e===5||e===26||e===27||e===6)return t.stateNode;throw Error(o(33))}function gn(t){var e=t[hr];return e||(e=t[hr]={hoistableStyles:new Map,hoistableScripts:new Map}),e}function ye(t){t[fu]=!0}function vr(t){t[ni]=void 0}var yr=new Set,gr={};function La(t,e){Sn(t,e),Sn(t+"Capture",e)}function Sn(t,e){forLine truncated
`).replace(M0,"")}function Rm(t,e){return e=zm(e),zm(t)===e}function Rt(t,e,l,a,n,u){switch(l){case"children":if(typeof a=="string")e==="body"||e==="textarea"&&a===""||bn(t,a);else if(typeof a=="number"||typeof a=="bigint")e!=="body"&&bn(t,""+a);else return;break;case"className":ii(t,"class",a);break;case"tabIndex":ii(t,"tabindex",a);break;case"dir":case"role":case"viewBox":case"width":case"height":ii(t,l,a);break;case"style":Nr(t,a,u);return;case"data":if(e!=="object"){ii(t,"data",a);break}case"src":case"href":if(a===""&&(e!=="a"||l!=="href")){t.removeAttribute(l);break}if(a==null||typeof a=="function"||typeof a=="symbol"||typeof a=="boolean"){t.removeAttribute(l);break}a=ci(a),t.setAttribute(l,a);break;case"action":case"formAction":if(typeof a=="function"){t.setAttribute(l,"javascript:throw new Error('A React form was unexpectedly submitted. If you called form.submit() manually, consider using form.requestSubmit() instead. If you\\'re trying to use event.stopPropagation() in a submit event handler, consider also calling event.preventDefault().')");break}else typeof u=="function"&&(l==="formAction"?(e!=="input"&&Rt(t,e,"name",n.name,n,null),Rt(t,e,"formEncType",n.formEncType,n,null),Rt(t,e,"formMethod",n.formMethod,n,null),Rt(t,e,"formTarget",n.formTarget,n,null)):(Rt(t,e,"encType",n.encType,n,null),Rt(t,e,"method",n.method,n,null),Rt(t,e,"target",n.target,n,null)));if(a==null||typeof a=="symbol"||typeof a=="boolean"){t.removeAttribute(l);break}a=ci(a),t.setAttribute(l,a);break;case"onClick":a!=null&&(t.onclick=Hl);return;case"onScroll":a!=null&&St("scroll",t);return;case"onScrollEnd":a!=null&&St("scrollend",t);return;case"dangerouslySetInnerHTML":if(a!=null){if(typeof a!="object"||!("__html"in a))throw Error(o(61));if(l=a.__html,l!=null){if(n.children!=null)throw Error(o(60));(u!=null?u.__html:void 0)!==l&&(t.innerHTML=l)}}break;case"multiple":t.multiple=a&&typeof a!="function"&&typeof a!="symbol";break;case"muted":t.muted=a&&typeof a!="function"&&typeof a!="symbol";break;case"suppressContentEditableWarning":case"suppressHydrationWarning":case"defaultValue":case"defaultChecked":case"innerHTML":case"ref":break;case"autoFocus":break;case"xlinkHref":if(a==null||typeof a=="function"||typeof a=="boolean"||typeof a=="symbol"){t.removeAttribute("xlink:href");break}l=ci(a),t.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",l);break;case"contentEditable":case"spellCheck":case"draggable":case"value":case"autoReverse":case"externalResourcesRequired":case"focusable":case"preserveAlpha":a!=null&&typeof a!="function"&&typeof a!="symbol"?t.setAttribute(l,a):t.removeAttribute(l);break;case"inert":case"allowFullScreen":case"async":case"autoPlay":case"controls":case"credentialless":case"default":case"defer":case"disabled":case"disablePictureInPicture":case"disableRemotePlayback":case"formNoValidate":case"hidden":case"loop":case"noModule":case"noValidate":case"open":case"playsInline":case"readOnly":case"required":case"reversed":case"scoped":case"seamless":case"itemScope":a&&typeof a!="function"&&typeof a!="symbol"?t.setAttribute(l,""):t.removeAttribute(l);break;case"capture":case"download":a===!0?t.setAttribute(l,""):a!==!1&&a!=null&&typeof a!="function"&&typeof a!="symbol"?t.setAttribute(l,a):t.removeAttribute(l);break;case"cols":case"rows":case"size":case"span":a!=null&&typeof a!="function"&&typeof a!="symbol"&&!isNaN(a)&&1<=a?t.setAttribute(l,a):t.removeAttribute(l);break;case"rowSpan":case"start":a==null||typeof a=="function"||typeof a=="symbol"||isNaN(a)?t.removeAttribute(l):t.setAttribute(l,a);break;case"popover":St("beforetoggle",t),St("toggle",t),ui(t,"popover",a);break;case"xlinkActuate":Wl(t,"http://www.w3.org/1999/xlink","xlink:actuate",a);break;case"xlinkArcrole":Wl(t,"http://www.w3.org/1999/xlink","xlink:arcrole",a);break;case"xlinkRole":Wl(t,"http://www.w3.org/1999/xlink","xlink:role",a);break;case"xlinkShow":Wl(t,"http://www.w3.org/1999/xlink","xlink:show",a);break;case"xlinkTitle":Wl(t,"http://www.w3.org/1999/xlink","xlink:title",a);break;case"xlinkType":Wl(t,"http://www.w3.org/1999/xlink","xlink:type",a);break;case"xmlBase":Wl(t,"http://www.w3.org/XML/1998/namespace","xml:base",a);break;case"xmlLang":Wl(t,"http://www.w3.org/XML/1998/namespace","xml:lang",a);break;case"xmlSpace":Wl(t,"http://www.w3.org/XML/1998/namespace","xml:space",a);break;case"is":ui(t,"is",a);break;case"innerText":case"textContent":return;default:if(!(2<l.length)||l[0]!=="o"&&l[0]!=="O"||l[1]!=="n"&&l[1]!=="N")l=Fv.get(l)||l,ui(t,l,a);else return}_t=!0}function Mf(t,e,l,a,n,u){switch(l){case"style":Nr(t,a,u);return;case"dangerouslySetInnerHTML":if(a!=null){if(typeof a!="object"||!("__html"in a))throw Error(o(61));if(l=a.__html,l!=null){if(n.children!=null)throw Error(o(60));(u!=null?u.__html:void 0)!==l&&(t.innerHTML=l)}}break;case"children":if(typeof a=="string")bn(t,a);else if(typeof a=="number"||typeof a=="bigint")bn(t,""+a);else return;break;case"onScroll":a!=null&&St("scroll",t);return;case"onScrollEnd":a!=null&&St("scroLine truncated `).replace(R0,"")}function Dm(t,e){return e=Rm(e),Rm(t)===e}function Rt(t,e,l,a,n,u){switch(l){case"children":if(typeof a=="string")e==="body"||e==="textarea"&&a===""||bn(t,a);else if(typeof a=="number"||typeof a=="bigint")e!=="body"&&bn(t,""+a);else return;break;case"className":ci(t,"class",a);break;case"tabIndex":ci(t,"tabindex",a);break;case"dir":case"role":case"viewBox":case"width":case"height":ci(t,l,a);break;case"style":Cr(t,a,u);return;case"data":if(e!=="object"){ci(t,"data",a);break}case"src":case"href":if(a===""&&(e!=="a"||l!=="href")){t.removeAttribute(l);break}if(a==null||typeof a=="function"||typeof a=="symbol"||typeof a=="boolean"){t.removeAttribute(l);break}a=si(a),t.setAttribute(l,a);break;case"action":case"formAction":if(typeof a=="function"){t.setAttribute(l,"javascript:throw new Error('A React form was unexpectedly submitted. If you called form.submit() manually, consider using form.requestSubmit() instead. If you\\'re trying to use event.stopPropagation() in a submit event handler, consider also calling event.preventDefault().')");break}else typeof u=="function"&&(l==="formAction"?(e!=="input"&&Rt(t,e,"name",n.name,n,null),Rt(t,e,"formEncType",n.formEncType,n,null),Rt(t,e,"formMethod",n.formMethod,n,null),Rt(t,e,"formTarget",n.formTarget,n,null)):(Rt(t,e,"encType",n.encType,n,null),Rt(t,e,"method",n.method,n,null),Rt(t,e,"target",n.target,n,null)));if(a==null||typeof a=="symbol"||typeof a=="boolean"){t.removeAttribute(l);break}a=si(a),t.setAttribute(l,a);break;case"onClick":a!=null&&(t.onclick=Hl);return;case"onScroll":a!=null&&St("scroll",t);return;case"onScrollEnd":a!=null&&St("scrollend",t);return;case"dangerouslySetInnerHTML":if(a!=null){if(typeof a!="object"||!("__html"in a))throw Error(o(61));if(l=a.__html,l!=null){if(n.children!=null)throw Error(o(60));(u!=null?u.__html:void 0)!==l&&(t.innerHTML=l)}}break;case"multiple":t.multiple=a&&typeof a!="function"&&typeof a!="symbol";break;case"muted":t.muted=a&&typeof a!="function"&&typeof a!="symbol";break;case"suppressContentEditableWarning":case"suppressHydrationWarning":case"defaultValue":case"defaultChecked":case"innerHTML":case"ref":break;case"autoFocus":break;case"xlinkHref":if(a==null||typeof a=="function"||typeof a=="boolean"||typeof a=="symbol"){t.removeAttribute("xlink:href");break}l=si(a),t.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",l);break;case"contentEditable":case"spellCheck":case"draggable":case"value":case"autoReverse":case"externalResourcesRequired":case"focusable":case"preserveAlpha":a!=null&&typeof a!="function"&&typeof a!="symbol"?t.setAttribute(l,a):t.removeAttribute(l);break;case"inert":case"allowFullScreen":case"async":case"autoPlay":case"controls":case"credentialless":case"default":case"defer":case"disabled":case"disablePictureInPicture":case"disableRemotePlayback":case"formNoValidate":case"hidden":case"loop":case"noModule":case"noValidate":case"open":case"playsInline":case"readOnly":case"required":case"reversed":case"scoped":case"seamless":case"itemScope":a&&typeof a!="function"&&typeof a!="symbol"?t.setAttribute(l,""):t.removeAttribute(l);break;case"capture":case"download":a===!0?t.setAttribute(l,""):a!==!1&&a!=null&&typeof a!="function"&&typeof a!="symbol"?t.setAttribute(l,a):t.removeAttribute(l);break;case"cols":case"rows":case"size":case"span":a!=null&&typeof a!="function"&&typeof a!="symbol"&&!isNaN(a)&&1<=a?t.setAttribute(l,a):t.removeAttribute(l);break;case"rowSpan":case"start":a==null||typeof a=="function"||typeof a=="symbol"||isNaN(a)?t.removeAttribute(l):t.setAttribute(l,a);break;case"popover":St("beforetoggle",t),St("toggle",t),ii(t,"popover",a);break;case"xlinkActuate":$l(t,"http://www.w3.org/1999/xlink","xlink:actuate",a);break;case"xlinkArcrole":$l(t,"http://www.w3.org/1999/xlink","xlink:arcrole",a);break;case"xlinkRole":$l(t,"http://www.w3.org/1999/xlink","xlink:role",a);break;case"xlinkShow":$l(t,"http://www.w3.org/1999/xlink","xlink:show",a);break;case"xlinkTitle":$l(t,"http://www.w3.org/1999/xlink","xlink:title",a);break;case"xlinkType":$l(t,"http://www.w3.org/1999/xlink","xlink:type",a);break;case"xmlBase":$l(t,"http://www.w3.org/XML/1998/namespace","xml:base",a);break;case"xmlLang":$l(t,"http://www.w3.org/XML/1998/namespace","xml:lang",a);break;case"xmlSpace":$l(t,"http://www.w3.org/XML/1998/namespace","xml:space",a);break;case"is":ii(t,"is",a);break;case"innerText":case"textContent":return;default:if(!(2<l.length)||l[0]!=="o"&&l[0]!=="O"||l[1]!=="n"&&l[1]!=="N")l=$h.get(l)||l,ii(t,l,a);else return}_t=!0}function zf(t,e,l,a,n,u){switch(l){case"style":Cr(t,a,u);return;case"dangerouslySetInnerHTML":if(a!=null){if(typeof a!="object"||!("__html"in a))throw Error(o(61));if(l=a.__html,l!=null){if(n.children!=null)throw Error(o(60));(u!=null?u.__html:void 0)!==l&&(t.innerHTML=l)}}break;case"children":if(typeof a=="string")bn(t,a);else if(typeof a=="number"||typeof a=="bigint")bn(t,""+a);else return;break;case"onScroll":a!=null&&St("scroll",t);return;case"onScrollEnd":a!=null&&St("scroLine truncated
`;wt&&($t+=wt+` `;Gt&&($t+=Gt+`
`),Ot&&($t+=(Array.isArray(Ot)?Ot.join(` `),Mt&&($t+=(Array.isArray(Mt)?Mt.join(`
`):String(Ot))+` `):String(Mt))+`
`),$t+=JSON.stringify(W,null,2).slice(0,4e3),Rl($t),be("已返回登录信息,见下方")}catch(W){be("发起失败:"+W.message)}},[]),Ue=h.useCallback(async()=>{const M=K.trim();if(!M){ut("请填要查配额的用户 id");return}try{const X=await lt(et.adminQuotaUser(M));ut("用户 "+M.slice(0,8)+":本月用量 "+ir(X.used_usd_micros)+" / 配额 "+ir(X.quota_usd_micros)+(X.remaining_usd_micros!==null&&X.remaining_usd_micros!==void 0?"(剩余 "+ir(X.remaining_usd_micros)+")":"")+" | 月份 "+(X.month||""))}catch(X){ut(ur(X))}},[K]),me=h.useCallback(async()=>{if(window.confirm("确定手动触发 sweep 吗?超阈值的陈旧 running 任务会被标为 interrupted。"))try{const X=(await lt(et.adminSweep,"POST",{})).swept||[];ut("sweep 完成,清理 "+X.length+" 个任务"+(X.length?":"+X.join("、"):""))}catch(M){ut(ur(M))}},[]),ml=h.useCallback(async()=>{try{const M=await lt(et.adminBackup,"POST",{});ut("备份完成:backend="+M.backend+" | 路径 "+M.path+" | 大小 "+M.size_bytes+" 字节 | 任务 "+M.task_count+" 行")}catch(M){ut(ur(M))}},[]);return{keySaved:i,keyState:g,quotaText:_,healthText:A,adminGate:Z,adminBody:w,adminResult:J,adminUserId:K,setAdminUserId:P,projects:it,projectId:Vt,setProjectId:pe,projectMsg:Ce,githubRepos:oe,workers:vt,workersSummary:te,workersError:de,members:Pe,memberMsg:q,memberError:tt,skills:ht,apps:Oe,mcpServers:v,skillMsg:F,skillError:yt,mcpMsg:Tt,mcpOauthMsg:at,mcpOauthBox:Ga,envs:Xe,envCount:At,envMsg:Kl,envRepoLine:xl,envRepoBar:Kt,envRepoMsg:tl,envSelect:Dl,setEnvSelect:ie,models:De,modelCustomVisible:Ul,refreshHealth:oa,loadQuota:kl,probeAdmin:Qa,refreshProjects:ae,loadGithubRepos:uu,loadRelayModels:mn,refreshWorkers:vn,refreshEnvs:Ze,refreshMembers:Xa,refreshSkills:da,saveKeyInput:iu,clearKeyInput:cu,createProject:Jl,createEnv:D,archiveEnv:z,saveEnvRepo:Y,inviteMember:$,changeMemberRole:Ut,reloadMcp:ma,mcpOauth:ll,adminQuota:Ue,adminSweep:me,adminBackup:ml}}function ky(){const[i,r]=h.useState([]),[g,o]=h.useState(""),[_,O]=h.useState(""),[A,E]=h.useState(""),[Z,U]=h.useState(""),w=h.useCallback(async(K,P)=>{const it=K!==void 0?K:P;if(!it){r([]);return}try{const jt=await lt(et.tasks(it));r(jt.tasks||[]),o("")}catch(jt){o("加载失败:"+jt.message)}},[]),x=h.useMemo(()=>{const K=Z.trim().toLowerCase();return i.filter(P=>!(_&&P.status!==_||A&&(P.executor||"")!==A||K&&!((P.id||"")+" "+(P.prompt||"")).toLowerCase().includes(K)))},[i,_,A,Z]),J=x.length+" 个任务(共 "+i.length+" 个)",ut=h.useCallback(async(K,P)=>{const it={...K};P.length&&(it.upload_id=await Vy(P));const jt=await lt(et.tasksCreate,"POST",it);return"任务已建:"+Ge(jt.id)},[]);return{tasks:i,taskError:g,statusFilter:_,setStatusFilter:O,executorFilter:A,setExecutorFilter:E,searchText:Z,setSearchText:U,filteredTasks:x,taskCountText:J,refreshTasks:w,dispatch:ut}}function Jy(i,r){const[g,o]=h.useState(null),[_,O]=h.useState(""),[A,E]=h.useState(""),[Z,U]=h.useState(""),[w,x]=h.useState(""),[J,ut]=h.useState(!1),[K,P]=h.useState(""),[it,jt]=h.useState([]),[Vt,pe]=h.useState([]),[Ce,Ft]=h.useState(""),[oe,st]=h.useState([]),[vt,Wt]=h.useState(""),[te,Lt]=h.useState(""),[de,Dt]=h.useState([]),[Pe,H]=h.useState(""),[q,L]=h.useState(""),[tt,xt]=h.useState(""),[ht,ee]=h.useState(""),[Oe,ue]=h.useState([]),[v,R]=h.useState([]),[F,k]=h.useState(""),[yt,dt]=h.useState([]),[Tt,G]=h.useState(""),[at,be]=h.useState(""),[Ga,Rl]=h.useState(""),[Xe,Yt]=h.useState(""),[At,Me]=h.useState([]),[Kl,le]=h.useState(""),xl=h.useRef(null),Re=h.useRef(null),Kt=h.useRef(null);Kt.current=g;const Ve=h.useCallback(()=>{if(xl.current){try{xl.current.abort()}catch{}xl.current=null}Re.current&&(clearTimeout(Re.current),Re.current=null)},[]),tl=h.useCallback(async D=>{try{const z=await lt(et.taskAgents(D));pe(z.agents||[]),Ft(z.note||"")}catch(z){pe([]),Ft("子代理链路加载失败:"+z.message)}},[]),ol=h.useCallback(D=>{Re.current&&clearTimeout(Re.current),Re.current=setTimeout(()=>void tl(D),1e3)},[tl]),Dl=h.useCallback(async D=>{if(!D.coordinator_parts){jt([]);return}try{const z=await lt(et.tasksByParent(D.project_id||"",D.id));jt(z.tasks||[])}catch{jt([])}},[]),ie=h.useCallback(async D=>{try{const z=await lt(et.taskFollowups(D));ue(z.followups||[])}catch{ue([])}},[]),De=h.useCallback(async D=>{var Y;const z=D||((Y=Kt.current)==null?void 0:Y.id);if(z)try{const $=await lt(et.taskReviews(z));st($.reviews||[]),Lt("")}catch($){Lt("评审队列加载失败:"+$.message)}},[]),el=h.useCallback(async D=>{var Y;const z=D||((Y=Kt.current)==null?void 0:Y.id);if(z)try{const $=await lt(et.taskApprovals(z));R($.approvals||[])}catch($){k("审批队列加载失败:"+$.message)}},[]),Ul=h.useCallback(async D=>{try{const z=await lt(et.taskMessages(D));dt(z.messages||[])}catch{dt([])}},[]),dl=h.useCallback(async D=>{try{const z=await lt(et.taskThread(D)),Y=z.thread||z;let $=Y.turns;$==null&&($=Y.turn_count),$==null&&($=Y.turns_count),be("id "+(Y.id||D)+" | 名字 "+(Y.name||Y.thread_name||"")+" | 归档 "+(Y.aLine truncated `),$t+=JSON.stringify(W,null,2).slice(0,4e3),Rl($t),xe("已返回登录信息,见下方")}catch(W){xe("发起失败:"+W.message)}},[]),He=y.useCallback(async()=>{const O=k.trim();if(!O){ut("请填要查配额的用户 id");return}try{const V=await lt(et.adminQuotaUser(O));ut("用户 "+O.slice(0,8)+":本月用量 "+cr(V.used_usd_micros)+" / 配额 "+cr(V.quota_usd_micros)+(V.remaining_usd_micros!==null&&V.remaining_usd_micros!==void 0?"(剩余 "+cr(V.remaining_usd_micros)+")":"")+" | 月份 "+(V.month||""))}catch(V){ut(ir(V))}},[k]),me=y.useCallback(async()=>{if(window.confirm("确定手动触发 sweep 吗?超阈值的陈旧 running 任务会被标为 interrupted。"))try{const V=(await lt(et.adminSweep,"POST",{})).swept||[];ut("sweep 完成,清理 "+V.length+" 个任务"+(V.length?":"+V.join("、"):""))}catch(O){ut(ir(O))}},[]),ml=y.useCallback(async()=>{try{const O=await lt(et.adminBackup,"POST",{});ut("备份完成:backend="+O.backend+" | 路径 "+O.path+" | 大小 "+O.size_bytes+" 字节 | 任务 "+O.task_count+" 行")}catch(O){ut(ir(O))}},[]);return{keySaved:i,keyState:m,quotaText:_,healthText:N,adminGate:B,adminBody:G,adminResult:J,adminUserId:k,setAdminUserId:P,projects:it,projectId:Vt,setProjectId:be,projectMsg:Me,githubRepos:oe,workers:ht,workersSummary:te,workersError:de,members:Pe,memberMsg:w,memberError:tt,skills:vt,apps:Oe,mcpServers:v,skillMsg:F,skillError:yt,mcpMsg:xt,mcpOauthMsg:at,mcpOauthBox:Qa,envs:Xe,envCount:Ct,envMsg:Kl,envRepoLine:jl,envRepoBar:kt,envRepoMsg:tl,envSelect:Dl,setEnvSelect:ie,models:Ue,modelCustomVisible:Ul,refreshHealth:da,loadQuota:Jl,probeAdmin:Xa,refreshProjects:ae,loadGithubRepos:iu,loadRelayModels:mn,refreshWorkers:hn,refreshEnvs:Ze,refreshMembers:Va,refreshSkills:ma,saveKeyInput:cu,clearKeyInput:su,createProject:Fl,createEnv:U,archiveEnv:z,saveEnvRepo:Y,inviteMember:$,changeMemberRole:Ut,reloadMcp:ha,mcpOauth:ll,adminQuota:He,adminSweep:me,adminBackup:ml}}function Fy(){const[i,r]=y.useState([]),[m,o]=y.useState(""),[_,M]=y.useState(""),[N,j]=y.useState(""),[B,R]=y.useState(""),G=y.useCallback(async(k,P)=>{const it=k!==void 0?k:P;if(!it){r([]);return}try{const Tt=await lt(et.tasks(it));r(Tt.tasks||[]),o("")}catch(Tt){o("加载失败:"+Tt.message)}},[]),E=y.useMemo(()=>{const k=B.trim().toLowerCase();return i.filter(P=>!(_&&P.status!==_||N&&(P.executor||"")!==N||k&&!((P.id||"")+" "+(P.prompt||"")).toLowerCase().includes(k)))},[i,_,N,B]),J=E.length+" 个任务(共 "+i.length+" 个)",ut=y.useCallback(async(k,P)=>{const it={...k};P.length&&(it.upload_id=await Ly(P));const Tt=await lt(et.tasksCreate,"POST",it);return"任务已建:"+ve(Tt.id)},[]);return{tasks:i,taskError:m,statusFilter:_,setStatusFilter:M,executorFilter:N,setExecutorFilter:j,searchText:B,setSearchText:R,filteredTasks:E,taskCountText:J,refreshTasks:G,dispatch:ut}}function Wy(i,r){const[m,o]=y.useState(null),[_,M]=y.useState(""),[N,j]=y.useState(""),[B,R]=y.useState(""),[G,E]=y.useState(""),[J,ut]=y.useState(!1),[k,P]=y.useState(""),[it,Tt]=y.useState([]),[Vt,be]=y.useState([]),[Me,Ft]=y.useState(""),[oe,st]=y.useState([]),[ht,Wt]=y.useState(""),[te,Lt]=y.useState(""),[de,Dt]=y.useState([]),[Pe,H]=y.useState(""),[w,L]=y.useState(""),[tt,jt]=y.useState(""),[vt,ee]=y.useState(""),[Oe,ue]=y.useState([]),[v,D]=y.useState([]),[F,K]=y.useState(""),[yt,dt]=y.useState([]),[xt,Q]=y.useState(""),[at,xe]=y.useState(""),[Qa,Rl]=y.useState(""),[Xe,Yt]=y.useState(""),[Ct,ze]=y.useState([]),[Kl,le]=y.useState(""),jl=y.useRef(null),De=y.useRef(null),kt=y.useRef(null);kt.current=m;const Ve=y.useCallback(()=>{if(jl.current){try{jl.current.abort()}catch{}jl.current=null}De.current&&(clearTimeout(De.current),De.current=null)},[]),tl=y.useCallback(async U=>{try{const z=await lt(et.taskAgents(U));be(z.agents||[]),Ft(z.note||"")}catch(z){be([]),Ft("子代理链路加载失败:"+z.message)}},[]),ol=y.useCallback(U=>{De.current&&clearTimeout(De.current),De.current=setTimeout(()=>void tl(U),1e3)},[tl]),Dl=y.useCallback(async U=>{if(!U.coordinator_parts){Tt([]);return}try{const z=await lt(et.tasksByParent(U.project_id||"",U.id));Tt(z.tasks||[])}catch{Tt([])}},[]),ie=y.useCallback(async U=>{try{const z=await lt(et.taskFollowups(U));ue(z.followups||[])}catch{ue([])}},[]),Ue=y.useCallback(async U=>{var Y;const z=U||((Y=kt.current)==null?void 0:Y.id);if(z)try{const $=await lt(et.taskReviews(z));st($.reviews||[]),Lt("")}catch($){Lt("评审队列加载失败:"+$.message)}},[]),el=y.useCallback(async U=>{var Y;const z=U||((Y=kt.current)==null?void 0:Y.id);if(z)try{const $=await lt(et.taskApprovals(z));D($.approvals||[])}catch($){K("审批队列加载失败:"+$.message)}},[]),Ul=y.useCallback(async U=>{try{const z=await lt(et.taskMessages(U));dt(z.messages||[])}catch{dt([])}},[]),dl=y.useCallback(async U=>{try{const z=await lt(et.taskThread(U)),Y=z.thread||z;let $=Y.turns;$==null&&($=Y.turn_count),$==null&&($=Y.turns_count),xe("id "+(Y.id||U)+" | 名字 "+(Y.name||Y.thread_name||"")+" | 归档 "+(Y.aLine truncated
`);wt=$t.pop()||"";for(const Le of $t){const ei=Le.split(` `);Gt=$t.pop()||"";for(const Le of $t){const li=Le.split(`
`).filter(Ke=>Ke.indexOf("data: ")===0).map(Ke=>Ke.slice(6)).join(` `).filter(ke=>ke.indexOf("data: ")===0).map(ke=>ke.slice(6)).join(`
`);if(ei)try{const Ke=JSON.parse(ei);if(Ke.type==="snapshot")$=Ke.entries||[],Object.keys(Ut).forEach(He=>delete Ut[He]),$.forEach((He,li)=>{He.id&&(Ut[He.id]=li)}),ma=Ke.note||"",Dt([...$]),H(ma),ol(D);else if(Ke.type==="entry"){const He=Ke.entry;He.id&&He.id in Ut?$[Ut[He.id]]=He:(He.id&&(Ut[He.id]=$.length),$.push(He)),Dt([...$]),ol(D)}else Ke.type==="done"&&(ll=!0,Ue=Ke.status,L(Ue))}catch{}}if(ll)break}}catch(me){if(me&&me.name==="AbortError")return;H("链路流中断:"+me.message);return}ll&&r()},[Ve,ol,r]),kl=h.useCallback(async D=>{Ve();try{const z=await lt(et.task(D));o(z);let Y="";z.result_text&&(Y+=`=== result === `);if(li)try{const ke=JSON.parse(li);if(ke.type==="snapshot")$=ke.entries||[],Object.keys(Ut).forEach(Be=>delete Ut[Be]),$.forEach((Be,ai)=>{Be.id&&(Ut[Be.id]=ai)}),ha=ke.note||"",Dt([...$]),H(ha),ol(U);else if(ke.type==="entry"){const Be=ke.entry;Be.id&&Be.id in Ut?$[Ut[Be.id]]=Be:(Be.id&&(Ut[Be.id]=$.length),$.push(Be)),Dt([...$]),ol(U)}else ke.type==="done"&&(ll=!0,He=ke.status,L(He))}catch{}}if(ll)break}}catch(me){if(me&&me.name==="AbortError")return;H("链路流中断:"+me.message);return}ll&&r()},[Ve,ol,r]),Jl=y.useCallback(async U=>{Ve();try{const z=await lt(et.task(U));o(z);let Y="";z.result_text&&(Y+=`=== result ===
`+z.result_text.slice(0,8e3)+` `+z.result_text.slice(0,8e3)+`
`),z.error_text&&(Y+=`=== error === `),z.error_text&&(Y+=`=== error ===
`+z.error_text.slice(0,8e3)+` `+z.error_text.slice(0,8e3)+`
`),Y||(Y="(暂无 result/error 输出)"),O(Y),x(""),ut(!1),P(""),G(""),Yt(""),ra(z.status);const $=i(z.project_id),Ut=$==="maintainer"||$==="owner",ma=$==="contributor"||Ut,ll=nu.includes(z.status),Ue=[];["failed","interrupted","merge-failed"].includes(z.status)&&Ut||Ue.push("重试:不可用——仅 failed/interrupted/merge-failed 可重试"+(Ut?"":",且仅 maintainer 可重试")),!ll&&ma||Ue.push("取消:不可用——"+(ll?"终态任务不可取消":"仅项目成员(contributor 及以上)可取消")),z.status==="completed"&&Ut||Ue.push("合并:不可用——仅 completed 可合并"+(Ut?"":",且仅 maintainer 可合并")),z.status==="merged"&&Ut||Ue.push("提 PR:不可用——仅 merged 可提 PR"+(Ut?"":",且仅 maintainer 可提 PR")),U(Ue.join(";")),E(""),oa(D,z.status),tl(D),Dl(z),ie(D),Ul(D),dl(D),kt(D),De(D),el(D)}catch(z){o(null),O("加载失败:"+z.message)}},[Ve,oa,tl,Dl,ie,Ul,dl,kt,De,el,i]),Qa=h.useCallback(async()=>{const D=Kt.current;if(D){try{const z=await lt(et.task(D.id));o(z);let Y="";z.result_text&&(Y+=`=== result === `),Y||(Y="(暂无 result/error 输出)"),M(Y),E(""),ut(!1),P(""),Q(""),Yt(""),oa(z.status);const $=i(z.project_id),Ut=$==="maintainer"||$==="owner",ha=$==="contributor"||Ut,ll=nu.includes(z.status),He=[];["failed","interrupted","merge-failed"].includes(z.status)&&Ut||He.push("重试:不可用——仅 failed/interrupted/merge-failed 可重试"+(Ut?"":",且仅 maintainer 可重试")),!ll&&ha||He.push("取消:不可用——"+(ll?"终态任务不可取消":"仅项目成员(contributor 及以上)可取消")),z.status==="completed"&&Ut||He.push("合并:不可用——仅 completed 可合并"+(Ut?"":",且仅 maintainer 可合并")),z.status==="merged"&&Ut||He.push("提 PR:不可用——仅 merged 可提 PR"+(Ut?"":",且仅 maintainer 可提 PR")),R(He.join(";")),j(""),da(U,z.status),tl(U),Dl(z),ie(U),Ul(U),dl(U),Kt(U),Ue(U),el(U)}catch(z){o(null),M("加载失败:"+z.message)}},[Ve,da,tl,Dl,ie,Ul,dl,Kt,Ue,el,i]),Xa=y.useCallback(async()=>{const U=kt.current;if(U){try{const z=await lt(et.task(U.id));o(z);let Y="";z.result_text&&(Y+=`=== result ===
`+z.result_text.slice(0,8e3)+` `+z.result_text.slice(0,8e3)+`
`),z.error_text&&(Y+=`=== error === `),z.error_text&&(Y+=`=== error ===
`+z.error_text.slice(0,8e3)+` `+z.error_text.slice(0,8e3)+`
`),O(Y||"(暂无 result/error 输出)")}catch{}ie(D.id),De(D.id),el(D.id),Dl(D),tl(D.id),Ul(D.id),dl(D.id),kt(D.id)}},[ie,De,el,Dl,tl,Ul,dl,kt]),ae=h.useCallback(async D=>{const z=Kt.current;if(!z)return;const Y={cancel:"确定取消该任务吗?",merge:"确定把 completed 任务标为 merged 吗?",pr:"确定为该任务提 PR 吗?(会在仓库真实建 PR)"};if(!(Y[D]&&!window.confirm(Y[D])))try{const $=await lt(et.taskAction(z.id,D),"POST",{});E(D+" 已提交:"+JSON.stringify($).slice(0,300)),r(),await kl(z.id)}catch($){E(D+" 失败:"+$.message)}},[kl,r]),uu=h.useCallback(async()=>{const D=Kt.current;if(D)try{const z=await lt(et.taskCost(D.id));x(JSON.stringify(z,null,2).slice(0,4e3))}catch(z){x("查成本失败:"+z.message)}},[]),mn=h.useCallback(async D=>{const z=Kt.current;if(z){if(!D.trim()){P("分支消息必填");return}if(!nu.includes(z.status)){P("仅终态任务可分支");return}try{const Y=await lt(et.taskFork(z.id),"POST",{message:D.trim()});P("分支任务已建:"+Y.id.slice(0,8)),r()}catch(Y){P("分支失败:"+Y.message)}}},[r]),vn=h.useCallback(async D=>{const z=Kt.current;if(z)try{await lt(et.taskReviews(z.id),"POST",D),Wt("评审已登记(requested)"),await De(z.id)}catch(Y){Wt("登记评审需求失败:"+Y.message)}},[De]),Ze=h.useCallback(D=>{const z=Kt.current;if(!z)return;const Y=window.prompt("输入该条评审的 findings(将写回记录并标为 completed):");Y!==null&&lt(et.taskReviewFindings(z.id,D),"POST",{findings:Y}).then(()=>void De(z.id)).catch($=>Wt("写 findings 失败:"+$.message))},[De]),Xa=h.useCallback((D,z)=>{const Y=Kt.current;if(!Y)return;const $=z==="approved"?"approve":"deny";lt(et.taskApprovalDecision(Y.id,D,$),"POST",{}).then(()=>{k("已记录"+(z==="approved"?"允许":"拒绝")+"(当前版本只留回执,不拦截实时行为)"),el(Y.id)}).catch(Ut=>k("决定失败:"+Ut.message))},[el]),da=h.useCallback(async(D,z,Y)=>{const $=Kt.current;if($){if(!z.trim()){G("目标任务 id 不能为空");return}if(!Y.trim()){G("消息正文不能为空");return}try{const Ut=await lt(et.taskMessagesTo(z.trim()),"POST",{from_task_id:$.id,body:Y.trim(),mode:D});G("已发送("+Ut.delivery+")"),await Ul($.id)}catch(Ut){G("发送失败:"+Ut.message)}}},[Ul]),iu=h.useCallback((D,z)=>{const Y=Kt.current;if(!Y)return;if(!["completed","failed","interrupted"].includes(Y.status)){Yt("仅 completed/failed/interrupted 任务可操作线程(merged/merge-failed 不可改,服务端同样 409)");return}const $={};if(D==="rename"){if(!z.trim()){Yt("新线程名不能为空");return}$.name=z.trim()}lt(et.taskThreadAction(Y.id,D),"POST",$).then(Ut=>{Yt(D+" 已提交:"+JSON.stringify(Ut).slice(0,300)),dl(Y.id),kt(Y.id)}).catch(Ut=>Yt(D+" 失败:"+Ut.message))},[dl,kt]),cu=h.useCallback(async D=>{const z=Kt.current;if(!z)return;const Y=D.trim();if(!Y){le("消息不能为空");return}try{nu.includes(z.status)&&z.status!=="merged"?(await lt(et.taskContinue(z.id),"POST",{message:Y}),le("已重新排队,同一会话继续"),r(),await kl(z.id)):["queued","running"].includes(z.status)?(await lt(et.taskFollowups(z.id),"POST",{body:Y,mode:"direct"}),le("已直接发送"),await ie(z.id)):le("merged/merge-failed 任务不可继续,也不可发后续消息")}catch($){le("发送失败:"+$.message)}},[kl,r,ie]),Jl=h.useCallback(async()=>{const D=Kt.current;if(!D){ee("先选一个任务");return}try{const z=await lt(et.taskTrace(D.id)),Y=new Blob([JSON.stringify({task_id:D.id,status:z.status,note:z.note||"",count:(z.entries||[]).length,entries:z.entries||[]},null,2)],{type:"application/json"}),$=document.createElement("a");$.href=URL.createObjectURL(Y),$.download="trace-"+D.id.slice(0,8)+".json",document.body.appendChild($),$.click(),$.remove(),setTimeout(()=>URL.revokeObjectURL($.href),1e3),ee("已下载完整链路 "+(z.entries||[]).length+" 条")}catch(z){ee("下载失败:"+z.message)}},[]);return h.useEffect(()=>()=>Ve(),[Ve]),{currentTask:g,detailBody:_,actionMsg:A,actionReasons:Z,costBox:w,forkVisible:J,setForkVisible:ut,forkMsg:K,coordChildren:it,agents:Vt,agentsNote:Ce,reviews:oe,reviewMsg:vt,reviewError:te,traceEntries:de,traceNote:Pe,traceDone:q,traceKind:tt,setTraceKind:xt,traceMsg:ht,followups:Oe,approvals:v,approvalMsg:F,peerMessages:yt,peerMsg:Tt,threadText:at,threadGateNote:Ga,threadMsg:Xe,threadList:At,chatMsg:Kl,showDetail:kl,refreshDetailLists:Qa,doAction:ae,taskCost:uu,forkTask:mn,postReview:vn,submitFindings:Ze,decideApproval:Xa,postPeer:da,threadAction:iu,sendChatMessage:cu,downloadTrace:Jl,refreshReviews:()=>void De(),refreshApprovals:()=>void el()}}function Fy(i){const[r,g]=h.useState([]),[o,_]=h.useState(""),[O,A]=h.useState(null),[E,Z]=h.useState(""),U=h.useCallback(async ut=>{const K=ut!==void 0?ut:i();if(!K){g([]);return}try{const P=await lt(et.projectAutomations(K));g(P.automations||[])}catch(P){_("自动化加载失败:"+P.message)}},[i]),w=h.useCallback(async(ut,K,P,it)=>{const jt=i();if(!jt){_("先选项目"Line truncated `),M(Y||"(暂无 result/error 输出)")}catch{}ie(U.id),Ue(U.id),el(U.id),Dl(U),tl(U.id),Ul(U.id),dl(U.id),Kt(U.id)}},[ie,Ue,el,Dl,tl,Ul,dl,Kt]),ae=y.useCallback(async U=>{const z=kt.current;if(!z)return;const Y={cancel:"确定取消该任务吗?",merge:"确定把 completed 任务标为 merged 吗?",pr:"确定为该任务提 PR 吗?(会在仓库真实建 PR)"};if(!(Y[U]&&!window.confirm(Y[U])))try{const $=await lt(et.taskAction(z.id,U),"POST",{});j(U+" 已提交:"+JSON.stringify($).slice(0,300)),r(),await Jl(z.id)}catch($){j(U+" 失败:"+$.message)}},[Jl,r]),iu=y.useCallback(async()=>{const U=kt.current;if(U)try{const z=await lt(et.taskCost(U.id));E(JSON.stringify(z,null,2).slice(0,4e3))}catch(z){E("查成本失败:"+z.message)}},[]),mn=y.useCallback(async U=>{const z=kt.current;if(z){if(!U.trim()){P("分支消息必填");return}if(!nu.includes(z.status)){P("仅终态任务可分支");return}try{const Y=await lt(et.taskFork(z.id),"POST",{message:U.trim()});P("分支任务已建:"+Y.id.slice(0,8)),r()}catch(Y){P("分支失败:"+Y.message)}}},[r]),hn=y.useCallback(async U=>{const z=kt.current;if(z)try{await lt(et.taskReviews(z.id),"POST",U),Wt("评审已登记(requested)"),await Ue(z.id)}catch(Y){Wt("登记评审需求失败:"+Y.message)}},[Ue]),Ze=y.useCallback(U=>{const z=kt.current;if(!z)return;const Y=window.prompt("输入该条评审的 findings(将写回记录并标为 completed):");Y!==null&&lt(et.taskReviewFindings(z.id,U),"POST",{findings:Y}).then(()=>void Ue(z.id)).catch($=>Wt("写 findings 失败:"+$.message))},[Ue]),Va=y.useCallback((U,z)=>{const Y=kt.current;if(!Y)return;const $=z==="approved"?"approve":"deny";lt(et.taskApprovalDecision(Y.id,U,$),"POST",{}).then(()=>{K("已记录"+(z==="approved"?"允许":"拒绝")+"(当前版本只留回执,不拦截实时行为)"),el(Y.id)}).catch(Ut=>K("决定失败:"+Ut.message))},[el]),ma=y.useCallback(async(U,z,Y)=>{const $=kt.current;if($){if(!z.trim()){Q("目标任务 id 不能为空");return}if(!Y.trim()){Q("消息正文不能为空");return}try{const Ut=await lt(et.taskMessagesTo(z.trim()),"POST",{from_task_id:$.id,body:Y.trim(),mode:U});Q("已发送("+Ut.delivery+")"),await Ul($.id)}catch(Ut){Q("发送失败:"+Ut.message)}}},[Ul]),cu=y.useCallback((U,z)=>{const Y=kt.current;if(!Y)return;if(!["completed","failed","interrupted"].includes(Y.status)){Yt("仅 completed/failed/interrupted 任务可操作线程(merged/merge-failed 不可改,服务端同样 409)");return}const $={};if(U==="rename"){if(!z.trim()){Yt("新线程名不能为空");return}$.name=z.trim()}lt(et.taskThreadAction(Y.id,U),"POST",$).then(Ut=>{Yt(U+" 已提交:"+JSON.stringify(Ut).slice(0,300)),dl(Y.id),Kt(Y.id)}).catch(Ut=>Yt(U+" 失败:"+Ut.message))},[dl,Kt]),su=y.useCallback(async U=>{const z=kt.current;if(!z)return;const Y=U.trim();if(!Y){le("消息不能为空");return}try{nu.includes(z.status)&&z.status!=="merged"?(await lt(et.taskContinue(z.id),"POST",{message:Y}),le("已重新排队,同一会话继续"),r(),await Jl(z.id)):["queued","running"].includes(z.status)?(await lt(et.taskFollowups(z.id),"POST",{body:Y,mode:"direct"}),le("已直接发送"),await ie(z.id)):le("merged/merge-failed 任务不可继续,也不可发后续消息")}catch($){le("发送失败:"+$.message)}},[Jl,r,ie]),Fl=y.useCallback(async()=>{const U=kt.current;if(!U){ee("先选一个任务");return}try{const z=await lt(et.taskTrace(U.id)),Y=new Blob([JSON.stringify({task_id:U.id,status:z.status,note:z.note||"",count:(z.entries||[]).length,entries:z.entries||[]},null,2)],{type:"application/json"}),$=document.createElement("a");$.href=URL.createObjectURL(Y),$.download="trace-"+U.id.slice(0,8)+".json",document.body.appendChild($),$.click(),$.remove(),setTimeout(()=>URL.revokeObjectURL($.href),1e3),ee("已下载完整链路 "+(z.entries||[]).length+" 条")}catch(z){ee("下载失败:"+z.message)}},[]);return y.useEffect(()=>()=>Ve(),[Ve]),{currentTask:m,detailBody:_,actionMsg:N,actionReasons:B,costBox:G,forkVisible:J,setForkVisible:ut,forkMsg:k,coordChildren:it,agents:Vt,agentsNote:Me,reviews:oe,reviewMsg:ht,reviewError:te,traceEntries:de,traceNote:Pe,traceDone:w,traceKind:tt,setTraceKind:jt,traceMsg:vt,followups:Oe,approvals:v,approvalMsg:F,peerMessages:yt,peerMsg:xt,threadText:at,threadGateNote:Qa,threadMsg:Xe,threadList:Ct,chatMsg:Kl,showDetail:Jl,refreshDetailLists:Xa,doAction:ae,taskCost:iu,forkTask:mn,postReview:hn,submitFindings:Ze,decideApproval:Va,postPeer:ma,threadAction:cu,sendChatMessage:su,downloadTrace:Fl,refreshReviews:()=>void Ue(),refreshApprovals:()=>void el()}}function $y(i){const[r,m]=y.useState([]),[o,_]=y.useState(""),[M,N]=y.useState(null),[j,B]=y.useState(""),R=y.useCallback(async ut=>{const k=ut!==void 0?ut:i();if(!k){m([]);return}try{const P=await lt(et.projectAutomations(k));m(P.automations||[])}catch(P){_("自动化加载失败:"+P.message)}},[i]),G=y.useCallback(async(ut,k,P,it)=>{const Tt=i();if(!Tt){_("先选项目"Line truncated
<style rel="stylesheet" crossorigin>:root{--ink:#1c2220;--ink-soft:#4a554f;--paper:#f5f3ee;--card:#ffffff;--line:#e6e1d6;--line-strong:#d3ccbc;--seal:#be2a1e;--seal-soft:#fdeeeb;--seal-dark:#9c2118;--pine:#14544a;--pine-soft:#e2efea;--amber:#92400e;--amber-soft:#fef3c7;--success:#15803d;--danger:#b42318;--danger-soft:#fef3f2;--purple:#6941c6;--radius:16px;--radius-sm:10px;--shadow:0 1px 2px rgba(28,34,32,.05), 0 12px 32px rgba(28,34,32,.06);--serif:"Songti SC","Noto Serif SC","SimSun",serif;--sans:-apple-system,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;--mono:"IBM Plex Mono",Menlo,Consolas,monospace;--ctl:40px}*{box-sizing:border-box}body{font-family:var(--sans);margin:0;color:var(--ink);background:var(--paper);line-height:1.6;font-size:15px}a{color:var(--pine);text-underline-offset:3px}:focus-visible{outline:3px solid var(--seal);outline-offset:2px}@media(prefers-reduced-motion:reduce){*{scroll-behavior:auto!important;transition:none!important}}.muted{color:#7a857e;font-size:13px;line-height:1.6}.err{color:var(--danger)}.ok{color:var(--success)}.site-header{position:sticky;top:0;z-index:30;background:#fff}.topbar{display:flex;align-items:center;gap:16px;padding:16px 28px;background:#fff;border-bottom:1px solid var(--line)}.seal-mark{flex:none;width:38px;height:38px;background:var(--seal);color:#fff;display:grid;place-items:center;font-family:var(--serif);font-size:20px;font-weight:700;border-radius:8px}.topbar h1{font-family:var(--serif);font-size:25px;line-height:1.15;margin:0;font-weight:700;letter-spacing:1px}.topbar .subtitle{font-size:13px;color:#7a857e;margin:1px 0 0;letter-spacing:2px}.version{font-size:12px;color:#7a857e;border:1px solid var(--line);background:#fff;border-radius:999px;padding:6px 11px;white-space:nowrap}.topnav{display:flex;gap:4px;flex-wrap:wrap;align-items:center;padding:8px 28px;background:#fff;border-bottom:1px solid var(--line);overflow-x:auto;scroll-margin-top:0}.topnav a{color:var(--ink-soft);text-decoration:none;font-size:13.5px;font-weight:600;padding:6px 10px;border-radius:999px;white-space:nowrap}.topnav a:hover{color:var(--ink);background:var(--pine-soft)}.topnav a.active{color:var(--ink);font-weight:700}.topnav .auto-refresh{margin-left:auto;color:#7a857e;font-size:12px;white-space:nowrap}section[id],div[id]{scroll-margin-top:130px}.shell{display:grid;grid-template-columns:300px minmax(0,1fr) 340px;gap:20px;align-items:start;padding:24px 28px 48px}.rail{display:flex;flex-direction:column;gap:20px;min-width:0}.center-col{min-width:0}.center-inner{max-width:800px;margin:0 auto;width:100%;display:flex;flex-direction:column;gap:20px}.detail-col{display:flex;flex-direction:column;gap:20px;min-width:0}.left-nav{display:flex;flex-direction:column;gap:8px}.left-nav button{text-align:left;border-radius:12px;background:#fff}.left-nav button.active{background:var(--ink);color:#fff;border-color:var(--ink)}.left-tasks input[type=text]{width:100%}.selected-task{border-color:var(--seal)!important;background:var(--seal-soft)!important}.conversation{display:flex;flex-direction:column;gap:20px}.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow);padding:24px}.card h2{font-family:var(--serif);font-size:18px;margin:0 0 12px;letter-spacing:.5px}.card h3{font-family:var(--serif);font-size:15px;margin:24px 0 12px;padding-top:20px;border-top:1px solid var(--line)}.card h3:first-of-type{border-top:0;padding-top:0}.composer h2{font-size:22px}.composer textarea#prompt,.composer textarea.prompt{min-height:148px;font-size:16px;padding:16px 18px;border-radius:12px}.composer textarea.coord{font-family:var(--mono);font-size:13px}.bar{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin:12px 0}.bar>button,.bar>label{display:inline-flex;align-items:center;height:var(--ctl);min-height:var(--ctl);padding:0 16px;box-sizing:border-box;white-space:nowrap}.bar>input,.bar>select{height:var(--ctl);min-height:var(--ctl)}input,select,textarea,button{font:inherit;font-size:14px;padding:10px 13px;border-radius:var(--radius-sm);border:1px solid var(--line-strong);background:#fff;color:var(--ink)}input:focus,select:focus,textarea:focus{outline:none;border-color:var(--ink);box-shadow:0 0 0 3px #1c222014}button{cursor:pointer;font-weight:600;border-radius:999px;padding:9px 16px}button:hover{box-shadow:0 4px 14px #1c22201a}button:disabled{opacity:.45;cursor:not-allowed;box-shadow:none}button.primary{background:var(--ink);border-color:var(--ink);color:#fff}button.primary:hover{background:#000}button.seal{background:var(--seal);border-color:var(--seal);color:#fff}button.seal:hover{background:var(--seal-dark)}button.danger{color:var(--danger);border-color:#fecdca;background:var(--danger-soft)}button.danger:hover{background:#fee4e2}select{-moz-appearance:none;appearance:none;-webkit-appearance:none;cursor:pointer;padding-right:34px;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height=Line truncated <style rel="stylesheet" crossorigin>:root{--text:#1d2129;--muted:#667085;--line:#e4e7ec;--line-strong:#d0d5dd;--paper:#ffffff;--card:#ffffff;--bubble-assistant:#f2f2f2;--bubble-user:#bfe0ff;--accent:#3b82f6;--accent-dark:#2563eb;--accent-soft:#eef4ff;--green:#22c55e;--success:#16a34a;--danger:#b42318;--danger-soft:#fef3f2;--amber:#b54708;--purple:#6941c6;--radius:12px;--radius-sm:10px;--shadow:none;--sans:-apple-system,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;--mono:"IBM Plex Mono",Menlo,Consolas,monospace;--ctl:40px}*{box-sizing:border-box}html,body,#root{height:100%}body{font-family:var(--sans);margin:0;color:var(--text);background:#fff;line-height:1.6;font-size:14px}a{color:var(--accent);text-underline-offset:3px}:focus-visible{outline:3px solid var(--accent);outline-offset:2px}@media(prefers-reduced-motion:reduce){*{scroll-behavior:auto!important;transition:none!important}}.muted{color:var(--muted);font-size:13px;line-height:1.6}.err{color:var(--danger)}.ok{color:var(--success)}button{cursor:pointer;font-weight:600;border-radius:999px}button:disabled{opacity:.45;cursor:not-allowed;box-shadow:none}button.primary{background:var(--accent);border-color:var(--accent);color:#fff}button.primary:hover{background:var(--accent-dark)}button.seal{background:var(--accent);border-color:var(--accent);color:#fff}button.seal:hover{background:var(--accent-dark)}button.danger{color:var(--danger);border-color:#fecdca;background:var(--danger-soft)}button.danger:hover{background:#fee4e2}.icon-btn{width:32px;height:32px;padding:0;display:grid;place-items:center;border:1px solid var(--line);border-radius:50%;background:#fff;color:var(--text);font-size:16px;line-height:1}.icon-btn:hover{background:#f9fafb}.muse-app{display:grid;grid-template-columns:56px 260px minmax(0,1fr) 300px;height:100vh;background:#fff}.muse-app.no-right{grid-template-columns:56px 260px minmax(0,1fr)}.icon-rail{border-right:1px solid var(--line);display:flex;flex-direction:column;align-items:center;gap:4px;padding:12px 0;overflow-y:auto}.icon-rail button{width:40px;height:40px;border:0;border-radius:12px;background:transparent;display:grid;place-items:center;color:var(--text);padding:0;flex:none}.icon-rail button:hover{background:#f2f2f2}.icon-rail button.active{background:var(--accent-soft);color:var(--accent)}.icon-rail svg{width:22px;height:22px}.list-col{border-right:1px solid var(--line);overflow-y:auto;padding:16px 12px;min-width:0}.search-box{display:flex;align-items:center;gap:8px;border:1px solid var(--line);border-radius:999px;padding:8px 12px;background:#fff}.search-box svg{flex:none;color:var(--muted)}.search-box input{border:0;padding:0;flex:1;min-width:0;font-size:14px;background:transparent}.search-box input:focus{box-shadow:none;outline:none}.list-section-head{display:flex;align-items:center;justify-content:space-between;padding:16px 4px 8px;font-weight:600;font-size:14px}.list-section-head button{width:28px;height:28px;padding:0;display:grid;place-items:center;border-radius:50%}.muse-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}.muse-item{padding:10px 12px;border-radius:12px;cursor:pointer;overflow:hidden}.muse-item:hover{background:#f9fafb}.muse-item.selected{background:#f2f2f2}.muse-item-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:14px}.muse-item-sub{display:flex;gap:6px;align-items:center;color:var(--muted);font-size:12px;margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.task-dot{width:8px;height:8px;border-radius:50%;background:currentColor;flex:none}.center-col{min-width:0;display:flex;flex-direction:column;overflow-y:auto;background:#fff}.center-topbar{position:sticky;top:0;z-index:5;display:flex;align-items:center;justify-content:space-between;padding:12px 16px;background:#fff;border-bottom:1px solid var(--line)}.center-inner{max-width:760px;margin:0 auto;width:100%;padding:24px 20px 16px;display:flex;flex-direction:column;gap:20px;flex:1}.right-col{border-left:1px solid var(--line);overflow-y:auto;padding:20px 16px;display:flex;flex-direction:column;gap:20px;min-width:0}.right-profile{text-align:center;position:relative}.right-profile .icon-btn{position:absolute;top:0;right:0}.right-avatar{width:72px;height:72px;border-radius:50%;background:var(--accent-soft);color:var(--accent);display:grid;place-items:center;font-size:28px;font-weight:700;margin:0 auto}.right-name{font-weight:700;font-size:17px;margin-top:10px}.right-status{color:var(--green);font-size:13px;font-weight:600}.right-status.off{color:var(--muted)}.right-icon-row{display:flex;gap:4px;justify-content:space-between;border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding:10px 4px}.right-icon-row button{width:36px;height:36px;border:0;border-radius:12px;background:transparent;display:grid;place-items:center;color:var(--text);padding:0}.right-icon-row button:hover{background:#f2f2f2}.right-icon-row button.active{background:var(--accent-sLine truncated
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>