Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ the engine generation, so it moves 0.14.1 → 0.15.0.
Desktop against a real `@directory` request.

### Fixed
- **Skill and MCP toggles no longer redraw the entire management list.** Enabling or disabling an
item now updates that toggle in place while the app applies the change to active agents. The list
keeps its current order and scroll position; it is reconciled the next time the page is opened,
filtered, or explicitly refreshed.
- **The token total now reflects what the provider actually processed.** Desktop no longer adds
rough character-based estimates for reads, searches, web results, writes, or attachments on top
of the provider's prompt and completion counts. File reads still show their line counts.
Expand Down
8 changes: 7 additions & 1 deletion src/MandoCode.Desktop/MainWindow.Mcp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,13 @@ private async void McpEnabled_Toggled(object sender, RoutedEventArgs e)

McpPageStatus.Text = sw.IsOn ? $"Enabling “{row.Name}”…" : $"Disabling “{row.Name}”…";
await Task.Run(() => _controller.SaveMcpServerAsync(row.Name, row.Name, server));
await RefreshMcpListAsync();

// Do not replace the grouped ItemsSource for a single toggle. Recreating the list makes
// every row animate back into place and moves this server between groups while the user is
// still looking at it. The durable config and live agent tools are already updated above;
// the current view is reconciled when the page is opened again, filtered, or refreshed.
row.Enabled = sw.IsOn;
McpPageStatus.Text = sw.IsOn ? $"Enabled “{row.Name}”." : $"Disabled “{row.Name}”.";
}

/// <summary>Runs a slash command through the normal pipeline (transcript echo, wizard
Expand Down
12 changes: 10 additions & 2 deletions src/MandoCode.Desktop/MainWindow.Skills.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ private void ApplySkillFilter()
SkillsPageStatus.Text = $"{total} skill{(total == 1 ? "" : "s")}, {enabledTotal} enabled · {_skillCoordinator.UserSkillsDirectory}";
}

/// <summary>Reload every agent's skill set + prompt, then re-render the list and report.</summary>
/// <summary>Reload every agent's skill set + prompt, then re-render the list and report.
/// Use this after a structural change such as create, edit, install, delete, or an explicit
/// refresh. A simple enable/disable change deliberately keeps the current list in place.</summary>
private async Task ApplySkillChangeAsync(string status)
{
await _skillCoordinator.ReloadAllAsync();
Expand Down Expand Up @@ -138,7 +140,13 @@ private async void SkillEnabled_Toggled(object sender, RoutedEventArgs e)
try
{
_skillCoordinator.SetEnabled(row.FolderPath, sw.IsOn);
await ApplySkillChangeAsync(sw.IsOn ? $"Enabled “{row.Name}”." : $"Disabled “{row.Name}”.");
// Keep this row exactly where the user toggled it. Reapplying the grouped ItemsSource
// would remove and recreate every row, producing a distracting slide animation and
// reordering enabled/disabled groups mid-click. The persisted state is reconciled on
// the next page open, filter change, or explicit refresh.
row.Enabled = sw.IsOn;
await _skillCoordinator.ReloadAllAsync();
SkillsPageStatus.Text = sw.IsOn ? $"Enabled “{row.Name}”." : $"Disabled “{row.Name}”.";
}
catch (Exception ex)
{
Expand Down
4 changes: 2 additions & 2 deletions src/MandoCode.Desktop/MainWindow.ViewModels.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ public sealed class McpRow
public string Status { get; init; } = "";
public SolidColorBrush StatusBrush { get; init; } = new(Colors.Gray);
/// <summary>Per-server on/off (the config's Disabled flag, inverted). Shared by every agent.</summary>
public bool Enabled { get; init; }
public bool Enabled { get; set; }
}

/// <summary>A section of the skills list (e.g. "Enabled (12)"). A List subclass so a
Expand All @@ -218,7 +218,7 @@ public sealed class SkillRow
public string Description { get; init; } = "";
public string Body { get; init; } = "";
public string FolderPath { get; init; } = "";
public bool Enabled { get; init; }
public bool Enabled { get; set; }

// Size of the instructions body — what gets injected into the prompt on load, so it's the cost
// that spins a local model up. ~4 chars/token is the usual rough estimate.
Expand Down
Loading