런처 Agent Compare 기능 1차 이식 및 현재 런처 구조 연결

- Agent Compare 기준으로 런처 빠른 실행 칩, 검색 히스토리 탐색, 선택 항목 미리보기 패널을 현재 런처에 이식
- 하단 위젯 바, QuickLook(F3), 화면 OCR(F4), 관련 서비스/partial 파일을 현재 LauncherWindow/LauncherViewModel 구조에 연결
- UsageRankingService 상위 항목 조회와 SearchHistoryService를 추가해 실행 상위 경로/검색 기록이 실제 런처 동작에 반영되도록 정리
- README.md, docs/DEVELOPMENT.md에 이식 범위와 검증 결과를 2026-04-05 11:58 (KST) 기준으로 기록

검증 결과
- dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\ 경고 0 / 오류 0
This commit is contained in:
2026-04-05 11:51:43 +09:00
parent 0336904258
commit f7cafe0cfc
17 changed files with 2518 additions and 24 deletions

View File

@@ -18,6 +18,8 @@
WindowStartupLocation="Manual"
Loaded="Window_Loaded"
Deactivated="Window_Deactivated"
LocationChanged="Window_LocationChanged"
IsVisibleChanged="Window_IsVisibleChanged"
PreviewKeyDown="Window_PreviewKeyDown"
KeyDown="Window_KeyDown">
@@ -201,10 +203,16 @@
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- ─── 입력 영역 ─── -->
<Grid Grid.Row="0" Margin="20,16,20,16">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
@@ -413,8 +421,57 @@
Foreground="{DynamicResource HintText}"
Margin="3,0,0,0"
VerticalAlignment="Center"/>
</StackPanel>
</Border>
</StackPanel>
</Border>
<ItemsControl Grid.Row="1"
Grid.ColumnSpan="3"
ItemsSource="{Binding QuickActionItems}"
Margin="0,10,0,0"
Visibility="{Binding ShowQuickActions, Converter={StaticResource BoolToVisibilityConverter}}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Margin="0,0,6,6"
Padding="9,5"
CornerRadius="10"
Cursor="Hand"
Background="{Binding Background}"
BorderThickness="1"
BorderBrush="{DynamicResource BorderColor}"
MouseLeftButtonUp="QuickActionChip_Click">
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="{DynamicResource AccentColor}"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Symbol}"
FontFamily="Segoe MDL2 Assets"
FontSize="11"
Foreground="{DynamicResource SecondaryText}"
VerticalAlignment="Center"
Margin="0,0,5,0"/>
<TextBlock Text="{Binding Title}"
FontFamily="Segoe UI, Malgun Gothic"
FontSize="11"
Foreground="{DynamicResource PrimaryText}"
VerticalAlignment="Center"
MaxWidth="100"
TextTrimming="CharacterEllipsis"/>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
<!-- ─── 파일 액션 모드 breadcrumb 바 ─── -->
@@ -691,9 +748,31 @@
</ListView.ItemTemplate>
</ListView>
<Border Grid.Row="5"
x:Name="PreviewPanel"
Visibility="{Binding HasPreview, Converter={StaticResource BoolToVisibilityConverter}}"
Background="{DynamicResource ItemBackground}"
CornerRadius="8"
Margin="10,0,10,8"
Padding="12,8"
MaxHeight="100">
<ScrollViewer VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled">
<ScrollViewer.Resources>
<Style TargetType="ScrollBar" BasedOn="{StaticResource SlimScrollBar}"/>
</ScrollViewer.Resources>
<TextBlock Text="{Binding PreviewText}"
FontFamily="Segoe UI Mono, Consolas, Malgun Gothic"
FontSize="11"
Foreground="{DynamicResource SecondaryText}"
TextWrapping="Wrap"
LineHeight="16"/>
</ScrollViewer>
</Border>
<!-- ─── 인덱싱 상태 바 ─── -->
<TextBlock x:Name="IndexStatusText"
Grid.Row="5"
Grid.Row="6"
Visibility="Collapsed"
FontSize="10"
Foreground="{DynamicResource SecondaryText}"
@@ -701,9 +780,179 @@
Margin="0,0,0,8"
Opacity="0.7"/>
<Border x:Name="WidgetBar"
Grid.Row="7"
BorderBrush="{DynamicResource SeparatorColor}"
BorderThickness="0,1,0,0"
Padding="10,7,10,9">
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="6"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="6"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="6"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Border x:Name="WgtPerf" Grid.Column="0"
CornerRadius="5" Padding="8,5"
Background="#0D60A5FA"
Cursor="Hand"
MouseLeftButtonUp="WgtPerf_Click">
<StackPanel Orientation="Horizontal">
<TextBlock Text="&#xE950;"
FontFamily="Segoe MDL2 Assets" FontSize="10"
Foreground="#60A5FA"
VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBlock Text="{Binding Widget_PerfText}"
FontSize="10"
Foreground="{DynamicResource SecondaryText}"
VerticalAlignment="Center"/>
</StackPanel>
</Border>
<Border x:Name="WgtPomo" Grid.Column="2"
CornerRadius="5" Padding="8,5"
Background="#0DF59E0B"
Cursor="Hand"
MouseLeftButtonUp="WgtPomo_Click">
<StackPanel Orientation="Horizontal">
<TextBlock Text="&#xE916;"
FontFamily="Segoe MDL2 Assets" FontSize="10"
Foreground="#F59E0B"
VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBlock x:Name="WgtPomoText"
Text="{Binding Widget_PomoText}"
FontSize="10"
Foreground="{DynamicResource SecondaryText}"
VerticalAlignment="Center"/>
</StackPanel>
</Border>
<Border x:Name="WgtNote" Grid.Column="4"
CornerRadius="5" Padding="8,5"
Background="#0D8B5CF6"
Cursor="Hand"
MouseLeftButtonUp="WgtNote_Click">
<StackPanel Orientation="Horizontal">
<TextBlock Text="&#xE70B;"
FontFamily="Segoe MDL2 Assets" FontSize="10"
Foreground="#8B5CF6"
VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBlock Text="{Binding Widget_NoteText}"
FontSize="10"
Foreground="{DynamicResource SecondaryText}"
VerticalAlignment="Center"/>
</StackPanel>
</Border>
<Border x:Name="WgtServer" Grid.Column="6"
CornerRadius="5" Padding="8,5"
Background="#0D10B981"
Cursor="Hand"
MouseLeftButtonUp="WgtServer_Click">
<StackPanel Orientation="Horizontal" x:Name="WgtServerContent">
<Ellipse x:Name="OllamaStatusDot"
Width="6" Height="6"
Fill="#9E9E9E"
VerticalAlignment="Center" Margin="0,0,3,0"/>
<TextBlock Text="Ollama"
FontSize="10"
Foreground="{DynamicResource SecondaryText}"
VerticalAlignment="Center" Margin="0,0,8,0"/>
<Ellipse x:Name="LlmStatusDot"
Width="6" Height="6"
Fill="#9E9E9E"
VerticalAlignment="Center" Margin="0,0,3,0"/>
<TextBlock Text="API"
FontSize="10"
Foreground="{DynamicResource SecondaryText}"
VerticalAlignment="Center" Margin="0,0,8,0"/>
<Ellipse x:Name="McpStatusDot"
Width="6" Height="6"
Fill="#9E9E9E"
VerticalAlignment="Center" Margin="0,0,3,0"/>
<TextBlock x:Name="McpNameText"
Text="{Binding Widget_McpName}"
FontSize="10"
Foreground="{DynamicResource SecondaryText}"
VerticalAlignment="Center"/>
</StackPanel>
</Border>
</Grid>
<Grid Margin="0,4,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="6"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="6"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Border x:Name="WgtWeather" Grid.Column="0"
CornerRadius="5" Padding="8,5"
Background="#0D3B82F6"
Cursor="Hand"
MouseLeftButtonUp="WgtWeather_Click">
<StackPanel Orientation="Horizontal">
<TextBlock Text="&#xE708;"
FontFamily="Segoe MDL2 Assets" FontSize="10"
Foreground="#60A5FA"
VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBlock Text="{Binding Widget_WeatherText}"
FontSize="10"
Foreground="{DynamicResource SecondaryText}"
VerticalAlignment="Center"
TextTrimming="CharacterEllipsis"
MaxWidth="100"/>
</StackPanel>
</Border>
<Border x:Name="WgtCal" Grid.Column="2"
CornerRadius="5" Padding="8,5"
Background="#0DEC4899"
Cursor="Hand"
MouseLeftButtonUp="WgtCal_Click">
<StackPanel Orientation="Horizontal">
<TextBlock Text="&#xE8BF;"
FontFamily="Segoe MDL2 Assets" FontSize="10"
Foreground="#EC4899"
VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBlock Text="{Binding Widget_CalText}"
FontSize="10"
Foreground="{DynamicResource SecondaryText}"
VerticalAlignment="Center"/>
</StackPanel>
</Border>
<Border x:Name="WgtBattery" Grid.Column="4"
CornerRadius="5" Padding="8,5"
Background="#0D10B981"
Cursor="Hand"
MouseLeftButtonUp="WgtBattery_Click"
Visibility="{Binding Widget_BatteryVisible, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Widget_BatteryIcon}"
FontFamily="Segoe MDL2 Assets" FontSize="10"
Foreground="#10B981"
VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBlock Text="{Binding Widget_BatteryText}"
FontSize="10"
Foreground="{DynamicResource SecondaryText}"
VerticalAlignment="Center"/>
</StackPanel>
</Border>
</Grid>
</StackPanel>
</Border>
<!-- ─── 토스트 오버레이 ─── -->
<Border x:Name="ToastOverlay"
Grid.Row="4" Grid.RowSpan="2"
Grid.Row="4" Grid.RowSpan="4"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
Margin="0,0,0,12"