Skip to content

Commit ef872e1

Browse files
sharpninjaCopilot
andcommitted
Polish agent chat, todos, and session log UX
Add the Web agent chat flyout and inline polish, tighten shared todo and session-log surfaces across clients, and update the McpServer submodule to use streamed voice POST transport. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 99b3831 commit ef872e1

99 files changed

Lines changed: 3437 additions & 837 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

nupkg/SharpNinja.McpServer.Director.nuspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
33
<metadata>
44
<id>SharpNinja.McpServer.Director</id>
5-
<version>0.5.1-30</version>
5+
<version>0.5.1-36</version>
66
<authors>SharpNinja</authors>
77
<description>CLI management tool for McpServer. Provides workspace management, agent orchestration, compliance policy editing, Keycloak OIDC auth, and an interactive Terminal.Gui TUI with 7 tabbed screens. 18 CLI commands via System.CommandLine.</description>
88
<packageTypes>

nupkg/SharpNinja.McpServer.Web.nuspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
33
<metadata>
44
<id>SharpNinja.McpServer.Web</id>
5-
<version>0.5.1-34</version>
5+
<version>0.5.1-36</version>
66
<authors>SharpNinja</authors>
77
<description>SharpNinja.McpServer.Web</description>
88
<packageTypes>

src/McpServer.Director/Screens/SessionLogScreen.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ private static string FormatDetail(SessionLogDetail detail)
263263
$"Model: {ValueOrDash(detail.Model)}",
264264
$"Started: {FormatTimestampOrDash(detail.Started)}",
265265
$"Updated: {FormatTimestampOrDash(detail.LastUpdated)}",
266-
$"EntryCount: {detail.EntryCount}",
266+
$"TurnCount: {detail.TurnCount}",
267267
$"TotalTokens: {detail.TotalTokens?.ToString() ?? "—"}",
268268
$"CursorSessionLabel: {ValueOrDash(detail.CursorSessionLabel)}",
269269
};
@@ -290,13 +290,13 @@ private static string FormatDetail(SessionLogDetail detail)
290290
}
291291

292292
lines.Add("");
293-
lines.Add($"Entries ({detail.Entries.Count}):");
294-
if (detail.Entries.Count == 0)
293+
lines.Add($"Turns ({detail.Turns.Count}):");
294+
if (detail.Turns.Count == 0)
295295
return string.Join(Environment.NewLine, lines);
296296

297-
for (var i = 0; i < detail.Entries.Count; i++)
297+
for (var i = 0; i < detail.Turns.Count; i++)
298298
{
299-
var entry = detail.Entries[i];
299+
var entry = detail.Turns[i];
300300
lines.Add("");
301301
lines.Add($"[{i + 1}] RequestId: {ValueOrDash(entry.RequestId)}");
302302
lines.Add($" Status: {ValueOrDash(entry.Status)}");

src/McpServer.Director/SessionLogApiClientAdapter.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ private static SessionLogSummary MapSummary(UnifiedSessionLogDto item)
119119
Model: item.Model,
120120
Started: item.Started,
121121
LastUpdated: item.LastUpdated,
122-
EntryCount: item.EntryCount);
122+
TurnCount: item.TurnCount);
123123

124124
private static UnifiedSessionLogDto MapSubmit(SessionLogDetail detail)
125125
=> new()
@@ -131,7 +131,7 @@ private static UnifiedSessionLogDto MapSubmit(SessionLogDetail detail)
131131
Model = detail.Model,
132132
Started = detail.Started,
133133
LastUpdated = detail.LastUpdated,
134-
EntryCount = detail.EntryCount,
134+
TurnCount = detail.TurnCount,
135135
TotalTokens = detail.TotalTokens,
136136
CursorSessionLabel = detail.CursorSessionLabel,
137137
Workspace = detail.Workspace is null
@@ -153,10 +153,10 @@ private static UnifiedSessionLogDto MapSubmit(SessionLogDetail detail)
153153
CompletedCount = detail.CopilotStatistics.CompletedCount,
154154
InProgressCount = detail.CopilotStatistics.InProgressCount
155155
},
156-
Entries = detail.Entries.Select(MapSubmitEntry).ToList()
156+
Turns = detail.Turns.Select(MapSubmitTurn).ToList()
157157
};
158158

159-
private static UnifiedRequestEntryDto MapSubmitEntry(SessionLogEntryDetail entry)
159+
private static UnifiedRequestEntryDto MapSubmitTurn(SessionLogTurnDetail entry)
160160
=> new()
161161
{
162162
RequestId = entry.RequestId,
@@ -222,7 +222,7 @@ private static SessionLogDetail MapDetail(UnifiedSessionLogDto item)
222222
Model: item.Model,
223223
Started: item.Started,
224224
LastUpdated: item.LastUpdated,
225-
EntryCount: item.EntryCount,
225+
TurnCount: item.TurnCount,
226226
TotalTokens: item.TotalTokens,
227227
CursorSessionLabel: item.CursorSessionLabel,
228228
Workspace: item.Workspace is null ? null : new SessionLogWorkspaceInfo(
@@ -236,9 +236,9 @@ private static SessionLogDetail MapDetail(UnifiedSessionLogDto item)
236236
item.CopilotStatistics.TotalNetPremiumRequests,
237237
item.CopilotStatistics.CompletedCount,
238238
item.CopilotStatistics.InProgressCount),
239-
Entries: item.Entries?.Select(MapEntry).ToList() ?? []);
239+
Turns: item.Turns?.Select(MapTurn).ToList() ?? []);
240240

241-
private static SessionLogEntryDetail MapEntry(UnifiedRequestEntryDto entry)
241+
private static SessionLogTurnDetail MapTurn(UnifiedRequestEntryDto entry)
242242
=> new(
243243
RequestId: entry.RequestId ?? string.Empty,
244244
Timestamp: entry.Timestamp,

src/McpServer.UI.Core/Commands/AllCommands.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public async Task<Result<bool>> HandleAsync(RefreshViewCommand command, CallCont
4242

4343
// --- Request Details ---
4444

45-
public sealed record ShowRequestDetailsCommand(Models.Json.SearchableEntry Entry) : ICommand<bool>;
45+
public sealed record ShowRequestDetailsCommand(Models.Json.SearchableTurn Entry) : ICommand<bool>;
4646

4747
public sealed class ShowRequestDetailsHandler(IRequestDetailsTarget target) : ICommandHandler<ShowRequestDetailsCommand, bool>
4848
{
@@ -88,13 +88,13 @@ public Task<Result<bool>> HandleAsync(NavigateToNextRequestCommand command, Call
8888

8989
// --- Selection ---
9090

91-
public sealed record SelectSearchEntryCommand(Models.Json.SearchableEntry Entry) : ICommand<bool>;
91+
public sealed record SelectSearchTurnCommand(Models.Json.SearchableTurn Entry) : ICommand<bool>;
9292

93-
public sealed class SelectSearchEntryHandler(IRequestDetailsTarget target) : ICommandHandler<SelectSearchEntryCommand, bool>
93+
public sealed class SelectSearchTurnHandler(IRequestDetailsTarget target) : ICommandHandler<SelectSearchTurnCommand, bool>
9494
{
95-
public Task<Result<bool>> HandleAsync(SelectSearchEntryCommand command, CallContext context)
95+
public Task<Result<bool>> HandleAsync(SelectSearchTurnCommand command, CallContext context)
9696
{
97-
target.SelectSearchEntry(command.Entry);
97+
target.SelectSearchTurn(command.Entry);
9898
return Task.FromResult(Result<bool>.Success(true));
9999
}
100100
}
@@ -112,7 +112,7 @@ public async Task<Result<bool>> HandleAsync(CopyTextCommand command, CallContext
112112
}
113113
}
114114

115-
public sealed record CopyOriginalJsonCommand(Models.Json.UnifiedRequestEntry? Entry) : ICommand<bool>;
115+
public sealed record CopyOriginalJsonCommand(Models.Json.UnifiedSessionTurn? Entry) : ICommand<bool>;
116116

117117
public sealed class CopyOriginalJsonHandler(IClipboardTarget target) : ICommandHandler<CopyOriginalJsonCommand, bool>
118118
{
@@ -249,7 +249,7 @@ public Task<Result<bool>> HandleAsync(JsonNodeDoubleTappedCommand command, CallC
249249

250250
// --- Search Row Tap ---
251251

252-
public sealed record SearchRowTappedCommand(Models.Json.SearchableEntry? Entry) : ICommand<bool>;
252+
public sealed record SearchRowTappedCommand(Models.Json.SearchableTurn? Entry) : ICommand<bool>;
253253

254254
public sealed class SearchRowTappedHandler(IRequestDetailsTarget target) : ICommandHandler<SearchRowTappedCommand, bool>
255255
{
@@ -262,7 +262,7 @@ public Task<Result<bool>> HandleAsync(SearchRowTappedCommand command, CallContex
262262

263263
// --- Search Row Double-Tap ---
264264

265-
public sealed record SearchRowDoubleTappedCommand(Models.Json.SearchableEntry? Entry) : ICommand<bool>;
265+
public sealed record SearchRowDoubleTappedCommand(Models.Json.SearchableTurn? Entry) : ICommand<bool>;
266266

267267
public sealed class SearchRowDoubleTappedHandler(IRequestDetailsTarget target) : ICommandHandler<SearchRowDoubleTappedCommand, bool>
268268
{

src/McpServer.UI.Core/Commands/AsyncCommands.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -87,39 +87,39 @@ public Task<Result<bool>> HandleAsync(RefreshAndLoadAllJsonCommand command, Call
8787
uniqueSessions = data.OrderAndDeduplicateSessions(byPath);
8888
}
8989

90-
// Stamp agent on entries
90+
// Stamp agent on turns
9191
foreach (var log in uniqueSessions)
9292
{
9393
var agent = string.IsNullOrWhiteSpace(log.SourceType) ? "Unknown" : log.SourceType.Trim();
94-
if (log.Entries == null) continue;
95-
foreach (var entry in log.Entries)
94+
if (log.Turns == null) continue;
95+
foreach (var entry in log.Turns)
9696
{
9797
if (entry != null && string.IsNullOrWhiteSpace(entry.Agent))
9898
entry.Agent = agent;
9999
}
100100
}
101101

102-
var allEntries = uniqueSessions.SelectMany(l => l.Entries).OrderByDescending(e => e.Timestamp).ToList();
103-
var deduped = MainWindowViewModel.DeduplicateUnifiedEntries(allEntries);
102+
var allTurns = uniqueSessions.SelectMany(l => l.Turns).OrderByDescending(e => e.Timestamp).ToList();
103+
var deduped = MainWindowViewModel.DeduplicateUnifiedTurns(allTurns);
104104

105105
var masterLog = new UnifiedSessionLog
106106
{
107107
SourceType = "Aggregated",
108108
SessionId = "ALL-JSON",
109-
Title = "All Requests",
109+
Title = "All Turns",
110110
Model = "Various",
111111
Started = DateTime.Now,
112112
Status = "Aggregated",
113-
EntryCount = deduped.Count,
114-
Entries = deduped,
113+
TurnCount = deduped.Count,
114+
Turns = deduped,
115115
TotalTokens = uniqueSessions.Sum(l => l.TotalTokens)
116116
};
117117

118118
var summary = new JsonLogSummary();
119119
data.BuildUnifiedSummaryAndIndex(masterLog, summary);
120120
summary.SummaryLines.Clear();
121121
summary.SummaryLines.Add($"Type: {masterLog.SourceType}");
122-
summary.SummaryLines.Add($"Total Entries: {masterLog.EntryCount}");
122+
summary.SummaryLines.Add($"Total Turns: {masterLog.TurnCount}");
123123
summary.SummaryLines.Add($"Total Tokens: {masterLog.TotalTokens:N0}");
124124
summary.SummaryLines.Add($"Aggregated at: {masterLog.Started}");
125125

@@ -129,7 +129,7 @@ public Task<Result<bool>> HandleAsync(RefreshAndLoadAllJsonCommand command, Call
129129
root.Children.Add(new JsonTreeNode("sourceType", masterLog.SourceType ?? "Aggregated", "String"));
130130
root.Children.Add(new JsonTreeNode("sessionId", masterLog.SessionId ?? "ALL-JSON", "String"));
131131
root.Children.Add(new JsonTreeNode("title", masterLog.Title ?? "All Requests", "String"));
132-
root.Children.Add(new JsonTreeNode("entryCount", masterLog.EntryCount.ToString(), "Number"));
132+
root.Children.Add(new JsonTreeNode("turnCount", masterLog.TurnCount.ToString(), "Number"));
133133
root.Children.Add(new JsonTreeNode("totalTokens", $"{masterLog.TotalTokens:N0}", "Number"));
134134
root.Children.Add(new JsonTreeNode("sessions", $"{uniqueSessions.Count} sessions", "Number"));
135135

@@ -145,7 +145,7 @@ public Task<Result<bool>> HandleAsync(RefreshAndLoadAllJsonCommand command, Call
145145
data.JsonLogSummary = summary;
146146
data.JsonTree.Clear();
147147
data.JsonTree.Add(root);
148-
data.UpdateFilteredSearchEntries();
148+
data.UpdateFilteredSearchTurns();
149149
data.AgentFilter = string.IsNullOrWhiteSpace(preselectedAgent) ? "" : preselectedAgent.Trim();
150150
dispatch.StatusMessage = string.IsNullOrWhiteSpace(preselectedAgent)
151151
? $"Loaded {reqCount} requests from {sessionCount} sessions."
@@ -212,7 +212,7 @@ public Task<Result<bool>> HandleAsync(RefreshAndLoadSessionCommand command, Call
212212
summary.SummaryLines.Clear();
213213
summary.SummaryLines.Add($"Type: {session.SourceType}");
214214
summary.SummaryLines.Add($"Session: {session.SessionId}");
215-
summary.SummaryLines.Add($"Entries: {session.EntryCount}");
215+
summary.SummaryLines.Add($"Turns: {session.TurnCount}");
216216
if (!string.IsNullOrEmpty(session.Model))
217217
summary.SummaryLines.Add($"Model: {session.Model}");
218218
if (session.LastUpdated.HasValue)
@@ -229,7 +229,7 @@ public Task<Result<bool>> HandleAsync(RefreshAndLoadSessionCommand command, Call
229229
data.JsonTree.Clear();
230230
data.JsonLogSummary = summary;
231231
data.JsonTree.Add(root);
232-
data.UpdateFilteredSearchEntries();
232+
data.UpdateFilteredSearchTurns();
233233
dispatch.StatusMessage = $"Loaded {session.SourceType}/{session.SessionId}";
234234
});
235235
}

src/McpServer.UI.Core/Commands/IClipboardTarget.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ namespace McpServer.UI.Core.Commands;
99
public interface IClipboardTarget
1010
{
1111
Task CopyText(string text);
12-
Task CopyOriginalJson(UnifiedRequestEntry? entry);
12+
Task CopyOriginalJson(UnifiedSessionTurn? entry);
1313
}
1414

src/McpServer.UI.Core/Commands/IRequestDetailsTarget.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ namespace McpServer.UI.Core.Commands;
77
/// </summary>
88
public interface IRequestDetailsTarget
99
{
10-
void ShowRequestDetails(SearchableEntry entry);
10+
void ShowRequestDetails(SearchableTurn entry);
1111
void CloseRequestDetails();
1212
void NavigateToPreviousRequest();
1313
void NavigateToNextRequest();
14-
void SelectSearchEntry(SearchableEntry entry);
15-
void SearchRowTapped(SearchableEntry? entry);
16-
void SearchRowDoubleTapped(SearchableEntry? entry);
14+
void SelectSearchTurn(SearchableTurn entry);
15+
void SearchRowTapped(SearchableTurn? entry);
16+
void SearchRowDoubleTapped(SearchableTurn? entry);
1717
}
1818

src/McpServer.UI.Core/Commands/ISessionDataTarget.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public interface ISessionDataTarget
1919
void LoadJson(string filePath);
2020
void LoadMarkdownFile(FileNode node);
2121
void LoadSourceFile(FileNode node);
22-
void UpdateFilteredSearchEntries();
22+
void UpdateFilteredSearchTurns();
2323
McpSessionLogService McpSessionService { get; }
2424
JsonLogSummary JsonLogSummary { get; set; }
2525
ObservableCollection<JsonTreeNode> JsonTree { get; }

0 commit comments

Comments
 (0)