diff --git a/README.md b/README.md index 84c409c..05dd214 100644 --- a/README.md +++ b/README.md @@ -867,6 +867,12 @@ ow + toggle 시각 언어로 통일했습니다. - 현재 `claw-code` 대비 추정 진척율은 핵심 엔진 `88%`, 채팅 메인 UI `94%`, Cowork/Code 상태 UX `89%`, 내부 설정 연결 `88%`, 전체 AX Agent `92%` 정도입니다. - 검증: `dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\` 경고 0 / 오류 0 - 업데이트: 2026-04-05 18:30 (KST) +- Cowork/Code 보조 상태 레이어도 다시 최소 노출 기준으로 정리했습니다. [ChatWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml) 에서 `ConversationStatusStrip`, `ConversationQuickStrip`, `AgentProgressBar`, `RuntimeActivityBadge`, `ExecutionLog`, `SubAgentIndicator`, `StatusElapsed`, `StatusTokens`의 패딩·폰트·간격을 한 단계 더 줄여 상단/하단 보조 정보가 transcript보다 먼저 튀지 않도록 조정했습니다. +- [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)의 `ShowTaskSummaryPopup()`은 필터 칩과 과한 대시보드형 액션을 걷어내고, 최근 실행도 1건 중심의 요약 카드만 남기도록 줄였습니다. 활성/최근 작업 카드는 각각 `3/2`개만 노출하도록 낮췄고, 배경색도 팝업 테마와 같은 축을 쓰게 맞췄습니다. +- 같은 변경에서 `BuildHookSummaryCard(...)`, `BuildActiveBackgroundSummaryCard(...)`, `BuildRecentBackgroundJobCard(...)`, `AddTaskSummaryObservabilitySections(...)`를 더 보수적으로 정리해 훅/백그라운드/권한 이력이 기본 팝업을 점유하지 않게 했습니다. 백그라운드 작업은 현재 활성 상태만 짧게 요약하고, 세부 이동/필터 버튼은 대부분 제거해 `claw-code`처럼 “필요할 때만 보이는 진단 패널”에 가깝게 맞췄습니다. +- 현재 `claw-code` 대비 추정 진척율은 핵심 엔진 `88%`, 채팅 메인 UI `95%`, Cowork/Code 상태 UX `91%`, 내부 설정 연결 `88%`, 전체 AX Agent `93%` 정도입니다. +- 검증: `dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\` 경고 0 / 오류 0 +- 업데이트: 2026-04-05 18:40 (KST) --- diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index 396c56c..ec75a57 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -4627,3 +4627,9 @@ ow + toggle ?쒓컖 ?몄뼱濡??ㅼ떆 ?뺣젹?덈떎. - 현재 `claw-code` 대비 추정 진척율은 핵심 엔진 `88%`, 채팅 메인 UI `94%`, Cowork/Code 상태 UX `89%`, 내부 설정 연결 `88%`, 전체 AX Agent `92%` 정도로 봅니다. - 검증: `dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\verify\ -p:IntermediateOutputPath=obj\verify\` 경고 0 / 오류 0 - 업데이트: 2026-04-05 18:30 (KST) +- Cowork/Code 보조 상태 레이어를 추가로 축소했습니다. [ChatWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml)의 `ConversationStatusStrip`, `ConversationQuickStrip`, `AgentProgressBar`, `RuntimeActivityBadge`, `ExecutionLog`, `SubAgentIndicator`, `StatusElapsed`, `StatusTokens`는 패딩·폰트·간격을 한 단계 더 낮춰 transcript 우선 구조를 해치지 않도록 정리했습니다. +- [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)의 `ShowTaskSummaryPopup()`은 `claw-code` 기준 최소 노출 방향으로 다시 구성했습니다. 필터 칩 행을 제거했고, 최근 실행은 1건 기준의 마지막 실행 카드만 남기며, 활성/최근 작업 카드도 각각 `3/2`개만 노출하게 줄였습니다. +- 같은 파일의 `BuildHookSummaryCard(...)`, `BuildActiveBackgroundSummaryCard(...)`, `BuildRecentBackgroundJobCard(...)`는 라운드, 패딩, 타이포 밀도를 함께 낮추고, 배경/훅 카드의 이동·필터 액션을 대부분 제거해 “상태 대시보드”보다 “짧은 진단 카드” 쪽으로 맞췄습니다. `AddTaskSummaryObservabilitySections(...)`는 기본 팝업에서 권한/백그라운드 현재 상태만 남기고 권한 이력/훅 이력/최근 백그라운드 이력을 기본 노출에서 제외했습니다. +- 현재 `claw-code` 대비 추정 진척율은 핵심 엔진 `88%`, 채팅 메인 UI `95%`, Cowork/Code 상태 UX `91%`, 내부 설정 연결 `88%`, 전체 AX Agent `93%` 정도로 봅니다. +- 검증: `dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\verify\ -p:IntermediateOutputPath=obj\verify\` 경고 0 / 오류 0 +- 업데이트: 2026-04-05 18:40 (KST) diff --git a/src/AxCopilot/Views/ChatWindow.xaml b/src/AxCopilot/Views/ChatWindow.xaml index 41ea935..f80d657 100644 --- a/src/AxCopilot/Views/ChatWindow.xaml +++ b/src/AxCopilot/Views/ChatWindow.xaml @@ -865,31 +865,31 @@ KeyDown="ChatTitleEdit_KeyDown"/> + Margin="0,0,0,0"> @@ -914,7 +914,7 @@ + Padding="7,1,7,1"> @@ -2297,15 +2297,15 @@ - + @@ -2318,28 +2318,28 @@ Cursor="Hand" MouseLeftButtonUp="RuntimeTaskSummary_Click"/> - + @@ -2355,10 +2355,10 @@ VerticalAlignment="Center"/> - - + diff --git a/src/AxCopilot/Views/ChatWindow.xaml.cs b/src/AxCopilot/Views/ChatWindow.xaml.cs index 7c2325d..69b7793 100644 --- a/src/AxCopilot/Views/ChatWindow.xaml.cs +++ b/src/AxCopilot/Views/ChatWindow.xaml.cs @@ -20148,22 +20148,11 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi }); panel.Children.Add(new TextBlock { - Text = "현재 실행/권한/작업 흐름", - FontSize = 8.75, + Text = "현재 상태 요약", + FontSize = 8.5, Foreground = secondaryText, - Margin = new Thickness(8, 0, 8, 3), + Margin = new Thickness(8, 0, 8, 5), }); - var taskFilterRow = new WrapPanel - { - Margin = new Thickness(6, 0, 6, 6), - }; - taskFilterRow.Children.Add(CreateTaskSummaryFilterChip("all", "전체")); - taskFilterRow.Children.Add(CreateTaskSummaryFilterChip("permission", "권한")); - taskFilterRow.Children.Add(CreateTaskSummaryFilterChip("queue", "대기")); - taskFilterRow.Children.Add(CreateTaskSummaryFilterChip("tool", "도구")); - taskFilterRow.Children.Add(CreateTaskSummaryFilterChip("subagent", "서브")); - taskFilterRow.Children.Add(CreateTaskSummaryFilterChip("hook", "훅")); - panel.Children.Add(taskFilterRow); ChatConversation? currentConversation; lock (_convLock) currentConversation = _currentConversation; @@ -20211,55 +20200,13 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi panel.Children.Add(currentRun); } - var recentAgentRuns = _appState.GetRecentAgentRuns(2); + var recentAgentRuns = _appState.GetRecentAgentRuns(1); if (recentAgentRuns.Count > 0) { - var latestFailedRun = _appState.GetLatestFailedRun(); - if (latestFailedRun != null) - { - panel.Children.Add(new Border - { - Background = BrushFromHex("#FEF2F2"), - BorderBrush = BrushFromHex("#FECACA"), - BorderThickness = new Thickness(1), - CornerRadius = new CornerRadius(8), - Padding = new Thickness(8, 6, 8, 6), - Margin = new Thickness(6, 0, 6, 6), - Child = new StackPanel - { - Children = - { - new TextBlock - { - Text = $"최근 실패 · run {ShortRunId(latestFailedRun.RunId)}", - FontWeight = FontWeights.SemiBold, - Foreground = BrushFromHex("#991B1B"), - FontSize = 9.75, - }, - new TextBlock - { - Text = $"{latestFailedRun.UpdatedAt:HH:mm:ss} · step {latestFailedRun.LastIteration}", - Margin = new Thickness(0, 2, 0, 0), - Foreground = BrushFromHex("#B45309"), - FontSize = 8.75, - }, - new TextBlock - { - Text = string.IsNullOrWhiteSpace(latestFailedRun.Summary) ? "요약 없음" : latestFailedRun.Summary, - Margin = new Thickness(0, 3, 0, 0), - TextWrapping = TextWrapping.Wrap, - Foreground = secondaryText, - FontSize = 8.9, - } - } - } - }); - } - panel.Children.Add(new TextBlock { - Text = "최근 실행", - FontSize = 9.5, + Text = "마지막 실행", + FontSize = 9, FontWeight = FontWeights.SemiBold, Foreground = Brushes.DimGray, Margin = new Thickness(8, 0, 8, 2), @@ -20267,8 +20214,8 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi foreach (var run in recentAgentRuns) { - var runEvents = GetExecutionEventsForRun(run.RunId); - var runFilePaths = GetExecutionEventFilePaths(run.RunId); + var runEvents = GetExecutionEventsForRun(run.RunId, 1); + var runFilePaths = GetExecutionEventFilePaths(run.RunId, 1); var runDisplay = _appState.GetRunDisplay(run); var runCardStack = new StackPanel { @@ -20279,22 +20226,22 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi Text = runDisplay.HeaderText, FontWeight = FontWeights.SemiBold, Foreground = GetRunStatusBrush(run.Status), - FontSize = 9.75, + FontSize = 9.5, }, new TextBlock { Text = runDisplay.MetaText, - Margin = new Thickness(0, 2, 0, 0), + Margin = new Thickness(0, 1, 0, 0), Foreground = secondaryText, - FontSize = 8.75, + FontSize = 8.25, }, new TextBlock { - Text = TruncateForStatus(runDisplay.SummaryText, 140), - Margin = new Thickness(0, 2, 0, 0), + Text = TruncateForStatus(runDisplay.SummaryText, 92), + Margin = new Thickness(0, 1.5, 0, 0), TextWrapping = TextWrapping.Wrap, Foreground = secondaryText, - FontSize = 8.9, + FontSize = 8.5, } } }; @@ -20305,7 +20252,7 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi activitySummary.Children.Add(new TextBlock { Text = $"로그 {runEvents.Count} · 파일 {runFilePaths.Count}", - FontSize = 8.4, + FontSize = 8, Foreground = secondaryText, }); @@ -20328,9 +20275,9 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi Background = BrushFromHex("#F8FAFC"), BorderBrush = BrushFromHex("#E2E8F0"), BorderThickness = new Thickness(1), - CornerRadius = new CornerRadius(8), - Padding = new Thickness(7, 5, 7, 5), - Margin = new Thickness(0, 6, 0, 0), + CornerRadius = new CornerRadius(7), + Padding = new Thickness(6, 4, 6, 4), + Margin = new Thickness(0, 5, 0, 0), Child = activitySummary }); } @@ -20368,64 +20315,21 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi panel.Children.Add(new Border { - Background = Brushes.White, + Background = popupBackground, BorderBrush = BrushFromHex("#E5E7EB"), BorderThickness = new Thickness(1), - CornerRadius = new CornerRadius(8), - Padding = new Thickness(8, 5, 8, 5), - Margin = new Thickness(6, 0, 6, 5), + CornerRadius = new CornerRadius(7), + Padding = new Thickness(7, 5, 7, 5), + Margin = new Thickness(6, 0, 6, 4), Child = runCardStack }); } - - if (_appState.GetLatestFailedRun() != null - && CanRetryCurrentConversation()) - { - var actionsPanel = new StackPanel - { - Orientation = Orientation.Horizontal, - Margin = new Thickness(6, 1, 6, 6), - }; - - var retryButton = CreateTaskSummaryActionButton( - "마지막 요청 다시 시도", - "#EEF2FF", - "#C7D2FE", - "#3730A3", - (_, _) => - { - _taskSummaryPopup?.SetCurrentValue(Popup.IsOpenProperty, false); - RetryLastUserMessageFromConversation(); - }); - actionsPanel.Children.Add(retryButton); - - if (_appState.ActiveTasks.Count > 0) - { - var runningFilterButton = CreateTaskSummaryActionButton( - "진행 중 대화만 보기", - "#DBEAFE", - "#93C5FD", - "#1D4ED8", - (_, _) => - { - _runningOnlyFilter = true; - UpdateConversationRunningFilterUi(); - PersistConversationListPreferences(); - RefreshConversationList(); - _taskSummaryPopup?.SetCurrentValue(Popup.IsOpenProperty, false); - }, - trailingMargin: false); - runningFilterButton.Margin = new Thickness(2, 0, 0, 0); - actionsPanel.Children.Add(runningFilterButton); - } - panel.Children.Add(actionsPanel); - } } - foreach (var task in FilterTaskSummaryItems(_appState.ActiveTasks).Take(6)) + foreach (var task in FilterTaskSummaryItems(_appState.ActiveTasks).Take(3)) panel.Children.Add(BuildTaskSummaryCard(task, active: true)); - foreach (var task in FilterTaskSummaryItems(_appState.RecentTasks).Take(6)) + foreach (var task in FilterTaskSummaryItems(_appState.RecentTasks).Take(2)) panel.Children.Add(BuildTaskSummaryCard(task, active: false)); if (!FilterTaskSummaryItems(_appState.ActiveTasks).Any() && !FilterTaskSummaryItems(_appState.RecentTasks).Any()) @@ -21396,15 +21300,15 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi { Text = "\uE756", FontFamily = new FontFamily("Segoe MDL2 Assets"), - FontSize = 10, + FontSize = 9, Foreground = hook.Success ? BrushFromHex("#334155") : BrushFromHex("#991B1B"), - Margin = new Thickness(0, 0, 5, 0), + Margin = new Thickness(0, 0, 4, 0), VerticalAlignment = VerticalAlignment.Center, }, new TextBlock { - Text = "훅 이벤트", - FontSize = 10, + Text = "훅", + FontSize = 9, FontWeight = FontWeights.SemiBold, Foreground = hook.Success ? BrushFromHex("#334155") : BrushFromHex("#991B1B"), } @@ -21413,7 +21317,7 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi hookCardStack.Children.Add(new TextBlock { Text = _appState.FormatHookEventLine(hook), - FontSize = 9.5, + FontSize = 8.75, TextWrapping = TextWrapping.Wrap, Foreground = hook.Success ? secondaryText : BrushFromHex("#991B1B"), }); @@ -21460,9 +21364,9 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi Background = hook.Success ? BrushFromHex("#F8FAFC") : BrushFromHex("#FEF2F2"), BorderBrush = hook.Success ? BrushFromHex("#E2E8F0") : BrushFromHex("#FECACA"), BorderThickness = new Thickness(1), - CornerRadius = new CornerRadius(8), - Padding = new Thickness(8, 5, 8, 5), - Margin = new Thickness(6, 0, 6, 4), + CornerRadius = new CornerRadius(7), + Padding = new Thickness(7, 4, 7, 4), + Margin = new Thickness(6, 0, 6, 3), Child = hookCardStack }; } @@ -21480,15 +21384,15 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi { Text = "\uE9F9", FontFamily = new FontFamily("Segoe MDL2 Assets"), - FontSize = 10, + FontSize = 9, Foreground = BrushFromHex("#1D4ED8"), - Margin = new Thickness(0, 0, 5, 0), + Margin = new Thickness(0, 0, 4, 0), VerticalAlignment = VerticalAlignment.Center, }, new TextBlock { - Text = $"실행 중인 백그라운드 작업 {activeBackgroundCount}개", - FontSize = 10, + Text = $"백그라운드 {activeBackgroundCount}", + FontSize = 9, Foreground = BrushFromHex("#1D4ED8"), FontWeight = FontWeights.SemiBold, } @@ -21499,45 +21403,22 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi { activeBackgroundStack.Children.Add(new TextBlock { - Text = $"· {job.Title} · {TruncateForStatus(job.Summary, 52)}", - Margin = new Thickness(0, 3, 0, 0), - FontSize = 9.5, + Text = $"· {job.Title} · {TruncateForStatus(job.Summary, 40)}", + Margin = new Thickness(0, 2, 0, 0), + FontSize = 8.75, Foreground = secondaryText, TextWrapping = TextWrapping.Wrap, }); } - var activeActionRow = new WrapPanel - { - Margin = new Thickness(0, 6, 0, 0), - }; - - var runningFilterButton = CreateTaskSummaryActionButton( - "진행 중 대화만 보기", - "#DBEAFE", - "#93C5FD", - "#1D4ED8", - (_, _) => ShowRunningConversationsOnly()); - activeActionRow.Children.Add(runningFilterButton); - - var subTaskButton = CreateTaskSummaryActionButton( - "서브 작업만 보기", - "#F8FAFC", - "#CBD5E1", - "#334155", - (_, _) => ShowSubAgentTasksOnly(), - trailingMargin: false); - activeActionRow.Children.Add(subTaskButton); - activeBackgroundStack.Children.Add(activeActionRow); - return new Border { Background = BrushFromHex("#EFF6FF"), BorderBrush = BrushFromHex("#BFDBFE"), BorderThickness = new Thickness(1), - CornerRadius = new CornerRadius(8), - Padding = new Thickness(8, 5, 8, 5), - Margin = new Thickness(6, 0, 6, 5), + CornerRadius = new CornerRadius(7), + Padding = new Thickness(7, 4, 7, 4), + Margin = new Thickness(6, 0, 6, 4), Child = activeBackgroundStack }; } @@ -21557,15 +21438,15 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi { Text = "\uE823", FontFamily = new FontFamily("Segoe MDL2 Assets"), - FontSize = 10, + FontSize = 9, Foreground = isFailed ? BrushFromHex("#991B1B") : BrushFromHex("#334155"), - Margin = new Thickness(0, 0, 5, 0), + Margin = new Thickness(0, 0, 4, 0), VerticalAlignment = VerticalAlignment.Center, }, new TextBlock { Text = $"{job.Title} · {GetTaskStatusLabel(job.Status)}", - FontSize = 10, + FontSize = 9, FontWeight = FontWeights.SemiBold, Foreground = isFailed ? BrushFromHex("#991B1B") : BrushFromHex("#334155"), } @@ -21573,43 +21454,18 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi }); jobCardStack.Children.Add(new TextBlock { - Text = $"{job.UpdatedAt:HH:mm:ss} · {TruncateForStatus(job.Summary, 72)}", - FontSize = 9.5, + Text = $"{job.UpdatedAt:HH:mm:ss} · {TruncateForStatus(job.Summary, 48)}", + FontSize = 8.75, TextWrapping = TextWrapping.Wrap, Foreground = isFailed ? BrushFromHex("#991B1B") : secondaryText, }); - var jobActionRow = new WrapPanel - { - Margin = new Thickness(0, 6, 0, 0), - }; - - var focusButton = CreateTaskSummaryActionButton( - "이 대화로 이동", - "#F8FAFC", - "#CBD5E1", - "#334155", - (_, _) => - { - _taskSummaryPopup?.SetCurrentValue(Popup.IsOpenProperty, false); - FocusCurrentConversation(); - }); - jobActionRow.Children.Add(focusButton); - - var subagentOnlyButton = CreateTaskSummaryActionButton( - "서브 작업만 보기", - "#F8FAFC", - "#CBD5E1", - "#334155", - (_, _) => ShowSubAgentTasksOnly()); - jobActionRow.Children.Add(subagentOnlyButton); - if (string.Equals(job.Status, "failed", StringComparison.OrdinalIgnoreCase) && CanRetryCurrentConversation()) { var retryBackgroundButton = CreateTaskSummaryActionButton( - "이 작업 다시 시도", + "다시 시도", "#FEF2F2", "#FCA5A5", "#991B1B", @@ -21619,11 +21475,10 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi RetryLastUserMessageFromConversation(); }, trailingMargin: false); - jobActionRow.Children.Add(retryBackgroundButton); + retryBackgroundButton.Margin = new Thickness(0, 5, 0, 0); + jobCardStack.Children.Add(retryBackgroundButton); } - jobCardStack.Children.Add(jobActionRow); - return new Border { Background = string.Equals(job.Status, "failed", StringComparison.OrdinalIgnoreCase) @@ -21633,9 +21488,9 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi ? BrushFromHex("#FECACA") : BrushFromHex("#E2E8F0"), BorderThickness = new Thickness(1), - CornerRadius = new CornerRadius(8), - Padding = new Thickness(8, 5, 8, 5), - Margin = new Thickness(6, 0, 6, 4), + CornerRadius = new CornerRadius(7), + Padding = new Thickness(7, 4, 7, 4), + Margin = new Thickness(6, 0, 6, 3), Child = jobCardStack }; } @@ -21807,33 +21662,15 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi private void AddTaskSummaryBackgroundSection(StackPanel panel) { var activeBackgroundJobs = _appState.GetActiveBackgroundJobs(2); - var recentBackgroundJobs = _appState.GetRecentBackgroundJobs(2); var activeBackgroundCount = _appState.GetBackgroundJobSummary().ActiveCount; if (activeBackgroundCount > 0) panel.Children.Add(BuildActiveBackgroundSummaryCard(activeBackgroundJobs, activeBackgroundCount)); - - if (recentBackgroundJobs.Count == 0) - return; - - panel.Children.Add(new TextBlock - { - Text = "최근 백그라운드 작업", - FontSize = 11, - FontWeight = FontWeights.SemiBold, - Foreground = Brushes.DimGray, - Margin = new Thickness(10, 0, 10, 4), - }); - - foreach (var job in recentBackgroundJobs) - panel.Children.Add(BuildRecentBackgroundJobCard(job)); } private void AddTaskSummaryObservabilitySections(StackPanel panel, ChatConversation? currentConversation) { AddTaskSummaryPermissionSection(panel, currentConversation); - AddTaskSummaryPermissionHistorySection(panel); - AddTaskSummaryHookSection(panel); AddTaskSummaryBackgroundSection(panel); }