diff --git a/CHANGELOG.md b/CHANGELOG.md index c45e52f..1543ed9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,8 @@ ### Changed - 聊天面板(PR Agent)内部重构:2578 行的单文件 `ChatPane.tsx` 按「容器 / 领域组件 / hooks / 工具方法」分层拆分到 `components/chat/`,状态与生命周期、业务动作、时间线归并各自成 hook,展示组件与工具方法独立成文件。对外接口与界面行为保持不变,仅改善可维护性;token 用量 ↑/↓ 的绿红色值一并从内联样式收进设计令牌与样式类。 -- 首启向导内部重构:`OnboardingWizard.tsx` 的四个步骤组件(欢迎 / 平台 / LLM / 完成)拆分到 `onboarding/steps/` 各自成文件,容器只留向导骨架(步骤指示 + 切换 + 导航)。对外接口与界面行为不变。 +- 首启向导内部重构:`OnboardingWizard.tsx` 的四个步骤组件(欢迎 / 平台 / LLM / 完成)拆分到 `steps/` 各自成文件,容器只留向导骨架(步骤指示 + 切换 + 导航)。对外接口与界面行为不变。 +- `components/` 目录按职责重组:扁平堆叠的组件归入三类——`common/`(基础公共 UI)、`layout/`(应用骨架)、`features/`(业务领域:pr / diff / comments / drafts / settings / chat / onboarding),顶层只剩这三个桶。纯文件位置调整 + import 路径改写,无逻辑 / 界面变更。 ### Fixed diff --git a/apps/desktop/src/renderer/src/App.tsx b/apps/desktop/src/renderer/src/App.tsx index 03d7e92..4259f41 100644 --- a/apps/desktop/src/renderer/src/App.tsx +++ b/apps/desktop/src/renderer/src/App.tsx @@ -13,16 +13,16 @@ import type { UpdateCheckResult, } from '@meebox/shared'; import { invoke, subscribe } from './api'; -import { ChatPane, CHAT_MAX_WIDTH, CHAT_MIN_WIDTH } from './components/chat'; +import { ChatPane, CHAT_MAX_WIDTH, CHAT_MIN_WIDTH } from './components/features/chat'; import { wireChatRunStore } from './stores/chat-run-store'; import { wireDraftsStore } from './stores/drafts-store'; import { wireRepoSyncStore } from './stores/repo-sync-store'; -import { MainPane } from './components/MainPane'; -import { OnboardingWizard, type OnboardingResult } from './components/onboarding/OnboardingWizard'; -import { SettingsModal } from './components/SettingsModal'; -import { Sidebar, SIDEBAR_MAX_WIDTH, SIDEBAR_MIN_WIDTH } from './components/Sidebar'; -import { StatusBar } from './components/StatusBar'; -import { TitleBar } from './components/TitleBar'; +import { MainPane } from './components/layout/MainPane'; +import { OnboardingWizard, type OnboardingResult } from './components/features/onboarding/OnboardingWizard'; +import { SettingsModal } from './components/features/settings/SettingsModal'; +import { Sidebar, SIDEBAR_MAX_WIDTH, SIDEBAR_MIN_WIDTH } from './components/layout/Sidebar'; +import { StatusBar } from './components/layout/StatusBar'; +import { TitleBar } from './components/layout/TitleBar'; interface BootstrapState { info: AppInfo; diff --git a/apps/desktop/src/renderer/src/components/Avatar.tsx b/apps/desktop/src/renderer/src/components/common/Avatar.tsx similarity index 99% rename from apps/desktop/src/renderer/src/components/Avatar.tsx rename to apps/desktop/src/renderer/src/components/common/Avatar.tsx index 59e5471..f8fbc1d 100644 --- a/apps/desktop/src/renderer/src/components/Avatar.tsx +++ b/apps/desktop/src/renderer/src/components/common/Avatar.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { invoke } from '../api'; +import { invoke } from '../../api'; interface AvatarProps { connectionId: string; diff --git a/apps/desktop/src/renderer/src/components/BitbucketImage.tsx b/apps/desktop/src/renderer/src/components/common/BitbucketImage.tsx similarity index 99% rename from apps/desktop/src/renderer/src/components/BitbucketImage.tsx rename to apps/desktop/src/renderer/src/components/common/BitbucketImage.tsx index dc5ef78..9ff3dec 100644 --- a/apps/desktop/src/renderer/src/components/BitbucketImage.tsx +++ b/apps/desktop/src/renderer/src/components/common/BitbucketImage.tsx @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react'; import { createPortal } from 'react-dom'; import { useTranslation } from 'react-i18next'; -import { invoke } from '../api'; +import { invoke } from '../../api'; /** * react-markdown 默认 url sanitize 只允许 http/https/mailto/tel 协议, diff --git a/apps/desktop/src/renderer/src/components/ConfirmModal.tsx b/apps/desktop/src/renderer/src/components/common/ConfirmModal.tsx similarity index 100% rename from apps/desktop/src/renderer/src/components/ConfirmModal.tsx rename to apps/desktop/src/renderer/src/components/common/ConfirmModal.tsx diff --git a/apps/desktop/src/renderer/src/components/ErrorBoundary.tsx b/apps/desktop/src/renderer/src/components/common/ErrorBoundary.tsx similarity index 100% rename from apps/desktop/src/renderer/src/components/ErrorBoundary.tsx rename to apps/desktop/src/renderer/src/components/common/ErrorBoundary.tsx diff --git a/apps/desktop/src/renderer/src/components/LlmProviderIcon.tsx b/apps/desktop/src/renderer/src/components/common/LlmProviderIcon.tsx similarity index 100% rename from apps/desktop/src/renderer/src/components/LlmProviderIcon.tsx rename to apps/desktop/src/renderer/src/components/common/LlmProviderIcon.tsx diff --git a/apps/desktop/src/renderer/src/components/Loading.tsx b/apps/desktop/src/renderer/src/components/common/Loading.tsx similarity index 100% rename from apps/desktop/src/renderer/src/components/Loading.tsx rename to apps/desktop/src/renderer/src/components/common/Loading.tsx diff --git a/apps/desktop/src/renderer/src/components/MermaidDiagram.tsx b/apps/desktop/src/renderer/src/components/common/MermaidDiagram.tsx similarity index 100% rename from apps/desktop/src/renderer/src/components/MermaidDiagram.tsx rename to apps/desktop/src/renderer/src/components/common/MermaidDiagram.tsx diff --git a/apps/desktop/src/renderer/src/components/PlatformIcon.tsx b/apps/desktop/src/renderer/src/components/common/PlatformIcon.tsx similarity index 100% rename from apps/desktop/src/renderer/src/components/PlatformIcon.tsx rename to apps/desktop/src/renderer/src/components/common/PlatformIcon.tsx diff --git a/apps/desktop/src/renderer/src/components/icons.tsx b/apps/desktop/src/renderer/src/components/common/icons.tsx similarity index 100% rename from apps/desktop/src/renderer/src/components/icons.tsx rename to apps/desktop/src/renderer/src/components/common/icons.tsx diff --git a/apps/desktop/src/renderer/src/components/markdownMermaid.tsx b/apps/desktop/src/renderer/src/components/common/markdownMermaid.tsx similarity index 100% rename from apps/desktop/src/renderer/src/components/markdownMermaid.tsx rename to apps/desktop/src/renderer/src/components/common/markdownMermaid.tsx diff --git a/apps/desktop/src/renderer/src/components/chat/ChatPane.tsx b/apps/desktop/src/renderer/src/components/features/chat/ChatPane.tsx similarity index 98% rename from apps/desktop/src/renderer/src/components/chat/ChatPane.tsx rename to apps/desktop/src/renderer/src/components/features/chat/ChatPane.tsx index d6ac6c6..8fc8c40 100644 --- a/apps/desktop/src/renderer/src/components/chat/ChatPane.tsx +++ b/apps/desktop/src/renderer/src/components/features/chat/ChatPane.tsx @@ -1,11 +1,11 @@ import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import type { LocalPrStatus, PrAgentStatus, StoredPullRequest } from '@meebox/shared'; -import { ChatIcon, TrashIcon } from '../icons'; -import { ConfirmModal } from '../ConfirmModal'; -import { PaneLoading } from '../Loading'; -import { useChatRunStore } from '../../stores/chat-run-store'; -import { useDraftsForPr } from '../../stores/drafts-store'; +import { ChatIcon, TrashIcon } from '../../common/icons'; +import { ConfirmModal } from '../../common/ConfirmModal'; +import { PaneLoading } from '../../common/Loading'; +import { useChatRunStore } from '../../../stores/chat-run-store'; +import { useDraftsForPr } from '../../../stores/drafts-store'; import { CHAT_MAX_WIDTH, CHAT_MIN_WIDTH } from './constants'; import { useChatSession } from './hooks/useChatSession'; import { useChatActions } from './hooks/useChatActions'; diff --git a/apps/desktop/src/renderer/src/components/chat/commands.ts b/apps/desktop/src/renderer/src/components/features/chat/commands.ts similarity index 100% rename from apps/desktop/src/renderer/src/components/chat/commands.ts rename to apps/desktop/src/renderer/src/components/features/chat/commands.ts diff --git a/apps/desktop/src/renderer/src/components/chat/components/AgentStep.tsx b/apps/desktop/src/renderer/src/components/features/chat/components/AgentStep.tsx similarity index 98% rename from apps/desktop/src/renderer/src/components/chat/components/AgentStep.tsx rename to apps/desktop/src/renderer/src/components/features/chat/components/AgentStep.tsx index 1aa1c7e..1c3c8d6 100644 --- a/apps/desktop/src/renderer/src/components/chat/components/AgentStep.tsx +++ b/apps/desktop/src/renderer/src/components/features/chat/components/AgentStep.tsx @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import type { AgentStep } from '@meebox/shared'; -import { RobotIcon } from '../../icons'; +import { RobotIcon } from '../../../common/icons'; import { formatElapsed, formatTokens } from '../utils/format'; import { Spinner } from './shared'; diff --git a/apps/desktop/src/renderer/src/components/chat/components/ChatEmpty.tsx b/apps/desktop/src/renderer/src/components/features/chat/components/ChatEmpty.tsx similarity index 98% rename from apps/desktop/src/renderer/src/components/chat/components/ChatEmpty.tsx rename to apps/desktop/src/renderer/src/components/features/chat/components/ChatEmpty.tsx index 7be5fd1..f3d351d 100644 --- a/apps/desktop/src/renderer/src/components/chat/components/ChatEmpty.tsx +++ b/apps/desktop/src/renderer/src/components/features/chat/components/ChatEmpty.tsx @@ -1,6 +1,6 @@ import { useTranslation } from 'react-i18next'; import type { PrAgentStatus, StoredPullRequest } from '@meebox/shared'; -import { ChatIcon } from '../../icons'; +import { ChatIcon } from '../../../common/icons'; import { Bullet } from './shared'; export function ChatEmpty({ diff --git a/apps/desktop/src/renderer/src/components/chat/components/ChatInputBar.tsx b/apps/desktop/src/renderer/src/components/features/chat/components/ChatInputBar.tsx similarity index 99% rename from apps/desktop/src/renderer/src/components/chat/components/ChatInputBar.tsx rename to apps/desktop/src/renderer/src/components/features/chat/components/ChatInputBar.tsx index adffc79..2616b37 100644 --- a/apps/desktop/src/renderer/src/components/chat/components/ChatInputBar.tsx +++ b/apps/desktop/src/renderer/src/components/features/chat/components/ChatInputBar.tsx @@ -1,7 +1,7 @@ import { useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import type { LocalPrStatus, PrAgentStatus, ReviewRunTool, StoredPullRequest } from '@meebox/shared'; -import { AutoReviewIcon, SendIcon, StopIcon } from '../../icons'; +import { AutoReviewIcon, SendIcon, StopIcon } from '../../../common/icons'; import { COMMANDS, type CommandSpec } from '../commands'; import { loadChatHistory, pushChatHistory } from '../utils/chat-history'; diff --git a/apps/desktop/src/renderer/src/components/chat/components/ConversationMessage.tsx b/apps/desktop/src/renderer/src/components/features/chat/components/ConversationMessage.tsx similarity index 97% rename from apps/desktop/src/renderer/src/components/chat/components/ConversationMessage.tsx rename to apps/desktop/src/renderer/src/components/features/chat/components/ConversationMessage.tsx index 35747db..54a06e6 100644 --- a/apps/desktop/src/renderer/src/components/chat/components/ConversationMessage.tsx +++ b/apps/desktop/src/renderer/src/components/features/chat/components/ConversationMessage.tsx @@ -1,6 +1,6 @@ import { useTranslation } from 'react-i18next'; import type { AgentMessage } from '@meebox/shared'; -import { ChatIcon } from '../../icons'; +import { ChatIcon } from '../../../common/icons'; import { VERDICT_LABEL_KEY } from '../constants'; import { Md } from './shared'; diff --git a/apps/desktop/src/renderer/src/components/chat/components/FindingCard.tsx b/apps/desktop/src/renderer/src/components/features/chat/components/FindingCard.tsx similarity index 98% rename from apps/desktop/src/renderer/src/components/chat/components/FindingCard.tsx rename to apps/desktop/src/renderer/src/components/features/chat/components/FindingCard.tsx index 8f9161f..e8d325b 100644 --- a/apps/desktop/src/renderer/src/components/chat/components/FindingCard.tsx +++ b/apps/desktop/src/renderer/src/components/features/chat/components/FindingCard.tsx @@ -4,10 +4,10 @@ import ReactMarkdown from 'react-markdown'; import remarkBreaks from 'remark-breaks'; import remarkGfm from 'remark-gfm'; import type { Finding, PrDocSectionKey, ReviewDraft } from '@meebox/shared'; -import { ChevronIcon } from '../../icons'; -import { mermaidComponents, walkthroughMdComponents } from '../../markdownMermaid'; -import { REMOTE_REHYPE_PLUGINS } from '../../../markdown'; -import { translatePrAgentLabels } from '../../../utils/translate-pr-agent'; +import { ChevronIcon } from '../../../common/icons'; +import { mermaidComponents, walkthroughMdComponents } from '../../../common/markdownMermaid'; +import { REMOTE_REHYPE_PLUGINS } from '../../../../markdown'; +import { translatePrAgentLabels } from '../../../../utils/translate-pr-agent'; import { pillStyle, sectionLabel, diff --git a/apps/desktop/src/renderer/src/components/chat/components/QueuedView.tsx b/apps/desktop/src/renderer/src/components/features/chat/components/QueuedView.tsx similarity index 96% rename from apps/desktop/src/renderer/src/components/chat/components/QueuedView.tsx rename to apps/desktop/src/renderer/src/components/features/chat/components/QueuedView.tsx index 17fd2b4..2319e28 100644 --- a/apps/desktop/src/renderer/src/components/chat/components/QueuedView.tsx +++ b/apps/desktop/src/renderer/src/components/features/chat/components/QueuedView.tsx @@ -1,7 +1,7 @@ import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import type { ReviewRunTool } from '@meebox/shared'; -import { CloseIcon } from '../../icons'; +import { CloseIcon } from '../../../common/icons'; import { AskQuestion } from './shared'; /** diff --git a/apps/desktop/src/renderer/src/components/chat/components/RulePreviewModal.tsx b/apps/desktop/src/renderer/src/components/features/chat/components/RulePreviewModal.tsx similarity index 92% rename from apps/desktop/src/renderer/src/components/chat/components/RulePreviewModal.tsx rename to apps/desktop/src/renderer/src/components/features/chat/components/RulePreviewModal.tsx index 2ea7fe0..ce57d3b 100644 --- a/apps/desktop/src/renderer/src/components/chat/components/RulePreviewModal.tsx +++ b/apps/desktop/src/renderer/src/components/features/chat/components/RulePreviewModal.tsx @@ -2,8 +2,8 @@ import { useTranslation } from 'react-i18next'; import ReactMarkdown from 'react-markdown'; import remarkBreaks from 'remark-breaks'; import remarkGfm from 'remark-gfm'; -import { mermaidComponents } from '../../markdownMermaid'; -import { REMOTE_REHYPE_PLUGINS } from '../../../markdown'; +import { mermaidComponents } from '../../../common/markdownMermaid'; +import { REMOTE_REHYPE_PLUGINS } from '../../../../markdown'; import type { MatchedRule } from '../types'; export function RulePreviewModal({ diff --git a/apps/desktop/src/renderer/src/components/chat/components/RunResultView.tsx b/apps/desktop/src/renderer/src/components/features/chat/components/RunResultView.tsx similarity index 99% rename from apps/desktop/src/renderer/src/components/chat/components/RunResultView.tsx rename to apps/desktop/src/renderer/src/components/features/chat/components/RunResultView.tsx index 81717f5..83e7f25 100644 --- a/apps/desktop/src/renderer/src/components/chat/components/RunResultView.tsx +++ b/apps/desktop/src/renderer/src/components/features/chat/components/RunResultView.tsx @@ -1,7 +1,7 @@ import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import type { Finding, ReviewDraft, ReviewRun } from '@meebox/shared'; -import { RetryIcon } from '../../icons'; +import { RetryIcon } from '../../../common/icons'; import { orderFindings } from '../utils/findings'; import { formatStartTime, formatTokens, runStatusLabel } from '../utils/format'; import { extractTokenUsage, type TokenUsage } from '../utils/tokens'; diff --git a/apps/desktop/src/renderer/src/components/chat/components/RunningView.tsx b/apps/desktop/src/renderer/src/components/features/chat/components/RunningView.tsx similarity index 100% rename from apps/desktop/src/renderer/src/components/chat/components/RunningView.tsx rename to apps/desktop/src/renderer/src/components/features/chat/components/RunningView.tsx diff --git a/apps/desktop/src/renderer/src/components/chat/components/shared.tsx b/apps/desktop/src/renderer/src/components/features/chat/components/shared.tsx similarity index 92% rename from apps/desktop/src/renderer/src/components/chat/components/shared.tsx rename to apps/desktop/src/renderer/src/components/features/chat/components/shared.tsx index e6a2b2a..1a4b173 100644 --- a/apps/desktop/src/renderer/src/components/chat/components/shared.tsx +++ b/apps/desktop/src/renderer/src/components/features/chat/components/shared.tsx @@ -3,10 +3,10 @@ import { useTranslation } from 'react-i18next'; import ReactMarkdown from 'react-markdown'; import remarkBreaks from 'remark-breaks'; import remarkGfm from 'remark-gfm'; -import { QuestionIcon } from '../../icons'; -import { mermaidComponents } from '../../markdownMermaid'; -import { REMOTE_REHYPE_PLUGINS } from '../../../markdown'; -import { parseAnsi, segmentStyle } from '../../../utils/ansi'; +import { QuestionIcon } from '../../../common/icons'; +import { mermaidComponents } from '../../../common/markdownMermaid'; +import { REMOTE_REHYPE_PLUGINS } from '../../../../markdown'; +import { parseAnsi, segmentStyle } from '../../../../utils/ansi'; export function Spinner() { return