Phase 6.4 - Modular Architecture: - Add lewooogo-brain adapters for LLM providers - Add lewooogo-data dual memory (Redis + PostgreSQL) - Implement consensus engine for multi-agent decisions - Add incident memory service for historical context Phase 9 - Agent Teams (Claude Agent SDK): - Add base agent class with Claude Sonnet 4 integration - Implement action planner, blast radius, and security agents - Add agent API endpoints and proposal workflow - Integrate ADR-009 OpenClaw Agent Teams architecture DevOps & CI/CD: - Add GitHub Actions CI/CD workflows (ci.yaml, cd.yaml) - Add pre-commit hooks and secrets baseline - Add docker-compose for local development - Update Kubernetes network policies Frontend Improvements: - Add auto-healing error boundary component - Update i18n messages for agent features - Enhance dual-state incident card with execution feedback Documentation: - Add 7 ADRs covering MCP, design system, architecture decisions - Update ARCHITECTURE_MEMORY.md with modular design - Add GLOBAL_RULES.md and SOUL.md for project identity Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
656 lines
14 KiB
Markdown
656 lines
14 KiB
Markdown
# AWOOOI 原子組件庫規格
|
|
|
|
> **版本**: v1.0
|
|
> **建立日期**: 2026-03-20
|
|
> **負責人**: CPO
|
|
> **設計系統**: Nothing.tech 純白工業風
|
|
|
|
---
|
|
|
|
## 概述
|
|
|
|
本文件定義 AWOOOI 前端組件庫的設計規格,採用 Atomic Design 原則,確保視覺一致性與開發效率。
|
|
|
|
---
|
|
|
|
## 設計 Token
|
|
|
|
### 色彩系統
|
|
|
|
```typescript
|
|
// packages/lewooogo-ui/src/tokens/colors.ts
|
|
|
|
export const colors = {
|
|
// 基底色 (Pure White Base)
|
|
white: '#FFFFFF',
|
|
snow: '#FAFAFA', // 主背景
|
|
cloud: '#F5F5F5', // 次背景/卡片
|
|
mist: '#E5E5E5', // 邊框/分隔線
|
|
|
|
// 文字色 (High Contrast)
|
|
ink: '#0A0A0A', // 主文字
|
|
gray: {
|
|
600: '#6B7280', // 次文字
|
|
400: '#9CA3AF', // 輔助文字
|
|
200: '#E5E7EB', // 禁用文字
|
|
},
|
|
|
|
// 功能色
|
|
status: {
|
|
success: '#10B981',
|
|
warning: '#F59E0B',
|
|
error: '#EF4444',
|
|
info: '#3B82F6',
|
|
thinking: '#8B5CF6', // AI 思考中
|
|
},
|
|
|
|
// 品牌色
|
|
brand: {
|
|
primary: '#FF6B35', // AWOOOI 橘
|
|
nothingRed: '#D71921', // Nothing 品牌紅
|
|
},
|
|
} as const;
|
|
```
|
|
|
|
### 間距系統
|
|
|
|
```typescript
|
|
// packages/lewooogo-ui/src/tokens/spacing.ts
|
|
|
|
export const spacing = {
|
|
0: '0',
|
|
1: '4px',
|
|
2: '8px',
|
|
3: '12px',
|
|
4: '16px',
|
|
5: '20px',
|
|
6: '24px',
|
|
8: '32px',
|
|
10: '40px',
|
|
12: '48px',
|
|
16: '64px',
|
|
} as const;
|
|
```
|
|
|
|
### 字體系統
|
|
|
|
```typescript
|
|
// packages/lewooogo-ui/src/tokens/typography.ts
|
|
|
|
export const typography = {
|
|
fontFamily: {
|
|
display: '"NDot", monospace', // AI 介面/數字
|
|
body: '"Inter", system-ui', // 一般文字
|
|
mono: '"JetBrains Mono", monospace', // 程式碼
|
|
},
|
|
|
|
fontSize: {
|
|
xs: '12px',
|
|
sm: '14px',
|
|
base: '16px',
|
|
lg: '18px',
|
|
xl: '20px',
|
|
'2xl': '24px',
|
|
'3xl': '30px',
|
|
'4xl': '36px',
|
|
},
|
|
|
|
fontWeight: {
|
|
normal: 400,
|
|
medium: 500,
|
|
semibold: 600,
|
|
bold: 700,
|
|
},
|
|
|
|
lineHeight: {
|
|
tight: 1.25,
|
|
normal: 1.5,
|
|
relaxed: 1.75,
|
|
},
|
|
} as const;
|
|
```
|
|
|
|
### 效果系統
|
|
|
|
```typescript
|
|
// packages/lewooogo-ui/src/tokens/effects.ts
|
|
|
|
export const effects = {
|
|
// 白玻璃效果 (White Glassmorphism)
|
|
glass: {
|
|
background: 'rgba(255, 255, 255, 0.7)',
|
|
blur: 'blur(20px)',
|
|
border: 'rgba(0, 0, 0, 0.05)',
|
|
},
|
|
|
|
// 點陣紋理 (Dot Matrix)
|
|
dotMatrix: {
|
|
pattern: 'radial-gradient(circle, rgba(0, 0, 0, 0.03) 1px, transparent 1px)',
|
|
size: '16px 16px',
|
|
},
|
|
|
|
// 陰影
|
|
shadow: {
|
|
sm: '0 1px 2px rgba(0, 0, 0, 0.05)',
|
|
md: '0 4px 6px rgba(0, 0, 0, 0.05)',
|
|
lg: '0 10px 15px rgba(0, 0, 0, 0.05)',
|
|
glow: '0 0 20px rgba(255, 107, 53, 0.2)', // 品牌光暈
|
|
},
|
|
|
|
// 圓角
|
|
radius: {
|
|
sm: '4px',
|
|
md: '8px',
|
|
lg: '12px',
|
|
xl: '16px',
|
|
full: '9999px',
|
|
},
|
|
|
|
// 過渡
|
|
transition: {
|
|
fast: '150ms ease',
|
|
normal: '250ms ease',
|
|
slow: '350ms ease',
|
|
},
|
|
} as const;
|
|
```
|
|
|
|
---
|
|
|
|
## Atoms (原子組件)
|
|
|
|
### StatusOrb - 狀態呼吸燈
|
|
|
|
```tsx
|
|
// packages/lewooogo-ui/src/atoms/StatusOrb.tsx
|
|
|
|
interface StatusOrbProps {
|
|
status: 'healthy' | 'warning' | 'critical' | 'unknown' | 'thinking';
|
|
size?: 'sm' | 'md' | 'lg';
|
|
pulse?: boolean;
|
|
label?: string;
|
|
}
|
|
|
|
/**
|
|
* 狀態呼吸燈
|
|
* - 即時反映系統/主機狀態
|
|
* - 支援脈衝動畫 (告警/思考中)
|
|
*
|
|
* @example
|
|
* <StatusOrb status="healthy" size="md" />
|
|
* <StatusOrb status="thinking" pulse label="AI 處理中" />
|
|
*/
|
|
```
|
|
|
|
**視覺規格**:
|
|
| Size | 直徑 | 光暈半徑 |
|
|
|------|------|---------|
|
|
| sm | 8px | 12px |
|
|
| md | 12px | 18px |
|
|
| lg | 16px | 24px |
|
|
|
|
**狀態色彩**:
|
|
| Status | 色彩 | 脈衝 |
|
|
|--------|------|------|
|
|
| healthy | `#10B981` | 無 |
|
|
| warning | `#F59E0B` | 慢 (2s) |
|
|
| critical | `#EF4444` | 快 (0.5s) |
|
|
| unknown | `#9CA3AF` | 無 |
|
|
| thinking | `#8B5CF6` | 中 (1s) |
|
|
|
|
---
|
|
|
|
### MetricValue - 數值顯示
|
|
|
|
```tsx
|
|
// packages/lewooogo-ui/src/atoms/MetricValue.tsx
|
|
|
|
interface MetricValueProps {
|
|
value: number | string;
|
|
unit?: string;
|
|
trend?: 'up' | 'down' | 'stable';
|
|
trendValue?: string;
|
|
size?: 'sm' | 'md' | 'lg' | 'xl';
|
|
format?: 'number' | 'percent' | 'bytes' | 'duration';
|
|
}
|
|
|
|
/**
|
|
* 數值顯示組件
|
|
* - NDot 字體呈現數字
|
|
* - 支援趨勢箭頭與變化值
|
|
*
|
|
* @example
|
|
* <MetricValue value={99.9} unit="%" trend="up" trendValue="+0.1%" />
|
|
* <MetricValue value={1024} format="bytes" /> // 顯示 "1 KB"
|
|
*/
|
|
```
|
|
|
|
**視覺規格**:
|
|
| Size | 字體大小 | 權重 |
|
|
|------|---------|------|
|
|
| sm | 18px | 500 |
|
|
| md | 24px | 600 |
|
|
| lg | 36px | 700 |
|
|
| xl | 48px | 700 |
|
|
|
|
---
|
|
|
|
### IconButton - 圖示按鈕
|
|
|
|
```tsx
|
|
// packages/lewooogo-ui/src/atoms/IconButton.tsx
|
|
|
|
interface IconButtonProps {
|
|
icon: ReactNode;
|
|
variant?: 'ghost' | 'outline' | 'solid';
|
|
size?: 'sm' | 'md' | 'lg';
|
|
color?: 'default' | 'primary' | 'danger';
|
|
disabled?: boolean;
|
|
loading?: boolean;
|
|
tooltip?: string;
|
|
onClick?: () => void;
|
|
}
|
|
|
|
/**
|
|
* 圖示按鈕
|
|
* - 用於工具列、操作區
|
|
* - 必須有 tooltip 說明
|
|
*/
|
|
```
|
|
|
|
---
|
|
|
|
### Badge - 標籤徽章
|
|
|
|
```tsx
|
|
// packages/lewooogo-ui/src/atoms/Badge.tsx
|
|
|
|
interface BadgeProps {
|
|
children: ReactNode;
|
|
variant?: 'solid' | 'outline' | 'subtle';
|
|
color?: 'gray' | 'green' | 'yellow' | 'red' | 'blue' | 'purple' | 'orange';
|
|
size?: 'sm' | 'md';
|
|
dot?: boolean;
|
|
}
|
|
|
|
/**
|
|
* 標籤徽章
|
|
* - 用於狀態標示、分類
|
|
*
|
|
* @example
|
|
* <Badge color="green">Active</Badge>
|
|
* <Badge color="red" dot>3 Alerts</Badge>
|
|
*/
|
|
```
|
|
|
|
---
|
|
|
|
## Molecules (分子組件)
|
|
|
|
### GlassCard - 玻璃卡片
|
|
|
|
```tsx
|
|
// packages/lewooogo-ui/src/molecules/GlassCard.tsx
|
|
|
|
interface GlassCardProps {
|
|
children: ReactNode;
|
|
variant?: 'default' | 'elevated' | 'bordered';
|
|
padding?: 'sm' | 'md' | 'lg';
|
|
interactive?: boolean;
|
|
selected?: boolean;
|
|
onClick?: () => void;
|
|
}
|
|
|
|
/**
|
|
* 白玻璃卡片
|
|
* - Nothing.tech 核心視覺元素
|
|
* - 支援點擊交互與選中狀態
|
|
*
|
|
* CSS:
|
|
* - background: rgba(255, 255, 255, 0.7)
|
|
* - backdrop-filter: blur(20px)
|
|
* - border: 1px solid rgba(0, 0, 0, 0.05)
|
|
*/
|
|
```
|
|
|
|
**視覺規格**:
|
|
| Variant | 背景 | 邊框 | 陰影 |
|
|
|---------|------|------|------|
|
|
| default | glass | subtle | sm |
|
|
| elevated | glass | subtle | lg |
|
|
| bordered | white | solid | none |
|
|
|
|
---
|
|
|
|
### HostCard - 主機卡片
|
|
|
|
```tsx
|
|
// packages/lewooogo-ui/src/molecules/HostCard.tsx
|
|
|
|
interface HostCardProps {
|
|
host: {
|
|
id: string;
|
|
name: string;
|
|
ip: string;
|
|
role: string;
|
|
status: 'healthy' | 'warning' | 'critical' | 'unknown';
|
|
metrics?: {
|
|
cpu: number;
|
|
memory: number;
|
|
disk: number;
|
|
};
|
|
lastSeen?: string;
|
|
};
|
|
variant?: 'compact' | 'detailed';
|
|
showMetrics?: boolean;
|
|
onClick?: () => void;
|
|
}
|
|
|
|
/**
|
|
* 主機狀態卡片
|
|
* - 戰情室核心組件
|
|
* - 整合 StatusOrb + MetricValue
|
|
*
|
|
* @example
|
|
* <HostCard host={hostData} variant="detailed" showMetrics />
|
|
*/
|
|
```
|
|
|
|
**佈局**:
|
|
```
|
|
┌──────────────────────────────────────┐
|
|
│ ● web-server-01 [healthy] │
|
|
│ 192.168.0.188 · AI+Web 中心 │
|
|
├──────────────────────────────────────┤
|
|
│ CPU Memory Disk │
|
|
│ 45% 72% 58% │
|
|
│ ████░ ███████░ █████░ │
|
|
└──────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
### AlertPanel - 告警面板
|
|
|
|
```tsx
|
|
// packages/lewooogo-ui/src/molecules/AlertPanel.tsx
|
|
|
|
interface AlertPanelProps {
|
|
alerts: Alert[];
|
|
maxVisible?: number;
|
|
showTimestamp?: boolean;
|
|
onAlertClick?: (alert: Alert) => void;
|
|
onAcknowledge?: (alertId: string) => void;
|
|
}
|
|
|
|
interface Alert {
|
|
id: string;
|
|
severity: 'info' | 'warning' | 'critical';
|
|
title: string;
|
|
message: string;
|
|
source: string;
|
|
timestamp: string;
|
|
acknowledged?: boolean;
|
|
}
|
|
|
|
/**
|
|
* 告警列表面板
|
|
* - 即時更新 (SSE)
|
|
* - 支援確認操作
|
|
*/
|
|
```
|
|
|
|
---
|
|
|
|
### ApprovalCard - HITL 審批卡片
|
|
|
|
```tsx
|
|
// packages/lewooogo-ui/src/molecules/ApprovalCard.tsx
|
|
|
|
interface ApprovalCardProps {
|
|
approval: {
|
|
id: string;
|
|
type: 'deploy' | 'rollback' | 'config' | 'security';
|
|
title: string;
|
|
description: string;
|
|
requester: string;
|
|
blastRadius: 'low' | 'medium' | 'high' | 'critical';
|
|
signaturesRequired: number;
|
|
signaturesCollected: Signature[];
|
|
expiresAt: string;
|
|
aiSummary?: string;
|
|
aiConfidence?: number;
|
|
};
|
|
currentUser: string;
|
|
onApprove?: () => void;
|
|
onReject?: () => void;
|
|
onRequestInfo?: () => void;
|
|
}
|
|
|
|
/**
|
|
* Human-In-The-Loop 審批卡片
|
|
* - 顯示 Blast Radius 風險等級
|
|
* - 支援 Multi-Sig 簽核進度
|
|
* - AI 摘要與信心度
|
|
*/
|
|
```
|
|
|
|
**佈局**:
|
|
```
|
|
┌──────────────────────────────────────────────────┐
|
|
│ 🚀 部署請求: web-api v2.3.1 │
|
|
│ ════════════════════════════════════════════════ │
|
|
│ │
|
|
│ 📊 Blast Radius: ████████░░ HIGH │
|
|
│ 影響: 3 服務 · 12 Pods · ~5000 用戶 │
|
|
│ │
|
|
│ 🤖 AI 摘要: 此更新包含 API 破壞性變更,建議 │
|
|
│ 先通知下游服務團隊。信心度: 87% │
|
|
│ │
|
|
│ ✍️ 簽核進度: 1/2 │
|
|
│ ✅ CTO (2026-03-20 10:30) │
|
|
│ ⏳ CISO │
|
|
│ │
|
|
│ [詢問更多] [拒絕] [批准] │
|
|
└──────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Organisms (組織組件)
|
|
|
|
### CommandPalette - 快捷命令面板
|
|
|
|
```tsx
|
|
// packages/lewooogo-ui/src/organisms/CommandPalette.tsx
|
|
|
|
interface CommandPaletteProps {
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
commands: Command[];
|
|
recentCommands?: string[];
|
|
onCommandSelect: (command: Command) => void;
|
|
}
|
|
|
|
interface Command {
|
|
id: string;
|
|
label: string;
|
|
description?: string;
|
|
icon?: ReactNode;
|
|
shortcut?: string;
|
|
category: 'navigation' | 'action' | 'ai' | 'settings';
|
|
action: () => void;
|
|
}
|
|
|
|
/**
|
|
* Cmd+K 快捷命令面板
|
|
* - 全站快速導航與操作
|
|
* - 支援模糊搜尋
|
|
* - 顯示快捷鍵提示
|
|
*/
|
|
```
|
|
|
|
**快捷鍵**:
|
|
| 快捷鍵 | 功能 |
|
|
|-------|------|
|
|
| `Cmd+K` | 開啟面板 |
|
|
| `Esc` | 關閉面板 |
|
|
| `↑/↓` | 選擇項目 |
|
|
| `Enter` | 執行命令 |
|
|
|
|
---
|
|
|
|
### ThinkingTerminal - AI 思考終端
|
|
|
|
```tsx
|
|
// packages/lewooogo-ui/src/organisms/ThinkingTerminal.tsx
|
|
|
|
interface ThinkingTerminalProps {
|
|
isOpen: boolean;
|
|
stream: ThinkingStream | null;
|
|
position?: 'bottom' | 'right';
|
|
collapsible?: boolean;
|
|
}
|
|
|
|
interface ThinkingStream {
|
|
status: 'idle' | 'thinking' | 'completed' | 'error';
|
|
steps: ThinkingStep[];
|
|
result?: string;
|
|
error?: string;
|
|
}
|
|
|
|
interface ThinkingStep {
|
|
id: string;
|
|
type: 'input' | 'process' | 'output' | 'tool_call';
|
|
content: string;
|
|
timestamp: string;
|
|
duration?: number;
|
|
}
|
|
|
|
/**
|
|
* AI 思考過程終端
|
|
* - SSE 即時串流
|
|
* - 打字機效果
|
|
* - 支援摺疊
|
|
*/
|
|
```
|
|
|
|
---
|
|
|
|
### DataPincer - 數據鉗視覺化
|
|
|
|
```tsx
|
|
// packages/lewooogo-ui/src/organisms/DataPincer.tsx
|
|
|
|
interface DataPincerProps {
|
|
data: {
|
|
hosts: HostData[];
|
|
connections: Connection[];
|
|
flows: DataFlow[];
|
|
};
|
|
viewMode?: '2d' | '3d';
|
|
interactive?: boolean;
|
|
highlightHost?: string;
|
|
onHostClick?: (hostId: string) => void;
|
|
}
|
|
|
|
/**
|
|
* 數據鉗視覺化組件
|
|
* - AWOOOI 品牌視覺符號
|
|
* - 四主機架構拓撲圖
|
|
* - 即時資料流動畫
|
|
*/
|
|
```
|
|
|
|
---
|
|
|
|
## Templates (模板)
|
|
|
|
### DashboardLayout - 儀表板佈局
|
|
|
|
```tsx
|
|
// packages/lewooogo-ui/src/templates/DashboardLayout.tsx
|
|
|
|
interface DashboardLayoutProps {
|
|
children: ReactNode;
|
|
sidebar?: ReactNode;
|
|
header?: ReactNode;
|
|
background?: 'default' | 'dotMatrix';
|
|
}
|
|
|
|
/**
|
|
* 儀表板頁面佈局
|
|
* - 支援側邊欄
|
|
* - 點陣背景紋理
|
|
* - 響應式設計
|
|
*/
|
|
```
|
|
|
|
**斷點**:
|
|
| 斷點 | 寬度 | 佈局 |
|
|
|------|------|------|
|
|
| mobile | < 768px | 單欄 + 抽屜選單 |
|
|
| tablet | 768-1024px | 摺疊側欄 |
|
|
| desktop | 1024-1440px | 展開側欄 |
|
|
| wide | > 1440px | 展開側欄 + 更多欄位 |
|
|
|
|
---
|
|
|
|
## 無障礙規範 (WCAG 2.1 AA)
|
|
|
|
### 對比度要求
|
|
|
|
| 元素 | 最小對比度 | 實際值 |
|
|
|------|-----------|--------|
|
|
| 正文文字 | 4.5:1 | 17.3:1 (ink/snow) |
|
|
| 大標題 | 3:1 | 17.3:1 |
|
|
| 非文字元素 | 3:1 | 符合 |
|
|
| 狀態色 (綠) | 3:1 | 4.5:1 (success/snow) |
|
|
|
|
### 互動元素
|
|
|
|
- 所有可點擊元素必須有 `focus-visible` 樣式
|
|
- 鍵盤可操作 (Tab 導航)
|
|
- 適當的 `aria-label`
|
|
- 螢幕閱讀器支援
|
|
|
|
### Focus 樣式
|
|
|
|
```css
|
|
.focus-visible {
|
|
outline: 2px solid var(--brand-primary);
|
|
outline-offset: 2px;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 組件狀態
|
|
|
|
| 組件 | 狀態 | 負責人 |
|
|
|------|------|--------|
|
|
| StatusOrb | ⏳ 待開發 | CPO |
|
|
| MetricValue | ⏳ 待開發 | CPO |
|
|
| IconButton | ⏳ 待開發 | CPO |
|
|
| Badge | ⏳ 待開發 | CPO |
|
|
| GlassCard | ⏳ 待開發 | CPO |
|
|
| HostCard | ⏳ 待開發 | CPO |
|
|
| AlertPanel | ⏳ 待開發 | CPO |
|
|
| ApprovalCard | ⏳ 待開發 | CPO |
|
|
| CommandPalette | ⏳ 待開發 | CPO |
|
|
| ThinkingTerminal | ⏳ 待開發 | CPO |
|
|
| DataPincer | ⏳ 待開發 | CPO |
|
|
| DashboardLayout | ⏳ 待開發 | CPO |
|
|
|
|
---
|
|
|
|
## 變更記錄
|
|
|
|
| 日期 | 版本 | 變更 | 作者 |
|
|
|------|------|------|------|
|
|
| 2026-03-20 | v1.0 | 初版建立 | CPO |
|
|
|
|
---
|
|
|
|
*此文件由 CPO 維護,前端開發者必須遵守此規格。*
|