# 技術債清理與架構改進實施計劃

## Overview

清理 FWAuto codebase 中的技術債務並改進 AI nodes 架構，提升程式碼品質和可維護性。此計劃專注於三個主要目標：

1. **AI Brain Node 未使用的分支**：移除計劃但從未實作的 execution modes
2. **State 型別定義不一致**：移除定義但未使用的 execution mode
3. **AI Nodes 共用邏輯提取**：建立 `ai_utils.py` 減少程式碼重複，提升可維護性

## Current State Analysis

### 技術債 #1：AI Brain 未使用的分支

**檔案**：`src/fwauto/nodes/ai_brain.py:83-106`

**問題**：
- `analyze_task_type()` 函數檢查了三個從未被使用的 execution modes：
  - `"fix"` (line 98-100) → 無對應 CLI 命令，無對應 prompt template
  - `"natural"` (line 101-103) → 無對應 CLI 命令，無對應 prompt template
  - `else` 分支返回 `"general_codegen"` (line 105-106) → 無對應 prompt template

**現有 CLI 命令對照**：
- ✅ `build` → 直接執行，不經過 ai_brain
- ✅ `deploy` → 直接執行，不經過 ai_brain
- ✅ `run` → build + deploy，不經過 ai_brain
- ✅ `log` → 進入 log_node，不經過 ai_brain
- ✅ `feat` → 進入 ai_brain_node，使用 `"implement_feature"` 或 `"fix_build_errors"`
- ✅ `chat` → 進入 chat_node，不經過 ai_brain

**實際影響**：
- 這些分支永遠不會被執行（無 CLI 命令觸發）
- 程式碼混淆，暗示有功能但實際不存在
- 如果意外觸發 `else` 分支，會因為 template 缺失而失敗

### 技術債 #2：State 定義不一致

**檔案**：`src/fwauto/state.py:53-56`

**問題**：
- `execution_mode` Literal 定義包含 `"error"`，但從未被使用
- 檢查所有 CLI 命令和 nodes，沒有任何地方設定 `execution_mode = "error"`

**State 定義**：
```python
execution_mode: Literal["build", "deploy", "run", "log", "feat", "chat", "error"] | None
```

**實際使用**：
- ✅ `"build"` - cli.py:83
- ✅ `"deploy"` - cli.py:120
- ✅ `"run"` - cli.py:211
- ✅ `"log"` - cli.py:302
- ✅ `"feat"` - cli.py:353
- ✅ `"chat"` - cli.py:396
- ❌ `"error"` - 未使用

### 技術債 #3：AI Nodes 程式碼重複

**檔案**：`src/fwauto/nodes/ai_brain.py`、`log.py`、`chat.py`

**問題**：
- 三個 AI nodes 都有類似的 `_print_message()` 函數：
  - `ai_brain.py:76-80`
  - `log.py:199-209`
  - `chat.py:191-201`
- 都使用相同的 SDK 配置模式（`ClaudeAgentOptions`）
- 重複的訊息處理邏輯

**影響**：
- 程式碼重複降低可維護性
- 修改輸出格式需要同步更新三個檔案
- 未來新增 AI node 會繼續重複相同邏輯

**改進方向**：
- 建立 `ai_utils.py` 提取共用邏輯
- 保持三個 nodes 獨立（關注點分離）
- 減少重複程式碼，提升可維護性

## Desired End State

清理後的 codebase 應該：

1. ✅ **AI Brain 邏輯精簡**：
   - `analyze_task_type()` 只包含實際使用的分支
   - 所有返回的 task types 都有對應的 prompt templates
   - 清楚明確的程式碼邏輯

2. ✅ **型別定義一致**：
   - `execution_mode` Literal 只包含實際使用的值
   - 型別檢查工具不會發出警告

3. ✅ **共用邏輯統一**：
   - 建立 `src/fwauto/ai_utils.py` 模組
   - 三個 AI nodes 使用統一的訊息輸出函數
   - SDK 配置邏輯可選擇性共用（保持彈性）

4. ✅ **無回歸**：
   - 所有現有功能正常運作
   - 測試全部通過

### 驗證方式

**自動驗證**：
```bash
# 型別檢查
uv run pyright

# 測試
uv run pytest
```

**手動驗證**：
```bash
# 測試所有 CLI 命令
fwauto build
fwauto deploy
fwauto run
fwauto feat "測試功能"
fwauto log "分析日誌"
fwauto chat
```

## What We're NOT Doing

1. ❌ **不建立新的 prompt templates**：不為 `fix_bug`、`natural_language`、`general_codegen` 建立 templates
2. ❌ **不改變 system prompt 策略**：三個 AI nodes 的 system prompt 行為保持不變
3. ❌ **不新增功能**：這是純粹的程式碼清理與重構，不涉及新功能開發
4. ❌ **不改變 workflow routing**：LangGraph workflow 的路由邏輯維持原樣
5. ❌ **不整合 AI nodes**：保持 ai_brain、log、chat 三個獨立 nodes（基於可維護性考量）

## Implementation Approach

採用**漸進式清理與重構**策略：

1. **Phase 1**：清理 ai_brain.py，移除未使用的分支
2. **Phase 2**：清理 state.py，移除未使用的型別定義
3. **Phase 3**：建立 ai_utils.py，提取共用邏輯
4. **Phase 4**：完整驗證與測試

每個 Phase 都獨立可驗證，降低風險。

## 實施流程圖

```mermaid
graph TD
    Start["開始清理"] --> Phase1["Phase 1: 清理 AI Brain"]
    Phase1 --> Test1["驗證: 型別檢查 + 測試"]
    Test1 -->|通過| Phase2["Phase 2: 清理 State 定義"]
    Test1 -->|失敗| Fix1["修復問題"]
    Fix1 --> Test1

    Phase2 --> Test2["驗證: 型別檢查 + 測試"]
    Test2 -->|通過| Phase3["Phase 3: 建立 AI Utils"]
    Test2 -->|失敗| Fix2["修復問題"]
    Fix2 --> Test2

    Phase3 --> Test3["驗證: 型別檢查 + 測試"]
    Test3 -->|通過| Phase4["Phase 4: 完整驗證"]
    Test3 -->|失敗| Fix3["修復問題"]
    Fix3 --> Test3

    Phase4 --> Manual["手動測試所有命令"]
    Manual -->|通過| Complete["清理完成 ✓"]
    Manual -->|失敗| Fix4["修復問題"]
    Fix4 --> Manual

    style Phase1 fill:#fff3e0
    style Phase2 fill:#fff3e0
    style Phase3 fill:#c8e6c9
    style Phase4 fill:#e8f5e9
    style Complete fill:#4caf50,color:#fff
```

## Phase 1: 清理 AI Brain 未使用的分支

### Overview

簡化 `ai_brain.py` 的 `analyze_task_type()` 函數，移除所有未使用的 execution mode 檢查。

### 變更範圍影響圖

```mermaid
graph TD
    AIBrain["ai_brain.py<br/>analyze_task_type()"] -->|修改| Logic["簡化邏輯分支"]
    Logic --> Remove1["移除 'fix' 分支"]
    Logic --> Remove2["移除 'natural' 分支"]
    Logic --> Remove3["移除 else/general_codegen 分支"]

    AIBrain -->|不影響| OtherNodes["其他 Nodes<br/>(log, chat, build, deploy)"]
    AIBrain -->|不影響| CLI["CLI 命令"]
    AIBrain -->|不影響| Graph["LangGraph Workflow"]

    style AIBrain fill:#ffebee
    style Logic fill:#fff3e0
    style OtherNodes fill:#e8f5e9
    style CLI fill:#e8f5e9
    style Graph fill:#e8f5e9
```

### Changes Required

#### 1. 簡化 analyze_task_type() 函數

**File**: `src/fwauto/nodes/ai_brain.py`

**變更前** (lines 83-106):
```python
def analyze_task_type(state: FirmwareState) -> str:
    """
    Analyze current state to determine task type for prompt selection.

    Returns task type that directly corresponds to prompt filename.
    """
    logger = get_logger("nodes.ai_brain")
    logger.debug("🧠 AI Brain: Analyzing task type...")

    if state.get("build_errors") and state.get("build_status") == "error":
        logger.debug("  ✓ Build errors detected → fix_build_errors")
        return "fix_build_errors"
    elif state.get("execution_mode") == "feat":
        logger.debug("  ✓ Feature mode detected → implement_feature")
        return "implement_feature"
    elif state.get("execution_mode") == "fix":
        logger.debug("  ✓ Fix mode detected → fix_bug")
        return "fix_bug"
    elif state.get("execution_mode") == "natural":
        logger.debug("  ✓ Natural language mode → natural_language")
        return "natural_language"
    else:
        logger.debug("  ✓ No specific condition → general_codegen")
        return "general_codegen"
```

**變更後**:
```python
def analyze_task_type(state: FirmwareState) -> str:
    """
    Analyze current state to determine task type for prompt selection.

    Returns task type that directly corresponds to prompt filename.

    Supported task types:
    - fix_build_errors: Auto-fix compilation errors (triggered by build failures)
    - implement_feature: Implement new features (triggered by 'fwauto feat')
    """
    logger = get_logger("nodes.ai_brain")
    logger.debug("🧠 AI Brain: Analyzing task type...")

    if state.get("build_errors") and state.get("build_status") == "error":
        logger.debug("  ✓ Build errors detected → fix_build_errors")
        return "fix_build_errors"
    elif state.get("execution_mode") == "feat":
        logger.debug("  ✓ Feature mode detected → implement_feature")
        return "implement_feature"
    else:
        # This should never happen - all valid paths are handled above
        logger.error(f"  ✗ Unexpected state: execution_mode={state.get('execution_mode')}")
        raise ValueError(
            f"Invalid execution_mode for AI Brain: {state.get('execution_mode')}. "
            "AI Brain only supports 'feat' mode or build error auto-fix."
        )
```

**變更說明**：
1. 移除 `"fix"` 分支（lines 98-100）
2. 移除 `"natural"` 分支（lines 101-103）
3. 移除 `else` 分支的 `"general_codegen"` 返回（lines 104-106）
4. 新增明確的錯誤處理：如果遇到非預期的 execution_mode，拋出 ValueError
5. 新增 docstring 說明支援的 task types

**理由**：
- 移除的分支永遠不會被觸發（無對應 CLI 命令）
- 明確的錯誤處理比靜默失敗更好
- Docstring 讓開發者清楚知道支援哪些 task types

### Success Criteria

#### Code Changes
- [x] 簡化 `analyze_task_type()` 函數（移除未使用的分支）
- [x] 更新對應測試案例（test_fix_mode, test_natural_language_mode, test_default_mode）

#### Automated Verification

- [x] 型別檢查通過：`uv run pyright` (43 個既有錯誤，與此變更無關)
- [x] 現有測試通過：`uv run pytest` (119 passed, 13 skipped)
- [x] 程式碼格式檢查通過：`uv run python -m fwauto.scripts.format --check`
- [x] Lint 檢查通過：`uv run python -m fwauto.scripts.lint`

#### Manual Verification

- [ ] `fwauto feat "實作測試功能"` 正常運作
- [ ] Build 失敗時 auto-fix loop 正常觸發
- [ ] AI Brain log 輸出正確（只顯示兩個分支的 debug 訊息）
- [ ] 如果意外呼叫（測試），應該拋出明確的 ValueError

**Implementation Note**: 完成此階段並通過所有自動驗證後，暫停並等待手動確認測試成功，再進入 Phase 2。

---

## Phase 2: 清理 State 型別定義

### Overview

從 `state.py` 移除未使用的 `"error"` execution mode，確保型別定義與實際使用一致。

### 變更範圍影響圖

```mermaid
graph TD
    State["state.py<br/>FirmwareState"] -->|修改| ExecMode["execution_mode Literal"]
    ExecMode --> Remove["移除 'error'"]

    State -->|不影響| Nodes["所有 Nodes"]
    State -->|不影響| CLI2["CLI 命令"]
    State -->|不影響| Graph2["LangGraph Workflow"]

    style State fill:#ffebee
    style ExecMode fill:#fff3e0
    style Nodes fill:#e8f5e9
    style CLI2 fill:#e8f5e9
    style Graph2 fill:#e8f5e9
```

### Changes Required

#### 1. 更新 execution_mode 型別定義

**File**: `src/fwauto/state.py`

**變更前** (lines 53-56):
```python
execution_mode: Annotated[
    Literal["build", "deploy", "run", "log", "feat", "chat", "error"] | None,
    "Workflow execution mode set by Typer CLI",
]
```

**變更後**:
```python
execution_mode: Annotated[
    Literal["build", "deploy", "run", "log", "feat", "chat"] | None,
    "Workflow execution mode set by Typer CLI",
]
```

**變更說明**：
- 移除 `"error"` 從 Literal 定義
- 保留所有實際使用的 execution modes

**理由**：
- `"error"` 從未被任何 CLI 命令或 node 設定
- 保持型別定義精簡且與實際使用一致

### Success Criteria

#### Automated Verification

- [ ] 型別檢查通過：`uv run pyright`
- [ ] 現有測試通過：`uv run pytest`
- [ ] 程式碼格式檢查通過：`uv run python -m fwauto.scripts.format --check`
- [ ] Lint 檢查通過：`uv run python -m fwauto.scripts.lint`

#### Manual Verification

- [ ] 所有 CLI 命令正常運作（build, deploy, run, log, feat, chat）
- [ ] Nodes 正確設定 execution_mode
- [ ] 型別提示在 IDE 中正確顯示

**Implementation Note**: 完成此階段並通過所有自動驗證後，暫停並等待手動確認測試成功，再進入 Phase 3。

---

## Phase 3: 建立 AI 共用邏輯模組

### Overview

建立 `ai_utils.py` 模組，提取三個 AI nodes 的共用邏輯，減少程式碼重複，提升可維護性。

### 變更範圍影響圖

```mermaid
graph TD
    NewModule["src/fwauto/ai_utils.py<br/>(新建)"] --> Func1["print_ai_message()"]
    NewModule --> Func2["format_ai_response()"]

    AIBrain["ai_brain.py"] -->|使用| Func1
    LogNode["log.py"] -->|使用| Func1
    ChatNode["chat.py"] -->|使用| Func1

    AIBrain -->|移除| Old1["_print_message()"]
    LogNode -->|移除| Old2["_print_message()"]
    ChatNode -->|移除| Old3["_print_message()"]

    style NewModule fill:#c8e6c9
    style Func1 fill:#a5d6a7
    style Func2 fill:#a5d6a7
    style Old1 fill:#ffcdd2
    style Old2 fill:#ffcdd2
    style Old3 fill:#ffcdd2
```

### Changes Required

#### 1. 建立 AI Utils 模組

**File**: `src/fwauto/ai_utils.py` (新建)

**內容**:
```python
"""AI utilities for Claude Code SDK integration.

Shared utilities used across all AI nodes (ai_brain, log, chat) to reduce
code duplication and ensure consistent behavior.
"""

from claude_agent_sdk.types import AssistantMessage, Message, TextBlock


def print_ai_message(message: Message, prefix: str = "🧠") -> None:
    """
    Print AI message to console with consistent formatting.

    Args:
        message: Message from Claude Agent SDK
        prefix: Emoji prefix for the message (default: "🧠")

    Examples:
        >>> print_ai_message(message, prefix="📊")  # For log analysis
        >>> print_ai_message(message, prefix="💬")  # For chat
    """
    if isinstance(message, AssistantMessage):
        for block in message.content:
            if isinstance(block, TextBlock):
                print(f"{prefix} {block.text.strip()}")


def format_ai_response(message: Message) -> str:
    """
    Extract text content from AI message for storage.

    Args:
        message: Message from Claude Agent SDK

    Returns:
        Formatted text content
    """
    if isinstance(message, AssistantMessage):
        texts = []
        for block in message.content:
            if isinstance(block, TextBlock):
                texts.append(block.text.strip())
        return "\n".join(texts)
    return str(message)
```

**設計考量**：
- 保持函數簡單，只處理訊息輸出格式
- 提供 `prefix` 參數讓各 node 自訂 emoji
- 不涉及 SDK 配置邏輯（保持各 node 的特殊性）

#### 2. 重構 ai_brain.py

**File**: `src/fwauto/nodes/ai_brain.py`

**變更前** (lines 76-80):
```python
def _print_message(message: Message) -> None:
    if isinstance(message, AssistantMessage):
        for block in message.content:
            if isinstance(block, TextBlock):
                print(f"🧠 {block.text.strip()}")
```

**變更後**:
```python
# 移除 _print_message() 函數
# 在檔案開頭新增 import
from ..ai_utils import print_ai_message

# 在 run_ai_brain() 中使用
async for message in query(prompt=prompt, options=options):
    logger.debug(f"🧠 AI Brain: {message}")
    print_ai_message(message, prefix="🧠")  # 使用共用函數
    responses.append(str(message))
```

#### 3. 重構 log.py

**File**: `src/fwauto/nodes/log.py`

**變更前** (lines 199-209):
```python
def _print_message(message: Message) -> None:
    """
    Print AI message to console.

    Args:
        message: Message from Claude Agent SDK
    """
    if isinstance(message, AssistantMessage):
        for block in message.content:
            if isinstance(block, TextBlock):
                print(f"🧠 {block.text}")
```

**變更後**:
```python
# 移除 _print_message() 函數
# 在檔案開頭新增 import
from ..ai_utils import print_ai_message

# 在 _run_analysis() 中使用
async for message in query(prompt=prompt, options=options):
    logger.debug(f"🧠 Log Analysis: {message}")
    print_ai_message(message, prefix="📊")  # 使用共用函數
    responses.append(str(message))
```

#### 4. 重構 chat.py

**File**: `src/fwauto/nodes/chat.py`

**變更前** (lines 191-201):
```python
def _print_message(message: Message) -> None:
    """
    Print AI message to console.

    Args:
        message: Message from Claude Agent SDK
    """
    if isinstance(message, AssistantMessage):
        for block in message.content:
            if isinstance(block, TextBlock):
                print(f"🧠 {block.text}")
```

**變更後**:
```python
# 移除 _print_message() 函數
# 在檔案開頭新增 import
from ..ai_utils import print_ai_message

# 在 _run_chat_loop() 中使用
async for msg in client.receive_response():
    print_ai_message(msg, prefix="💬")  # 使用共用函數
```

### Success Criteria

#### Automated Verification

- [ ] 型別檢查通過：`uv run pyright`
- [ ] 現有測試通過：`uv run pytest`
- [ ] 程式碼格式檢查通過：`uv run python -m fwauto.scripts.format --check`
- [ ] Lint 檢查通過：`uv run python -m fwauto.scripts.lint`
- [ ] 新建的 `ai_utils.py` 可正確 import

#### Manual Verification

- [ ] `fwauto feat "測試功能"` 訊息輸出格式正確（🧠 prefix）
- [ ] `fwauto log "分析日誌"` 訊息輸出格式正確（📊 prefix）
- [ ] `fwauto chat` 訊息輸出格式正確（💬 prefix）
- [ ] 所有 AI 功能行為無變化，只是程式碼更整潔

**Implementation Note**: 完成此階段並通過所有自動驗證後，暫停並等待手動確認測試成功，再進入 Phase 4。

---

## Phase 4: 完整驗證與文件更新

### Overview

執行完整的端到端驗證，確保所有變更無回歸，並更新相關文件。

### 驗證流程圖

```mermaid
graph LR
    Start4["Phase 4 開始"] --> Auto["自動化測試套件"]
    Auto --> Manual4["手動功能測試"]
    Manual4 --> Doc["文件更新"]
    Doc --> Complete4["完成 ✓"]

    style Start4 fill:#e3f2fd
    style Auto fill:#fff3e0
    style Manual4 fill:#fff3e0
    style Doc fill:#e8f5e9
    style Complete4 fill:#4caf50,color:#fff
```

### Testing Strategy

#### Unit Tests

現有的單元測試應該全部通過，無需新增測試：

- `tests/test_story_001_state_expansion.py` - State 定義測試
- `tests/test_story_002_nodes_validation.py` - Nodes 邏輯測試
- `tests/test_story_003_workflow_routing.py` - Workflow 路由測試

#### Integration Tests

執行完整的整合測試（如果有的話）：

```bash
uv run pytest tests/integration/ -v -s
```

#### Manual Testing Steps

1. **測試 AI Brain Node（feat 命令）**：
   ```bash
   cd /path/to/fwauto/project
   fwauto feat "實作 LED 閃爍功能"
   ```
   - 驗證：AI 正常執行，無錯誤訊息

2. **測試 Build Auto-Fix Loop**：
   ```bash
   # 故意製造編譯錯誤，然後執行：
   fwauto feat "修復編譯錯誤"
   ```
   - 驗證：AI 自動修復編譯錯誤，最多重試 3 次

3. **測試其他命令**：
   ```bash
   fwauto build
   fwauto deploy
   fwauto run
   fwauto log "分析系統錯誤"
   fwauto chat
   ```
   - 驗證：所有命令正常運作，無回歸

### Success Criteria

#### Automated Verification

- [ ] 所有單元測試通過：`uv run pytest`
- [ ] 型別檢查無錯誤：`uv run pyright`
- [ ] Lint 檢查通過：`uv run python -m fwauto.scripts.lint`
- [ ] 程式碼格式正確：`uv run python -m fwauto.scripts.format --check`

#### Manual Verification

- [ ] `fwauto feat` 命令正常運作
- [ ] Build 失敗時 auto-fix 正常觸發
- [ ] `fwauto build/deploy/run/log/chat` 命令無回歸
- [ ] IDE 型別提示正確顯示
- [ ] 無任何 runtime 錯誤或警告

#### Documentation Updates

- [ ] 更新研究文件（`.ai/prpi/research/2025-11-19-claude-code-sdk-usage-patterns.md`）
  - 移除「技術債務與限制」章節中已修復的項目
  - 更新「架構洞察」章節，反映簡化後的邏輯
- [ ] 更新 CLAUDE.md（如果需要）
  - 確保文件中沒有提到已移除的 execution modes

## Performance Considerations

此次變更為純粹的程式碼清理，對效能無影響：

- ✅ **無效能影響**：移除的程式碼永遠不會被執行
- ✅ **邏輯簡化**：減少不必要的條件檢查（雖然影響極小）

## Migration Notes

此次變更為向後相容：

- ✅ **無需資料遷移**：不涉及資料結構變更
- ✅ **無需配置變更**：user-config.toml 和 project config 無需修改
- ✅ **無 API 變更**：對外 API（CLI 命令）完全不變

## References

- 原始研究文件：`.ai/prpi/research/2025-11-19-claude-code-sdk-usage-patterns.md`
- 相關檔案：
  - `src/fwauto/nodes/ai_brain.py:83-106` - AI Brain task type 分析
  - `src/fwauto/state.py:53-56` - Execution mode 定義
  - `src/fwauto/cli.py` - CLI 命令定義

---

## 總結

此計劃採用 KISS 原則，專注於技術債清理與架構改進：

### Phase 1-2：技術債清理
✅ **簡單**：清理未使用的程式碼分支和型別定義
✅ **安全**：漸進式實施，每個階段獨立驗證
✅ **清晰**：明確的錯誤處理，不靜默失敗

### Phase 3：架構改進
✅ **可維護性優先**：提取共用邏輯，減少程式碼重複
✅ **保持關注點分離**：不整合 AI nodes，保持三個獨立 nodes
✅ **統一輸出格式**：所有 AI nodes 使用一致的訊息輸出

### 預期成果

完成後，codebase 將達到：
- ✅ 更精簡：移除約 50-70 行未使用的程式碼
- ✅ 更一致：統一的型別定義和訊息輸出格式
- ✅ 更易維護：減少重複程式碼，提升可讀性
- ✅ 無回歸：所有現有功能保持正常運作
