AX Agent 내부 설정 MCP 서버 관리와 대화 스타일 섹션 복구
Some checks failed
Release Gate / gate (push) Has been cancelled
Some checks failed
Release Gate / gate (push) Has been cancelled
- AX Agent 내부 설정 공통 탭에 대화 스타일 섹션 제목을 복구해 문서 형태/디자인 스타일 저장 항목을 명확히 노출 - 스킬 탭 MCP 서버 영역에 서버 추가 버튼을 복원하고 목록 카드에서 활성화 전환과 삭제를 바로 처리하도록 보강 - 오버레이 저장 경로를 그대로 사용해 내부 설정에서 변경 즉시 저장되도록 유지 - README와 DEVELOPMENT 문서에 2026-04-06 00:45 (KST) 기준 이력 반영 및 Release 빌드 경고 0 오류 0 확인
This commit is contained in:
@@ -7,6 +7,10 @@ Windows 전용 시맨틱 런처 & 워크스페이스 매니저
|
||||
개발 참고: Claw Code 동등성 작업 추적 문서
|
||||
`docs/claw-code-parity-plan.md`
|
||||
|
||||
- 업데이트: 2026-04-06 00:45 (KST)
|
||||
- AX Agent 내부 설정 공통 탭에 `대화 스타일` 섹션 제목을 복구해, `문서 형태`와 `디자인 스타일` 저장 항목이 명확히 보이도록 정리했습니다.
|
||||
- AX Agent 내부 설정 스킬 탭의 `MCP 서버` 영역에 `서버 추가` 버튼을 복원했고, 목록 카드 안에서 `활성화/비활성화`와 `삭제`까지 바로 관리할 수 있게 옮겼습니다.
|
||||
|
||||
- 업데이트: 2026-04-05 19:04 (KST)
|
||||
- AX Agent transcript와 작업 요약에서 도구/스킬 이름을 사람이 읽기 쉬운 표시명으로 정리했습니다. raw snake_case 도구명 대신 `파일 읽기`, `빌드/실행`, `Git`, `/bug-hunt` 같은 표시명 중심으로 보입니다.
|
||||
- 도구/스킬 이벤트 배지는 역할 중심(`도구`, `도구 결과`, `스킬`)으로 단순화하고, 실제 도구명은 본문 보조 텍스트로만 노출되게 바꿨습니다.
|
||||
|
||||
@@ -4851,3 +4851,5 @@ ow + toggle ?쒓컖 ?몄뼱濡??ㅼ떆 ?뺣젹?덈떎.
|
||||
- [PermissionRequestWindow.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/PermissionRequestWindow.cs) 의 `BuildPreviewCard`, `BuildFileEditPreviewCard`, `BuildFileWriteTwoColumnPreviewCard`는 이 helper를 쓰도록 정리해 권한 승인 프리뷰가 같은 preview 언어를 따르도록 맞췄다.
|
||||
- [ChatWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml) 의 우측 프리뷰 패널 헤더를 `파일명 / 경로 / 형식·크기 메타` 구조로 재배치하고, [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs) 에 `SetPreviewHeader`, `SetPreviewHeaderState`를 추가해 현재 탭 파일 메타를 표시하도록 했다.
|
||||
- 텍스트 프리뷰 본문도 bordered preview box 안에 렌더되게 바꿔, AX Agent 파일 프리뷰와 transcript/승인 프리뷰 사이 시각 언어를 더 가깝게 맞췄다.
|
||||
- Document update: 2026-04-06 00:45 (KST) - Restored the missing AX Agent internal-settings UX for conversation-style persistence by adding a visible `대화 스타일` section header above the existing `문서 형태` and `디자인 스타일` controls. The underlying save path already existed in `CmbOverlayDefaultOutputFormat_SelectionChanged` and `CmbOverlayDefaultMood_SelectionChanged`; this pass makes that persisted behavior explicit again in the overlay.
|
||||
- Document update: 2026-04-06 00:45 (KST) - Restored MCP server management inside the AX Agent internal settings overlay. The skill tab now exposes `+ 서버 추가`, and overlay MCP cards support inline enable/disable and delete actions with immediate persistence through `PersistOverlaySettingsState(...)`.
|
||||
|
||||
@@ -3111,6 +3111,16 @@
|
||||
Checked="ChkOverlayAiEnabled_Changed"
|
||||
Unchecked="ChkOverlayAiEnabled_Changed"/>
|
||||
</Grid>
|
||||
<StackPanel Margin="0,4,0,12">
|
||||
<TextBlock Text="대화 스타일"
|
||||
FontSize="13"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource PrimaryText}"/>
|
||||
<TextBlock Text="응답 결과물의 기본 형태와 문서 분위기를 여기서 저장합니다."
|
||||
Margin="0,4,0,0"
|
||||
FontSize="11"
|
||||
Foreground="{DynamicResource SecondaryText}"/>
|
||||
</StackPanel>
|
||||
<Grid x:Name="OverlayDefaultOutputFormatRow" Margin="0,0,0,8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
@@ -5187,10 +5197,39 @@
|
||||
<StackPanel x:Name="OverlayFallbackModelsPanel"/>
|
||||
</Border>
|
||||
|
||||
<TextBlock Text="MCP 서버"
|
||||
FontSize="12.5"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource PrimaryText}"/>
|
||||
<Grid Margin="0,0,0,4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel>
|
||||
<TextBlock Text="MCP 서버"
|
||||
FontSize="12.5"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource PrimaryText}"/>
|
||||
<TextBlock Text="외부 도구 서버를 등록하면 AX Agent가 연결된 기능을 사용할 수 있습니다."
|
||||
Margin="0,4,0,0"
|
||||
FontSize="11"
|
||||
Foreground="{DynamicResource SecondaryText}"/>
|
||||
</StackPanel>
|
||||
<Button x:Name="BtnOverlayAddMcpServer"
|
||||
Grid.Column="1"
|
||||
Padding="12,6"
|
||||
Cursor="Hand"
|
||||
Click="BtnOverlayAddMcpServer_Click">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text=""
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
FontSize="11"
|
||||
Margin="0,0,5,0"
|
||||
VerticalAlignment="Center"/>
|
||||
<TextBlock Text="서버 추가"
|
||||
FontSize="11.5"
|
||||
Foreground="{DynamicResource AccentColor}"
|
||||
VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</Grid>
|
||||
<Border Background="{DynamicResource ItemBackground}"
|
||||
BorderBrush="{DynamicResource BorderColor}"
|
||||
BorderThickness="1"
|
||||
|
||||
@@ -15656,49 +15656,177 @@ public partial class ChatWindow : Window
|
||||
|
||||
OverlayMcpServerListPanel.Children.Clear();
|
||||
var servers = _settings.Settings.Llm.McpServers;
|
||||
var primaryText = TryFindResource("PrimaryText") as Brush ?? Brushes.Black;
|
||||
var secondaryText = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray;
|
||||
var accentBrush = TryFindResource("AccentColor") as Brush ?? Brushes.DodgerBlue;
|
||||
var borderBrush = TryFindResource("BorderColor") as Brush ?? Brushes.LightGray;
|
||||
var itemBackground = TryFindResource("ItemBackground") as Brush ?? Brushes.White;
|
||||
var cardBackground = TryFindResource("LauncherBackground") as Brush ?? Brushes.White;
|
||||
|
||||
if (servers == null || servers.Count == 0)
|
||||
{
|
||||
OverlayMcpServerListPanel.Children.Add(new TextBlock
|
||||
{
|
||||
Text = "등록된 MCP 서버가 없습니다.",
|
||||
FontSize = 11,
|
||||
Foreground = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray
|
||||
Foreground = secondaryText
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var server in servers)
|
||||
Border CreateActionChip(string text, Brush foreground, Action onClick)
|
||||
{
|
||||
var card = new Border
|
||||
var border = new Border
|
||||
{
|
||||
Background = TryFindResource("LauncherBackground") as Brush ?? Brushes.White,
|
||||
BorderBrush = TryFindResource("BorderColor") as Brush ?? Brushes.LightGray,
|
||||
Background = Brushes.Transparent,
|
||||
BorderBrush = Brushes.Transparent,
|
||||
BorderThickness = new Thickness(1),
|
||||
CornerRadius = new CornerRadius(8),
|
||||
Padding = new Thickness(10, 8, 10, 8),
|
||||
Padding = new Thickness(8, 4, 8, 4),
|
||||
Margin = new Thickness(6, 0, 0, 0),
|
||||
Cursor = Cursors.Hand,
|
||||
};
|
||||
|
||||
var label = new TextBlock
|
||||
{
|
||||
Text = text,
|
||||
FontSize = 11,
|
||||
FontWeight = FontWeights.SemiBold,
|
||||
Foreground = foreground,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
};
|
||||
|
||||
border.Child = label;
|
||||
border.MouseEnter += (_, _) =>
|
||||
{
|
||||
border.Background = TryFindResource("HintBackground") as Brush ?? new SolidColorBrush(Color.FromArgb(20, 0, 0, 0));
|
||||
border.BorderBrush = borderBrush;
|
||||
};
|
||||
border.MouseLeave += (_, _) =>
|
||||
{
|
||||
border.Background = Brushes.Transparent;
|
||||
border.BorderBrush = Brushes.Transparent;
|
||||
};
|
||||
border.MouseLeftButtonUp += (_, _) => onClick();
|
||||
return border;
|
||||
}
|
||||
|
||||
for (int index = 0; index < servers.Count; index++)
|
||||
{
|
||||
var server = servers[index];
|
||||
var card = new Border
|
||||
{
|
||||
Background = cardBackground,
|
||||
BorderBrush = borderBrush,
|
||||
BorderThickness = new Thickness(1),
|
||||
CornerRadius = new CornerRadius(8),
|
||||
Padding = new Thickness(12, 10, 12, 10),
|
||||
Margin = new Thickness(0, 0, 0, 6)
|
||||
};
|
||||
var stack = new StackPanel();
|
||||
stack.Children.Add(new TextBlock
|
||||
|
||||
var root = new StackPanel();
|
||||
var header = new Grid();
|
||||
header.ColumnDefinitions.Add(new ColumnDefinition());
|
||||
header.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
||||
|
||||
var title = new TextBlock
|
||||
{
|
||||
Text = server.Name,
|
||||
FontSize = 12,
|
||||
FontWeight = FontWeights.SemiBold,
|
||||
Foreground = TryFindResource("PrimaryText") as Brush ?? Brushes.Black
|
||||
});
|
||||
stack.Children.Add(new TextBlock
|
||||
Foreground = primaryText,
|
||||
VerticalAlignment = VerticalAlignment.Center
|
||||
};
|
||||
header.Children.Add(title);
|
||||
|
||||
var actions = new StackPanel
|
||||
{
|
||||
Text = $"{server.Command} {(server.Enabled ? "· 활성" : "· 비활성")}",
|
||||
Margin = new Thickness(0, 3, 0, 0),
|
||||
FontSize = 10.5,
|
||||
TextWrapping = TextWrapping.Wrap,
|
||||
Foreground = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray
|
||||
});
|
||||
card.Child = stack;
|
||||
Orientation = Orientation.Horizontal,
|
||||
HorizontalAlignment = HorizontalAlignment.Right,
|
||||
};
|
||||
actions.Children.Add(CreateActionChip(server.Enabled ? "비활성화" : "활성화", accentBrush, () =>
|
||||
{
|
||||
_settings.Settings.Llm.McpServers[index].Enabled = !_settings.Settings.Llm.McpServers[index].Enabled;
|
||||
PersistOverlaySettingsState(refreshOverlayDeferredInputs: false);
|
||||
BuildOverlayMcpServerCards();
|
||||
}));
|
||||
actions.Children.Add(CreateActionChip("삭제", BrushFromHex("#DC2626"), () =>
|
||||
{
|
||||
var result = CustomMessageBox.Show($"'{server.Name}' 서버를 삭제하시겠습니까?", "MCP 서버 삭제",
|
||||
MessageBoxButton.YesNo, MessageBoxImage.Question);
|
||||
if (result != MessageBoxResult.Yes)
|
||||
return;
|
||||
|
||||
_settings.Settings.Llm.McpServers.RemoveAt(index);
|
||||
PersistOverlaySettingsState(refreshOverlayDeferredInputs: false);
|
||||
BuildOverlayMcpServerCards();
|
||||
}));
|
||||
Grid.SetColumn(actions, 1);
|
||||
header.Children.Add(actions);
|
||||
root.Children.Add(header);
|
||||
|
||||
var commandCard = new Border
|
||||
{
|
||||
Background = itemBackground,
|
||||
BorderBrush = borderBrush,
|
||||
BorderThickness = new Thickness(1),
|
||||
CornerRadius = new CornerRadius(8),
|
||||
Padding = new Thickness(10, 8, 10, 8),
|
||||
Margin = new Thickness(0, 8, 0, 0),
|
||||
Child = new StackPanel
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new TextBlock
|
||||
{
|
||||
Text = server.Command,
|
||||
FontSize = 10.8,
|
||||
TextWrapping = TextWrapping.Wrap,
|
||||
Foreground = primaryText,
|
||||
},
|
||||
new TextBlock
|
||||
{
|
||||
Text = server.Enabled ? "활성 상태" : "비활성 상태",
|
||||
Margin = new Thickness(0, 4, 0, 0),
|
||||
FontSize = 10.5,
|
||||
Foreground = secondaryText,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
root.Children.Add(commandCard);
|
||||
card.Child = root;
|
||||
OverlayMcpServerListPanel.Children.Add(card);
|
||||
}
|
||||
}
|
||||
|
||||
private void BtnOverlayAddMcpServer_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var nameDialog = new InputDialog("MCP 서버 추가", "서버 이름:", placeholder: "예: my-mcp-server")
|
||||
{
|
||||
Owner = this
|
||||
};
|
||||
if (nameDialog.ShowDialog() != true || string.IsNullOrWhiteSpace(nameDialog.ResponseText))
|
||||
return;
|
||||
|
||||
var commandDialog = new InputDialog("MCP 서버 추가", "실행 명령:", placeholder: "예: npx -y @modelcontextprotocol/server-filesystem")
|
||||
{
|
||||
Owner = this
|
||||
};
|
||||
if (commandDialog.ShowDialog() != true || string.IsNullOrWhiteSpace(commandDialog.ResponseText))
|
||||
return;
|
||||
|
||||
_settings.Settings.Llm.McpServers.Add(new Models.McpServerEntry
|
||||
{
|
||||
Name = nameDialog.ResponseText.Trim(),
|
||||
Command = commandDialog.ResponseText.Trim(),
|
||||
Enabled = true,
|
||||
});
|
||||
|
||||
PersistOverlaySettingsState(refreshOverlayDeferredInputs: false);
|
||||
BuildOverlayMcpServerCards();
|
||||
}
|
||||
|
||||
private void BuildOverlayToolRegistryPanel()
|
||||
{
|
||||
if (OverlayToolRegistryPanel == null)
|
||||
|
||||
Reference in New Issue
Block a user