c6e66baa19
- web/: phosphor 调度台风格纯静态看板,审批闸内联 accept/reject(拒绝必填意见),WS 实时 - src/api/static.ts: 手写静态服务(路径穿越防护),daemon 接入 - src/mcp/: stdio MCP server,@modelcontextprotocol/sdk 1.29.0,12 工具薄封装 REST - src/cli/: 零依赖 CLI(project/task/next/approvals/import-todo),旧 todo.json 导入器 - 实测: pangolin 18 条旧任务导入 45 条;端到端验证通过 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
123 lines
4.7 KiB
HTML
123 lines
4.7 KiB
HTML
<!doctype html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>MAESTRO · 任务调度台</title>
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600;700&family=Noto+Sans+SC:wght@400;500;700&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="style.css">
|
|
</head>
|
|
<body>
|
|
<div id="app">
|
|
|
|
<!-- ════════ 左栏:项目 ════════ -->
|
|
<aside id="sidebar">
|
|
<div class="logo">
|
|
<div class="logo-word">MAESTRO<span class="cursor">▮</span></div>
|
|
<div class="logo-sub">多项目任务调度台</div>
|
|
</div>
|
|
|
|
<div class="side-head">
|
|
<span class="head-mark">▍</span>项目
|
|
<button class="btn btn-ghost btn-xs" data-action="open-new-project">+ 新建</button>
|
|
</div>
|
|
<ul id="projectList" class="project-list"></ul>
|
|
|
|
<div class="side-foot">
|
|
<span id="wsDot" class="ws-dot off"></span>
|
|
<span id="wsText">连接中…</span>
|
|
</div>
|
|
</aside>
|
|
|
|
<!-- ════════ 中栏:闸 + 任务树 ════════ -->
|
|
<main id="main">
|
|
<header id="topbar">
|
|
<div>
|
|
<div id="projTitle" class="proj-title">—</div>
|
|
<div id="projMeta" class="proj-meta"></div>
|
|
</div>
|
|
<div class="spacer"></div>
|
|
<div id="gateCount" class="gate-count" hidden></div>
|
|
</header>
|
|
|
|
<section id="gateSection" class="gate-section" hidden>
|
|
<div class="gate-stripe"></div>
|
|
<div class="sec-head gate-head"><span class="head-mark amber">▍</span>审批闸 · 等待裁决</div>
|
|
<div id="gateList"></div>
|
|
</section>
|
|
|
|
<section id="taskSection">
|
|
<div class="sec-head">
|
|
<span class="head-mark">▍</span>任务树
|
|
<button class="btn btn-ghost btn-xs" data-action="toggle-new-task">+ 新建任务</button>
|
|
</div>
|
|
|
|
<form id="newTaskPanel" class="panel form-panel" hidden>
|
|
<div class="form-row">
|
|
<label class="grow">标题 <span class="req">*</span>
|
|
<input name="title" type="text" placeholder="要做什么" autocomplete="off">
|
|
</label>
|
|
</div>
|
|
<div class="form-row">
|
|
<label>复杂度 <span class="req">*</span>
|
|
<span class="seg" id="cplxSeg">
|
|
<input type="radio" name="complexity" value="hard" id="cx-h"><label for="cx-h" class="seg-h">HARD</label>
|
|
<input type="radio" name="complexity" value="medium" id="cx-m" checked><label for="cx-m" class="seg-m">MEDIUM</label>
|
|
<input type="radio" name="complexity" value="easy" id="cx-e"><label for="cx-e" class="seg-e">EASY</label>
|
|
</span>
|
|
</label>
|
|
<label>父任务
|
|
<select name="parentId"><option value="">(顶层)</option></select>
|
|
</label>
|
|
<label class="narrow">优先级
|
|
<input name="priority" type="number" value="0" step="1">
|
|
</label>
|
|
</div>
|
|
<div class="form-row form-actions">
|
|
<button type="submit" class="btn btn-solid">创建任务</button>
|
|
<button type="button" class="btn" data-action="toggle-new-task">取消</button>
|
|
</div>
|
|
</form>
|
|
|
|
<div id="taskTree"></div>
|
|
</section>
|
|
</main>
|
|
|
|
<!-- ════════ 右栏:事件流 ════════ -->
|
|
<aside id="eventPanel">
|
|
<div class="sec-head"><span class="head-mark">▍</span>事件流</div>
|
|
<ul id="eventList" class="event-list"></ul>
|
|
</aside>
|
|
</div>
|
|
|
|
<!-- 新建项目 模态 -->
|
|
<div id="modalRoot" class="modal-root" hidden>
|
|
<div class="modal-mask" data-action="close-modal"></div>
|
|
<form id="newProjectForm" class="modal panel">
|
|
<div class="sec-head"><span class="head-mark">▍</span>新建项目</div>
|
|
<label>名称 <span class="req">*</span>
|
|
<input name="name" type="text" placeholder="my-project" autocomplete="off">
|
|
</label>
|
|
<label>仓库路径 <span class="req">*</span>
|
|
<input name="repoPath" type="text" placeholder="/path/to/repo" autocomplete="off">
|
|
</label>
|
|
<label>默认分支
|
|
<input name="defaultBranch" type="text" placeholder="main">
|
|
</label>
|
|
<label>校验命令
|
|
<input name="verifyCmd" type="text" placeholder="npm test(可空)">
|
|
</label>
|
|
<div class="form-row form-actions">
|
|
<button type="submit" class="btn btn-solid">创建</button>
|
|
<button type="button" class="btn" data-action="close-modal">取消</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<div id="toastRoot" class="toast-root"></div>
|
|
<script src="app.js"></script>
|
|
</body>
|
|
</html>
|