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 동등성 작업 추적 문서
|
개발 참고: Claw Code 동등성 작업 추적 문서
|
||||||
`docs/claw-code-parity-plan.md`
|
`docs/claw-code-parity-plan.md`
|
||||||
|
|
||||||
|
- 업데이트: 2026-04-06 00:45 (KST)
|
||||||
|
- AX Agent 내부 설정 공통 탭에 `대화 스타일` 섹션 제목을 복구해, `문서 형태`와 `디자인 스타일` 저장 항목이 명확히 보이도록 정리했습니다.
|
||||||
|
- AX Agent 내부 설정 스킬 탭의 `MCP 서버` 영역에 `서버 추가` 버튼을 복원했고, 목록 카드 안에서 `활성화/비활성화`와 `삭제`까지 바로 관리할 수 있게 옮겼습니다.
|
||||||
|
|
||||||
- 업데이트: 2026-04-05 19:04 (KST)
|
- 업데이트: 2026-04-05 19:04 (KST)
|
||||||
- AX Agent transcript와 작업 요약에서 도구/스킬 이름을 사람이 읽기 쉬운 표시명으로 정리했습니다. raw snake_case 도구명 대신 `파일 읽기`, `빌드/실행`, `Git`, `/bug-hunt` 같은 표시명 중심으로 보입니다.
|
- 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 언어를 따르도록 맞췄다.
|
- [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`를 추가해 현재 탭 파일 메타를 표시하도록 했다.
|
- [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/승인 프리뷰 사이 시각 언어를 더 가깝게 맞췄다.
|
- 텍스트 프리뷰 본문도 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"
|
Checked="ChkOverlayAiEnabled_Changed"
|
||||||
Unchecked="ChkOverlayAiEnabled_Changed"/>
|
Unchecked="ChkOverlayAiEnabled_Changed"/>
|
||||||
</Grid>
|
</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 x:Name="OverlayDefaultOutputFormatRow" Margin="0,0,0,8">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
@@ -5187,10 +5197,39 @@
|
|||||||
<StackPanel x:Name="OverlayFallbackModelsPanel"/>
|
<StackPanel x:Name="OverlayFallbackModelsPanel"/>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
|
<Grid Margin="0,0,0,4">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<StackPanel>
|
||||||
<TextBlock Text="MCP 서버"
|
<TextBlock Text="MCP 서버"
|
||||||
FontSize="12.5"
|
FontSize="12.5"
|
||||||
FontWeight="SemiBold"
|
FontWeight="SemiBold"
|
||||||
Foreground="{DynamicResource PrimaryText}"/>
|
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}"
|
<Border Background="{DynamicResource ItemBackground}"
|
||||||
BorderBrush="{DynamicResource BorderColor}"
|
BorderBrush="{DynamicResource BorderColor}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
|
|||||||
@@ -15656,49 +15656,177 @@ public partial class ChatWindow : Window
|
|||||||
|
|
||||||
OverlayMcpServerListPanel.Children.Clear();
|
OverlayMcpServerListPanel.Children.Clear();
|
||||||
var servers = _settings.Settings.Llm.McpServers;
|
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)
|
if (servers == null || servers.Count == 0)
|
||||||
{
|
{
|
||||||
OverlayMcpServerListPanel.Children.Add(new TextBlock
|
OverlayMcpServerListPanel.Children.Add(new TextBlock
|
||||||
{
|
{
|
||||||
Text = "등록된 MCP 서버가 없습니다.",
|
Text = "등록된 MCP 서버가 없습니다.",
|
||||||
FontSize = 11,
|
FontSize = 11,
|
||||||
Foreground = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray
|
Foreground = secondaryText
|
||||||
});
|
});
|
||||||
return;
|
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,
|
Background = Brushes.Transparent,
|
||||||
BorderBrush = TryFindResource("BorderColor") as Brush ?? Brushes.LightGray,
|
BorderBrush = Brushes.Transparent,
|
||||||
BorderThickness = new Thickness(1),
|
BorderThickness = new Thickness(1),
|
||||||
CornerRadius = new CornerRadius(8),
|
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)
|
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,
|
Text = server.Name,
|
||||||
FontSize = 12,
|
FontSize = 12,
|
||||||
FontWeight = FontWeights.SemiBold,
|
FontWeight = FontWeights.SemiBold,
|
||||||
Foreground = TryFindResource("PrimaryText") as Brush ?? Brushes.Black
|
Foreground = primaryText,
|
||||||
});
|
VerticalAlignment = VerticalAlignment.Center
|
||||||
stack.Children.Add(new TextBlock
|
};
|
||||||
|
header.Children.Add(title);
|
||||||
|
|
||||||
|
var actions = new StackPanel
|
||||||
{
|
{
|
||||||
Text = $"{server.Command} {(server.Enabled ? "· 활성" : "· 비활성")}",
|
Orientation = Orientation.Horizontal,
|
||||||
Margin = new Thickness(0, 3, 0, 0),
|
HorizontalAlignment = HorizontalAlignment.Right,
|
||||||
FontSize = 10.5,
|
};
|
||||||
|
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,
|
TextWrapping = TextWrapping.Wrap,
|
||||||
Foreground = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray
|
Foreground = primaryText,
|
||||||
});
|
},
|
||||||
card.Child = stack;
|
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);
|
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()
|
private void BuildOverlayToolRegistryPanel()
|
||||||
{
|
{
|
||||||
if (OverlayToolRegistryPanel == null)
|
if (OverlayToolRegistryPanel == null)
|
||||||
|
|||||||
Reference in New Issue
Block a user