Skip to content
Merged
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
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog

## 0.10.19 (Preview)

### Changed
- **Switched MCP server to AITools.BinlogMcp** — the extension now uses [AITools.BinlogMcp](https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/AITools.BinlogMcp) from the dotnet-eng feed instead of BinlogInsights.Mcp from nuget.org. The new package is auto-installed on first use. Existing BinlogInsights.Mcp installations are automatically migrated — the extension installs the new tool and prompts to uninstall the old one.
- **Consistent project count** — the overview and tree view now show the same deduplicated project count instead of the raw evaluation count
- **Search with text format** — search results from the new MCP's text format are parsed correctly for the tree view

### Fixed
- **Evaluations tree** — parse text format responses from the new MCP server; gracefully show "not available" when the tool isn't registered
- **Task expansion** — fixed parameter names (`target` not `target_name`, `task_id` not `task_name`) to match the new MCP tool signatures
- **Multi-binlog removal** — always inject `binlog_file` in tree MCP calls to avoid stale state errors when removing a binlog
- **Overview parsing** — handle both JSON (old) and text (new) overview formats
- **Project list for solutions** — parse `projectFile` property in addition to `fullPath` for compatibility

## 0.10.18 (Preview)

### Removed
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "binlog-analyzer",
"displayName": "MSBuild Binlog Analyzer",
"description": "Analyze MSBuild binary logs with Copilot Chat and MCP tools",
"version": "0.10.18",
"version": "0.10.19",
"preview": true,
"publisher": "dotutils",
"license": "MIT",
Expand Down
74 changes: 54 additions & 20 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2100,6 +2100,29 @@ async function configureMcpServer(binlogPaths: string[], config: vscode.Workspac
};
} else {
let insightsExe = findMcpTool();

// Force migration: if user has the old BinlogInsights.Mcp but not the
// new AITools.BinlogMcp, install the new one automatically.
if (insightsExe && insightsExe.includes('binlog-insights-mcp')) {
const newExeName = process.platform === 'win32' ? 'binlog-mcp.exe' : 'binlog-mcp';
const newExePath = path.join(os.homedir(), '.dotnet', 'tools', newExeName);
if (!fs.existsSync(newExePath)) {
const migrated = await installMcpTool();
if (migrated) {
insightsExe = migrated;
cachedMcpExePath = migrated;
vscode.window.showInformationMessage(
'🔄 Migrated from BinlogInsights.Mcp to AITools.BinlogMcp. You can uninstall the old tool: `dotnet tool uninstall -g BinlogInsights.Mcp`',
'Copy Command'
).then(sel => {
if (sel === 'Copy Command') {
vscode.env.clipboard.writeText('dotnet tool uninstall -g BinlogInsights.Mcp');
}
});
}
}
}

if (!insightsExe) {
insightsExe = await installMcpTool();
// After install, start the tree client (it skipped earlier because tool wasn't found)
Expand Down Expand Up @@ -2280,13 +2303,14 @@ async function fetchAboutInfo(mode: 'interactive' | 'auto' | 'silent') {
async function getInstalledMcpVersion(toolPath: string): Promise<string | null> {
// Primary: read version from the .store directory (works for all versions, even old ones without --version)
try {
const storeDir = path.join(os.homedir(), '.dotnet', 'tools', '.store', 'aitools.binlogmcp');
if (fs.existsSync(storeDir)) {
const versions = fs.readdirSync(storeDir).filter(d => /^\d+\.\d+\.\d+/.test(d));
if (versions.length > 0) {
// Sort and pick the highest (there should only be one for a global tool)
versions.sort(compareVersions);
return versions[versions.length - 1];
for (const storeId of ['aitools.binlogmcp', 'binloginsights.mcp']) {
const storeDir = path.join(os.homedir(), '.dotnet', 'tools', '.store', storeId);
if (fs.existsSync(storeDir)) {
const versions = fs.readdirSync(storeDir).filter(d => /^\d+\.\d+\.\d+/.test(d));
if (versions.length > 0) {
versions.sort(compareVersions);
return versions[versions.length - 1];
}
}
}
} catch { /* fall through */ }
Expand Down Expand Up @@ -2420,26 +2444,36 @@ function findMcpTool(): string | null {

const homeDir = os.homedir();
const isWindows = process.platform === 'win32';
const exeName = isWindows ? 'binlog-mcp.exe' : 'binlog-mcp';

// Look for both the new (AITools.BinlogMcp → binlog-mcp) and old
// (BinlogInsights.Mcp → binlog-insights-mcp) executables so existing
// users aren't broken on upgrade.
const candidates = isWindows
? ['binlog-mcp.exe', 'binlog-insights-mcp.exe']
: ['binlog-mcp', 'binlog-insights-mcp'];

// Global dotnet tools are installed in ~/.dotnet/tools/
const globalToolPath = path.join(homeDir, '.dotnet', 'tools', exeName);
if (fs.existsSync(globalToolPath)) {
cachedMcpExePath = globalToolPath;
return globalToolPath;
for (const exeName of candidates) {
const globalToolPath = path.join(homeDir, '.dotnet', 'tools', exeName);
if (fs.existsSync(globalToolPath)) {
cachedMcpExePath = globalToolPath;
return globalToolPath;
}
}

// Also check PATH
const pathDirs = (process.env.PATH || '').split(path.delimiter);
for (const dir of pathDirs) {
const candidate = path.join(dir, exeName);
try {
if (fs.existsSync(candidate)) {
cachedMcpExePath = candidate;
return candidate;
for (const exeName of candidates) {
for (const dir of pathDirs) {
const candidate = path.join(dir, exeName);
try {
if (fs.existsSync(candidate)) {
cachedMcpExePath = candidate;
return candidate;
}
} catch {
// ignore permission errors
}
} catch {
// ignore permission errors
}
}

Expand Down
Loading