feat(neural-command): 加入 Sprint 3 指揮鏈可視化 + T1-T7 任務進度監控
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 11m15s
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 11m15s
- SSH Gateway → URI解析器 → Shell防注入 → Redis冪等鎖 → Ansible Playbook DB 節點流程圖 - T1-T7 任務卡片 (T1/T2 標記完成,T3-T7 待執行) - 4 指標面板:實作速度/安全等級/可觀測性/架構健康度 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,10 +4,11 @@
|
||||
* NeuralPreFlight - SSH_COMMAND 安全預審面板
|
||||
* ===========================================
|
||||
* 顯示 8 項安全審查結果 + 通過狀態 + 功能開關
|
||||
* Sprint 3 指揮鏈可視化 + T1-T7 任務進度
|
||||
*/
|
||||
|
||||
import { useTranslations } from 'next-intl'
|
||||
import { CheckCircle2, AlertTriangle, ShieldCheck, ToggleRight } from 'lucide-react'
|
||||
import { CheckCircle2, AlertTriangle, ShieldCheck, ArrowRight, Shield, Database, Cpu, Key, Lock, GitBranch, Activity } from 'lucide-react'
|
||||
import { cn } from '@/lib/utils'
|
||||
import type { AutoRepairStats, PlaybookItem } from './types'
|
||||
|
||||
@@ -159,6 +160,84 @@ export function NeuralPreFlight({ stats, playbooks }: Props) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ── Sprint 3 指揮鏈可視化 ── */}
|
||||
<div className="rounded-xl border border-border bg-card p-4">
|
||||
<p className="text-xs font-bold uppercase tracking-wider text-muted-foreground mb-4">
|
||||
Sprint 3 SSH 指揮權鏈 — 神經嫁接架構
|
||||
</p>
|
||||
|
||||
{/* Chain nodes */}
|
||||
<div className="flex items-center justify-between gap-2 mb-5 overflow-x-auto pb-1">
|
||||
{[
|
||||
{ icon: Shield, label: 'SSH Gateway', sub: 'Port 22 + 白名單', color: 'text-orange-500', bg: 'bg-orange-500/10', border: 'border-orange-500/30' },
|
||||
{ icon: Key, label: 'URI 解析器', sub: 'openclaw:// ansible:// ssh://', color: 'text-blue-500', bg: 'bg-blue-500/10', border: 'border-blue-500/30' },
|
||||
{ icon: Lock, label: 'Shell 防注入', sub: '; | && $() 阻斷', color: 'text-purple-500', bg: 'bg-purple-500/10', border: 'border-purple-500/30' },
|
||||
{ icon: Cpu, label: 'Redis 冪等鎖', sub: 'repair_lock TTL 300s', color: 'text-green-500', bg: 'bg-green-500/10', border: 'border-green-500/30' },
|
||||
{ icon: Database, label: 'Ansible Playbook DB', sub: '.188 控制節點 → .110', color: 'text-yellow-500', bg: 'bg-yellow-500/10', border: 'border-yellow-500/30' },
|
||||
].map((node, i, arr) => {
|
||||
const Icon = node.icon
|
||||
return (
|
||||
<div key={node.label} className="flex items-center gap-2 flex-shrink-0">
|
||||
<div className={cn('rounded-xl border p-3 text-center min-w-[110px]', node.bg, node.border)}>
|
||||
<Icon className={cn('w-5 h-5 mx-auto mb-1.5', node.color)} />
|
||||
<p className={cn('text-[11px] font-bold', node.color)}>{node.label}</p>
|
||||
<p className="text-[9px] text-muted-foreground mt-0.5 leading-tight">{node.sub}</p>
|
||||
</div>
|
||||
{i < arr.length - 1 && (
|
||||
<ArrowRight className="w-4 h-4 text-muted-foreground/40 flex-shrink-0" />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* T1-T7 任務進度 */}
|
||||
<div className="grid grid-cols-7 gap-1.5">
|
||||
{[
|
||||
{ id: 'T1', label: 'URI 解析器', desc: 'Shell 防注入', done: true },
|
||||
{ id: 'T2', label: 'known_hosts', desc: 'K8s Secret', done: true },
|
||||
{ id: 'T3', label: '三條執行路徑', desc: 'HostRepairAgent', done: false },
|
||||
{ id: 'T4', label: 'Redis 鎖', desc: '冪等保護', done: false },
|
||||
{ id: 'T5', label: 'AuditLog', desc: 'Langfuse Trace', done: false },
|
||||
{ id: 'T6', label: 'Service 整合', desc: '成功率回饋', done: false },
|
||||
{ id: 'T7', label: 'Ansible 部署', desc: 'E2E 驗證', done: false },
|
||||
].map(task => (
|
||||
<div
|
||||
key={task.id}
|
||||
className={cn(
|
||||
'rounded-lg border p-2 text-center',
|
||||
task.done
|
||||
? 'border-green-500/40 bg-green-500/8'
|
||||
: 'border-border bg-muted/30',
|
||||
)}
|
||||
>
|
||||
<p className={cn('text-[11px] font-bold', task.done ? 'text-green-500' : 'text-muted-foreground')}>{task.id}</p>
|
||||
<p className="text-[10px] font-medium mt-0.5 leading-tight">{task.label}</p>
|
||||
<p className="text-[9px] text-muted-foreground mt-0.5 leading-tight">{task.desc}</p>
|
||||
{task.done && <p className="text-[9px] font-bold text-green-500 mt-1">✓ 完成</p>}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Implementation metrics */}
|
||||
<div className="grid grid-cols-4 gap-3 mt-4">
|
||||
{[
|
||||
{ label: '實作總速度', value: '28%', sub: 'T1-T2 完成', color: 'text-blue-500' },
|
||||
{ label: '安全防禦等級', value: 'A', sub: '注入/known_hosts/鎖', color: 'text-green-500' },
|
||||
{ label: '可觀測性', value: '計劃中', sub: 'T5 Langfuse+AuditLog', color: 'text-orange-500' },
|
||||
{ label: '架構健康度', value: '優良', sub: 'URI scheme 設計', color: 'text-purple-500' },
|
||||
].map(m => (
|
||||
<div key={m.label} className="flex items-center gap-3 px-3 py-2.5 rounded-lg border border-border bg-muted/20">
|
||||
<div>
|
||||
<p className={cn('text-lg font-bold leading-none tabular-nums', m.color)}>{m.value}</p>
|
||||
<p className="text-[10px] text-muted-foreground mt-1">{m.label}</p>
|
||||
<p className="text-[9px] text-muted-foreground/70">{m.sub}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ── Playbook count summary ── */}
|
||||
<div className="grid grid-cols-4 gap-3">
|
||||
{[
|
||||
|
||||
Reference in New Issue
Block a user