1fcd811c12
8 章设计文档 HTML(架构决策/状态设计/DB Schema/记忆注入/Agent 规格/ 运维护栏/安全沙箱/前端 API 契约),全图深色内联 SVG,附 docs/index.html 索引。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
441 lines
23 KiB
HTML
441 lines
23 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN" data-theme="dark">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>MAESTRO · 架构设计</title>
|
||
<style>
|
||
:root {
|
||
--bg: #0a0d0b;
|
||
--bg-deep: #070908;
|
||
--panel: #111610;
|
||
--panel-2: #161c13;
|
||
--line: #1e2a1c;
|
||
--ink: #c8d4c0;
|
||
--muted: #7a9070;
|
||
--faint: #445040;
|
||
--green: #4ade80;
|
||
--green-dim: rgba(74,222,128,.12);
|
||
--violet: #a78bfa;
|
||
--violet-dim: rgba(167,139,250,.1);
|
||
--amber: #fbbf24;
|
||
--amber-dim: rgba(251,191,36,.1);
|
||
--red: #f87171;
|
||
--red-dim: rgba(248,113,113,.1);
|
||
--cyan: #22d3ee;
|
||
--cyan-dim: rgba(34,211,238,.1);
|
||
--mono: 'IBM Plex Mono', 'Noto Sans SC', monospace;
|
||
--radius-sm: 4px;
|
||
--radius-md: 6px;
|
||
}
|
||
[data-theme="light"] {
|
||
--bg: #f4f6f2; --bg-deep: #eaede7; --panel: #ffffff; --panel-2: #f0f2ee;
|
||
--line: #d0d8cc; --ink: #1a2418; --muted: #4a6045; --faint: #8a9e86;
|
||
--green: #16a34a; --green-dim: rgba(22,163,74,.1);
|
||
--violet: #7c3aed; --violet-dim: rgba(124,58,237,.1);
|
||
--amber: #d97706; --amber-dim: rgba(217,119,6,.1);
|
||
--red: #dc2626; --red-dim: rgba(220,38,38,.1);
|
||
--cyan: #0891b2; --cyan-dim: rgba(8,145,178,.1);
|
||
}
|
||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||
html, body { height: 100%; }
|
||
body {
|
||
background: var(--bg); color: var(--ink);
|
||
font-family: var(--mono); font-size: 13px; line-height: 1.6;
|
||
padding: 32px;
|
||
}
|
||
body::before {
|
||
content: ''; position: fixed; inset: 0; z-index: 0; pointer-events: none;
|
||
background:
|
||
repeating-linear-gradient(0deg, rgba(0,0,0,.14) 0 1px, transparent 1px 3px),
|
||
radial-gradient(ellipse at 50% 40%, transparent 55%, rgba(0,0,0,.45));
|
||
opacity: .45;
|
||
}
|
||
[data-theme="light"] body::before { opacity: .07; }
|
||
.page { position: relative; z-index: 1; max-width: 1200px; margin: 0 auto; }
|
||
|
||
.header {
|
||
display: flex; align-items: baseline; gap: 16px;
|
||
border-bottom: 1px solid var(--line); padding-bottom: 20px; margin-bottom: 32px;
|
||
}
|
||
.logo { font-size: 18px; font-weight: 700; letter-spacing: .25em; color: var(--green); text-shadow: 0 0 16px var(--green); }
|
||
.logo span { animation: blink 1.1s steps(1) infinite; }
|
||
@keyframes blink { 50% { opacity: 0; } }
|
||
.subtitle { color: var(--muted); font-size: 11px; letter-spacing: .2em; }
|
||
.theme-btn {
|
||
margin-left: auto; background: var(--panel); border: 1px solid var(--line);
|
||
color: var(--muted); font-family: var(--mono); font-size: 11px;
|
||
padding: 4px 10px; border-radius: var(--radius-sm); cursor: pointer; letter-spacing: .1em;
|
||
}
|
||
.theme-btn:hover { color: var(--ink); border-color: var(--muted); }
|
||
|
||
.sec-head {
|
||
display: flex; align-items: center; gap: 8px;
|
||
font-size: 10px; font-weight: 600; letter-spacing: .28em;
|
||
color: var(--muted); text-transform: uppercase;
|
||
margin-bottom: 16px; margin-top: 40px;
|
||
}
|
||
.sec-mark { width: 3px; height: 14px; border-radius: 2px; }
|
||
|
||
/* Architecture grid */
|
||
.arch { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; margin-bottom: 12px; }
|
||
.layer {
|
||
border: 1px solid var(--line); border-radius: var(--radius-md);
|
||
background: var(--panel); padding: 16px;
|
||
}
|
||
.layer-title {
|
||
font-size: 10px; font-weight: 600; letter-spacing: .18em;
|
||
text-transform: uppercase; margin-bottom: 12px;
|
||
display: flex; align-items: center; gap: 8px;
|
||
}
|
||
.dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
|
||
.span-2 { grid-column: span 2; }
|
||
.span-3 { grid-column: span 3; }
|
||
|
||
.layer-frontend { border-color: rgba(34,211,238,.4); background: linear-gradient(135deg, var(--panel), rgba(34,211,238,.03)); }
|
||
.layer-frontend .layer-title { color: var(--cyan); }
|
||
.layer-api { border-color: rgba(167,139,250,.4); background: linear-gradient(135deg, var(--panel), rgba(167,139,250,.03)); }
|
||
.layer-api .layer-title { color: var(--violet); }
|
||
.layer-db { border-color: rgba(251,191,36,.4); background: linear-gradient(135deg, var(--panel), rgba(251,191,36,.03)); }
|
||
.layer-db .layer-title { color: var(--amber); }
|
||
.layer-daemon { border-color: rgba(74,222,128,.4); background: linear-gradient(135deg, var(--panel), rgba(74,222,128,.03)); }
|
||
.layer-daemon .layer-title { color: var(--green); }
|
||
.layer-worker { border-color: rgba(248,113,113,.4); background: linear-gradient(135deg, var(--panel), rgba(248,113,113,.03)); }
|
||
.layer-worker .layer-title { color: var(--red); }
|
||
|
||
.modules { display: flex; flex-wrap: wrap; gap: 6px; }
|
||
.mod {
|
||
font-size: 11px; padding: 4px 8px; border-radius: var(--radius-sm);
|
||
border: 1px solid var(--line); background: var(--panel-2); color: var(--muted); line-height: 1.5;
|
||
}
|
||
.mod b { color: var(--ink); font-weight: 600; display: block; }
|
||
.mod small { font-size: 10px; color: var(--faint); }
|
||
.mod-c { border-color: rgba(34,211,238,.35); background: var(--cyan-dim); color: var(--cyan); }
|
||
.mod-v { border-color: rgba(167,139,250,.35); background: var(--violet-dim); color: var(--violet); }
|
||
.mod-a { border-color: rgba(251,191,36,.35); background: var(--amber-dim); color: var(--amber); }
|
||
.mod-g { border-color: rgba(74,222,128,.35); background: var(--green-dim); color: var(--green); }
|
||
.mod-r { border-color: rgba(248,113,113,.35); background: var(--red-dim); color: var(--red); }
|
||
|
||
.connector {
|
||
grid-column: span 3; display: flex; justify-content: space-around;
|
||
padding: 6px 0; color: var(--faint); font-size: 10px; letter-spacing: .12em;
|
||
align-items: center;
|
||
}
|
||
.conn-item { display: flex; flex-direction: column; align-items: center; gap: 3px; }
|
||
.conn-line { width: 1px; height: 16px; background: var(--line); }
|
||
|
||
/* Flow */
|
||
.flow {
|
||
display: grid; grid-template-columns: repeat(5, 1fr);
|
||
border: 1px solid var(--line); border-radius: var(--radius-md); overflow: hidden;
|
||
margin-bottom: 40px;
|
||
}
|
||
.flow-step {
|
||
padding: 14px 14px; border-right: 1px solid var(--line); position: relative;
|
||
}
|
||
.flow-step:last-child { border-right: none; }
|
||
.flow-num { font-size: 10px; color: var(--faint); letter-spacing: .15em; margin-bottom: 4px; }
|
||
.flow-title { font-size: 12px; font-weight: 600; color: var(--ink); margin-bottom: 4px; }
|
||
.flow-desc { font-size: 11px; color: var(--muted); line-height: 1.5; }
|
||
.flow-arr {
|
||
position: absolute; right: -9px; top: 50%; transform: translateY(-50%);
|
||
color: var(--faint); font-size: 16px; z-index: 2; background: var(--panel); padding: 2px 1px;
|
||
}
|
||
|
||
/* Detail grid */
|
||
.detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 40px; }
|
||
.detail-card {
|
||
border: 1px solid var(--line); border-radius: var(--radius-md);
|
||
background: var(--panel); padding: 16px;
|
||
}
|
||
.detail-card h3 { font-size: 11px; font-weight: 600; letter-spacing: .18em; text-transform: uppercase; margin-bottom: 10px; }
|
||
.detail-card ul { list-style: none; display: flex; flex-direction: column; gap: 6px; }
|
||
.detail-card li { font-size: 11px; color: var(--muted); display: flex; gap: 8px; align-items: flex-start; }
|
||
.detail-card li::before { content: '→'; color: var(--faint); flex-shrink: 0; margin-top: 1px; }
|
||
.detail-card li b { color: var(--ink); }
|
||
.note { font-size: 10px; color: var(--faint); display: block; margin-top: 1px; }
|
||
|
||
/* File tree */
|
||
.file-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 40px; }
|
||
.file-tree {
|
||
background: var(--bg-deep); border: 1px solid var(--line);
|
||
border-radius: var(--radius-md); padding: 20px;
|
||
font-size: 12px; line-height: 2; margin-bottom: 40px;
|
||
}
|
||
.ft-dir { color: var(--cyan); font-weight: 600; }
|
||
.ft-file { color: var(--muted); }
|
||
.ft-new { color: var(--green); }
|
||
.ft-del { color: var(--red); text-decoration: line-through; opacity: .55; }
|
||
.ft-c { color: var(--faint); font-size: 10px; }
|
||
.i1 { padding-left: 16px; }
|
||
.i2 { padding-left: 32px; }
|
||
.i3 { padding-left: 48px; }
|
||
</style>
|
||
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||
</head>
|
||
<body>
|
||
<div class="page">
|
||
|
||
<div class="header">
|
||
<div class="logo">MAESTRO<span>▮</span></div>
|
||
<div class="subtitle">架构设计 · ARCHITECTURE DESIGN v2.0 DRAFT</div>
|
||
<button class="theme-btn" onclick="document.documentElement.dataset.theme=document.documentElement.dataset.theme==='dark'?'light':'dark'">⊙ 切换主题</button>
|
||
</div>
|
||
|
||
<!-- 全景架构 -->
|
||
<div class="sec-head"><div class="sec-mark" style="background:var(--green)"></div>全景架构 · SYSTEM OVERVIEW</div>
|
||
|
||
<div class="arch">
|
||
<!-- Frontend -->
|
||
<div class="layer layer-frontend span-3">
|
||
<div class="layer-title"><div class="dot" style="background:var(--cyan);box-shadow:0 0 8px var(--cyan)"></div>前端层 · FRONTEND — React 18 + TypeScript + Vite</div>
|
||
<div class="modules">
|
||
<div class="mod mod-c"><b>Design System 组件</b><small>从 claude.ai/design 迁移 · TSX</small></div>
|
||
<div class="mod mod-c"><b>三栏看板</b><small>Sidebar · Main · EventPanel · 拖拽宽度</small></div>
|
||
<div class="mod mod-c"><b>Mobile Tab</b><small>390px · 底部四 Tab 导航</small></div>
|
||
<div class="mod mod-c"><b>Zustand</b><small>客户端状态管理</small></div>
|
||
<div class="mod mod-c"><b>i18n · 5 语言</b><small>zh / en / es / ja / fr</small></div>
|
||
<div class="mod mod-c"><b>WebSocket Client</b><small>实时看板刷新</small></div>
|
||
<div class="mod"><b>Vite Dev Server</b><small>开发时 API 代理 · HMR</small></div>
|
||
<div class="mod"><b>dist/web/</b><small>构建产物 → Fastify 托管</small></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="connector">
|
||
<div class="conn-item"><div class="conn-line"></div><span>REST · /api/*</span><div class="conn-line"></div></div>
|
||
<div class="conn-item"><div class="conn-line"></div><span>WebSocket · /ws</span><div class="conn-line"></div></div>
|
||
<div class="conn-item"><div class="conn-line"></div><span style="opacity:.4">Auth Token(预留)</span><div class="conn-line"></div></div>
|
||
</div>
|
||
|
||
<!-- API -->
|
||
<div class="layer layer-api span-2">
|
||
<div class="layer-title"><div class="dot" style="background:var(--violet);box-shadow:0 0 8px var(--violet)"></div>API 层 · Fastify(路由拆分 + Schema 校验)</div>
|
||
<div class="modules">
|
||
<div class="mod mod-v"><b>routes/projects</b><small>CRUD · logo · sync · reorder</small></div>
|
||
<div class="mod mod-v"><b>routes/tasks</b><small>CRUD · decide · requeue · transition</small></div>
|
||
<div class="mod mod-v"><b>routes/runs</b><small>transcript · active runs</small></div>
|
||
<div class="mod mod-v"><b>routes/approvals</b><small>pendingApprovals</small></div>
|
||
<div class="mod mod-v"><b>routes/metrics</b><small>健康度 · 成本聚合</small></div>
|
||
<div class="mod mod-v"><b>ws.ts</b><small>Store 事件 → 广播所有客户端</small></div>
|
||
<div class="mod"><b>middleware/auth.ts</b><small>no-op · 预留 JWT 插槽</small></div>
|
||
<div class="mod"><b>schemas/</b><small>Fastify JSON Schema 请求校验</small></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- DB -->
|
||
<div class="layer layer-db">
|
||
<div class="layer-title"><div class="dot" style="background:var(--amber);box-shadow:0 0 8px var(--amber)"></div>数据层 · DB ABSTRACTION</div>
|
||
<div class="modules">
|
||
<div class="mod mod-a"><b>DBAdapter 接口</b><small>统一抽象</small></div>
|
||
<div class="mod mod-a"><b>SqliteAdapter</b><small>当前实现</small></div>
|
||
<div class="mod" style="border-style:dashed;opacity:.55"><b>PostgresAdapter</b><small>未来多租户</small></div>
|
||
<div class="mod mod-a"><b>ProjectRepo</b></div>
|
||
<div class="mod mod-a"><b>TaskRepo</b></div>
|
||
<div class="mod mod-a"><b>RunRepo</b></div>
|
||
<div class="mod mod-a"><b>ApprovalRepo</b></div>
|
||
<div class="mod mod-a"><b>EventRepo</b></div>
|
||
<div class="mod mod-a"><b>MetricsRepo</b></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="connector">
|
||
<div class="conn-item"><div class="conn-line"></div><span>读写 DB</span><div class="conn-line"></div></div>
|
||
<div class="conn-item"><div class="conn-line"></div><span>事件订阅 → WS 推送</span><div class="conn-line"></div></div>
|
||
<div class="conn-item"><div class="conn-line"></div><span>调度查询</span><div class="conn-line"></div></div>
|
||
</div>
|
||
|
||
<!-- Daemon -->
|
||
<div class="layer layer-daemon span-2">
|
||
<div class="layer-title"><div class="dot" style="background:var(--green);box-shadow:0 0 8px var(--green)"></div>Daemon 层(拆分 4 职责)</div>
|
||
<div class="modules">
|
||
<div class="mod mod-g"><b>Orchestrator</b><small>协调者 · tick 主循环</small></div>
|
||
<div class="mod mod-g"><b>Scheduler</b><small>纯调度逻辑 · score → 选任务</small></div>
|
||
<div class="mod mod-g"><b>WorkerManager</b><small>spawn / reap / pid 管理</small></div>
|
||
<div class="mod mod-g"><b>Ingestor</b><small>outbox.ndjson → DB · 幂等摄取</small></div>
|
||
<div class="mod mod-g"><b>MergeCoordinator</b><small>merge-resolve 池 + settle</small></div>
|
||
<div class="mod"><b>config.ts</b></div>
|
||
<div class="mod"><b>notify.ts</b></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Worker -->
|
||
<div class="layer layer-worker">
|
||
<div class="layer-title"><div class="dot" style="background:var(--red);box-shadow:0 0 8px var(--red)"></div>Worker 进程(按类型拆分)</div>
|
||
<div class="modules">
|
||
<div class="mod mod-r"><b>pipelines/executor</b></div>
|
||
<div class="mod mod-r"><b>pipelines/planner</b></div>
|
||
<div class="mod mod-r"><b>pipelines/conflict</b></div>
|
||
<div class="mod mod-r"><b>pipelines/merge-resolve</b></div>
|
||
<div class="mod mod-r"><b>runners/executor</b><small>prompt + runTask</small></div>
|
||
<div class="mod mod-r"><b>runners/planner</b><small>prompt + runPlanner</small></div>
|
||
<div class="mod mod-r"><b>runners/conflict</b></div>
|
||
<div class="mod mod-r"><b>runners/merge-resolve</b></div>
|
||
<div class="mod" style="border-style:dashed"><b>文件协议(保留不变)</b><small>job.json → outbox.ndjson → heartbeat</small></div>
|
||
</div>
|
||
</div>
|
||
|
||
</div><!-- /arch -->
|
||
|
||
<!-- 执行数据流 -->
|
||
<div class="sec-head"><div class="sec-mark" style="background:var(--cyan)"></div>任务执行数据流 · EXECUTION FLOW</div>
|
||
|
||
<div class="flow">
|
||
<div class="flow-step" style="background:var(--violet-dim)">
|
||
<div class="flow-num">01 · 触发</div>
|
||
<div class="flow-title">用户 / API</div>
|
||
<div class="flow-desc">POST /api/.../tasks<br>创建任务 → init 态</div>
|
||
<div class="flow-arr">›</div>
|
||
</div>
|
||
<div class="flow-step" style="background:var(--green-dim)">
|
||
<div class="flow-num">02 · 调度</div>
|
||
<div class="flow-title">Scheduler</div>
|
||
<div class="flow-desc">score 排序 → claimable<br>ready → queued → executing</div>
|
||
<div class="flow-arr">›</div>
|
||
</div>
|
||
<div class="flow-step" style="background:var(--green-dim)">
|
||
<div class="flow-num">03 · 起进程</div>
|
||
<div class="flow-title">WorkerManager</div>
|
||
<div class="flow-desc">spawn worker 进程<br>写 job.json · 记 pid</div>
|
||
<div class="flow-arr">›</div>
|
||
</div>
|
||
<div class="flow-step" style="background:var(--red-dim)">
|
||
<div class="flow-num">04 · 执行</div>
|
||
<div class="flow-title">Worker Pipeline</div>
|
||
<div class="flow-desc">CC Agent 执行任务<br>追加 outbox.ndjson</div>
|
||
<div class="flow-arr">›</div>
|
||
</div>
|
||
<div class="flow-step" style="background:var(--amber-dim)">
|
||
<div class="flow-num">05 · 摄取</div>
|
||
<div class="flow-title">Ingestor</div>
|
||
<div class="flow-desc">outbox → DB<br>→ WS 推送 → 审核闸</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 重构变更 -->
|
||
<div class="sec-head"><div class="sec-mark" style="background:var(--amber)"></div>重构变更对照 · WHAT CHANGES</div>
|
||
|
||
<div class="detail-grid">
|
||
<div class="detail-card">
|
||
<h3 style="color:var(--red)">✕ 删除</h3>
|
||
<ul>
|
||
<li><b>web/app.js</b> (2473 行)<span class="note">替换为 React + TypeScript 前端</span></li>
|
||
<li><b>web/style.css</b> (1333 行)<span class="note">设计 token 迁移到 frontend/src/tokens/</span></li>
|
||
<li><b>web/index.html</b><span class="note">Vite 入口替代</span></li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="detail-card">
|
||
<h3 style="color:var(--green)">✓ 保留不动</h3>
|
||
<ul>
|
||
<li><b>文件协议</b> — job.json / outbox.ndjson / heartbeat</li>
|
||
<li><b>状态机</b> — src/model/status.ts · TRANSITIONS</li>
|
||
<li><b>Score 调度算法</b> — src/model/scoring.ts</li>
|
||
<li><b>CC 封装</b> — src/executor/cc.ts</li>
|
||
<li><b>Schema SQL</b> — src/store/schema.sql</li>
|
||
<li><b>MCP server</b> — src/mcp/</li>
|
||
<li><b>CLI</b> — src/cli/</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="detail-card">
|
||
<h3 style="color:var(--amber)">⟳ 拆分重构</h3>
|
||
<ul>
|
||
<li><b>store.ts</b> (1227行) → <span style="color:var(--amber)">6 Repo + DBAdapter 接口</span></li>
|
||
<li><b>orchestrator.ts</b> (426行) → <span style="color:var(--amber)">Scheduler + WorkerManager + Ingestor + MergeCoordinator</span></li>
|
||
<li><b>runner.ts</b> (353行) → <span style="color:var(--amber)">runners/ 4 个独立文件</span></li>
|
||
<li><b>pipeline.ts</b> (358行) → <span style="color:var(--amber)">pipelines/ 4 个独立文件</span></li>
|
||
<li><b>server.ts</b> (401行) → <span style="color:var(--amber)">routes/ 5 个路由模块 + Schema</span></li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="detail-card">
|
||
<h3 style="color:var(--cyan)">✦ 新增</h3>
|
||
<ul>
|
||
<li><b>frontend/</b> — React + TypeScript + Vite 工程</li>
|
||
<li><b>frontend/components/</b> — claude design → TSX 组件库</li>
|
||
<li><b>src/store/db.ts</b> — DBAdapter 抽象接口</li>
|
||
<li><b>src/store/repos/</b> — 6 个职责单一的 Repository</li>
|
||
<li><b>src/api/middleware/auth.ts</b> — Auth 插槽(no-op)</li>
|
||
<li><b>src/api/schemas/</b> — Fastify JSON Schema 校验</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 目录结构 -->
|
||
<div class="sec-head"><div class="sec-mark" style="background:var(--violet)"></div>目录结构 · FILE STRUCTURE</div>
|
||
|
||
<div class="file-tree">
|
||
<div class="file-grid">
|
||
<div>
|
||
<div class="ft-dir">frontend/ <span class="ft-new">← 全新</span></div>
|
||
<div class="i1 ft-new">src/</div>
|
||
<div class="i2 ft-new">main.tsx</div>
|
||
<div class="i2 ft-new">App.tsx <span class="ft-c">三栏布局 · 状态根</span></div>
|
||
<div class="i2 ft-new">components/ <span class="ft-c">← claude design 迁移</span></div>
|
||
<div class="i3 ft-new">core/ <span class="ft-c">Button · StatusChip · ...</span></div>
|
||
<div class="i3 ft-new">forms/ <span class="ft-c">Input · Select · ...</span></div>
|
||
<div class="i3 ft-new">surfaces/ <span class="ft-c">Panel · GateCard · ...</span></div>
|
||
<div class="i2 ft-new">ui/ <span class="ft-c">页面级组件</span></div>
|
||
<div class="i3 ft-new">Sidebar.tsx</div>
|
||
<div class="i3 ft-new">Topbar.tsx</div>
|
||
<div class="i3 ft-new">GateSection.tsx</div>
|
||
<div class="i3 ft-new">TaskTree.tsx</div>
|
||
<div class="i3 ft-new">EventPanel.tsx</div>
|
||
<div class="i3 ft-new">ArchiveSection.tsx</div>
|
||
<div class="i2 ft-new">api/ <span class="ft-c">HTTP + WS 客户端</span></div>
|
||
<div class="i2 ft-new">store/ <span class="ft-c">Zustand 状态管理</span></div>
|
||
<div class="i2 ft-new">i18n/ <span class="ft-c">5 语言字符串</span></div>
|
||
<div class="i2 ft-new">tokens/ <span class="ft-c">CSS 自定义属性</span></div>
|
||
<div class="i1 ft-new">index.html</div>
|
||
<div class="i1 ft-new">vite.config.ts</div>
|
||
<div class="i1 ft-new">tsconfig.json</div>
|
||
<br>
|
||
<div class="ft-del">web/ <span class="ft-c">整体删除</span></div>
|
||
<div class="i1 ft-del">app.js <span class="ft-c">2473 行</span></div>
|
||
<div class="i1 ft-del">style.css <span class="ft-c">1333 行</span></div>
|
||
<div class="i1 ft-del">index.html</div>
|
||
</div>
|
||
<div>
|
||
<div class="ft-dir">src/</div>
|
||
<div class="i1 ft-dir">api/</div>
|
||
<div class="i2 ft-file">server.ts <span class="ft-c">入口(精简为注册插件)</span></div>
|
||
<div class="i2 ft-new">routes/ <span class="ft-c">← 拆分</span></div>
|
||
<div class="i3 ft-new">projects.ts · tasks.ts · runs.ts</div>
|
||
<div class="i3 ft-new">approvals.ts · metrics.ts</div>
|
||
<div class="i2 ft-new">schemas/ <span class="ft-c">JSON Schema 请求校验</span></div>
|
||
<div class="i2 ft-new">middleware/auth.ts <span class="ft-c">no-op 插槽</span></div>
|
||
<br>
|
||
<div class="i1 ft-dir">store/</div>
|
||
<div class="i2 ft-new">db.ts <span class="ft-c">DBAdapter 接口</span></div>
|
||
<div class="i2 ft-new">sqlite.ts <span class="ft-c">当前实现</span></div>
|
||
<div class="i2 ft-new">repos/ <span class="ft-c">← 拆分自 store.ts</span></div>
|
||
<div class="i3 ft-new">ProjectRepo · TaskRepo · RunRepo</div>
|
||
<div class="i3 ft-new">ApprovalRepo · EventRepo · MetricsRepo</div>
|
||
<div class="i2 ft-file">index.ts <span class="ft-c">Store 聚合(外部接口不变)</span></div>
|
||
<div class="i2 ft-file">mappers.ts <span class="ft-c">保留</span></div>
|
||
<br>
|
||
<div class="i1 ft-dir">daemon/</div>
|
||
<div class="i2 ft-new">scheduler.ts <span class="ft-c">← 拆分 · 纯调度逻辑</span></div>
|
||
<div class="i2 ft-new">worker-manager.ts <span class="ft-c">← 拆分 · 进程管理</span></div>
|
||
<div class="i2 ft-file">ingest.ts <span class="ft-c">保留接口不变</span></div>
|
||
<div class="i2 ft-new">merge-coordinator.ts <span class="ft-c">← 拆分</span></div>
|
||
<div class="i2 ft-new">orchestrator.ts <span class="ft-c">精简为协调者</span></div>
|
||
<br>
|
||
<div class="i1 ft-dir">executor/</div>
|
||
<div class="i2 ft-new">runners/ <span class="ft-c">← 拆分自 runner.ts</span></div>
|
||
<div class="i3 ft-new">executor · planner · conflict · merge-resolve</div>
|
||
<div class="i2 ft-new">pipelines/ <span class="ft-c">← 拆分自 pipeline.ts</span></div>
|
||
<div class="i3 ft-new">executor · planner · conflict · merge-resolve</div>
|
||
<div class="i2 ft-file">cc.ts · models.ts · worktree.ts <span class="ft-c">保留</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="padding:14px 16px; border:1px solid var(--line); border-radius:var(--radius-md); background:var(--panel); color:var(--faint); font-size:11px; letter-spacing:.08em;">
|
||
MAESTRO ARCHITECTURE · v2.0 DRAFT · 仅设计文档,尚未实现 · <span style="color:var(--green)">保留</span> · <span style="color:var(--amber)">拆分重构</span> · <span style="color:var(--cyan)">新增</span> · <span style="color:var(--red)">删除</span>
|
||
</div>
|
||
|
||
</div>
|
||
</body>
|
||
</html>
|