Skip to content

Commit 884e174

Browse files
Bump version to 0.10.17
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 8203083 commit 884e174

12 files changed

Lines changed: 1108 additions & 86 deletions

CHANGELOG.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,34 @@
11
# Changelog
22

3+
## 0.10.17 (Preview)
4+
5+
### Added
6+
- **Language Model Tools** — 5 LM-tool wrappers (`binlog_lm_overview`, `binlog_lm_errors`, `binlog_lm_search`, `binlog_lm_perf`, `binlog_lm_compare`) registered via `vscode.lm.registerTool` so any agent (@workspace, agent mode, custom chat modes) can analyze loaded binlogs — not just `@binlog`
7+
- **"Ask @binlog" CodeAction** — click a build error/warning squiggle in the editor → Quick Fix → "Ask @binlog about this error" or "Fix with @binlog"
8+
- **Auto-fix diagnostic** — right-click any error/warning in the Binlog Explorer → "Auto-fix with Copilot" opens agent mode to edit the source file directly
9+
- **Diagnostic context menu** — right-click error/warning tree items for "Ask @binlog about this issue" and "Auto-fix with Copilot"
10+
- **Fix All: before/after comparison** — "Fix All Issues" now writes to a new `{name}_fixed_{N}.binlog` (preserving the original) and auto-loads both for `/compare`
11+
- **`/timeline` command playbook**`/timeline` now has its own per-command instruction file
12+
- **esbuild bundling** — extension ships as a single `dist/extension.js` (~476 KB) instead of raw TypeScript output
13+
- **CI matrix** — GitHub Actions workflow runs on both Ubuntu and Windows
14+
15+
### Changed
16+
- **Prompt refactor** — SYSTEM_PROMPT and COMMAND_PROMPTS moved to lazy-loaded markdown playbooks (`resources/playbooks/`). Total prompt budget ~250 tokens baseline vs ~1500 before
17+
- **Auto-greeting** — loading a binlog now fires `@binlog /summary` automatically instead of asking "What would you like to analyze?"
18+
- **Multi-binlog support** — all MCP tool calls (tree view, document provider, timeline, extension commands) now auto-inject `binlog_file` for the primary binlog when multiple are loaded
19+
20+
### Fixed
21+
- **MCP startup race** — auto-greeting now waits for both MCP config AND tree client initialization before firing `/summary`
22+
- **LM-tool readiness** — wrappers wait up to 10s for MCP client to become ready instead of immediately returning "No binlog loaded"
23+
- **Cross-machine file navigation** — diagnostics and tree view items from binlogs built on other machines (CI, coworkers) no longer show "file not found" — paths are resolved against workspace folders
24+
- **Multi-root workspace path resolution**`resolveFilePath` now checks each workspace folder for file existence instead of blindly using the first
25+
- **MCP timer leak**`setTimeout` in `sendRequest` is now cleared on resolve/reject
26+
- **Spawn error handler** — missing `error` event listener on MCP subprocess no longer crashes the extension host
27+
- **processResponse error retry** — recursive tool-call retry now checks all 5 error patterns (was missing `role 'tool'`, `tool_call_id`, `400`)
28+
- **CodeAction cap** — max 5 diagnostics per `provideCodeActions` call to prevent unusable Quick Fix menus
29+
- **Cross-platform tests**`workspaceMatchesBinlog` and `getSourceLabel` no longer depend on `path.sep` (fixes CI on Ubuntu)
30+
- **Stale tool names in prompts**`analyzeInChat` prompts no longer reference non-existent tools (`binlog_search_targets`, etc.)
31+
332
## 0.10.16 (Preview)
433

534
### Fixed

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,17 @@ The [BinlogInsights.Mcp](https://www.nuget.org/packages/BinlogInsights.Mcp) serv
2525

2626
| Feature | Description |
2727
|---------|-------------|
28-
| **@binlog Chat** | Ask Copilot about errors, performance, targets, imports, NuGet issues — with slash commands like `/errors`, `/perf`, `/timeline`, `/compare` |
28+
| **@binlog Chat** | Ask Copilot about errors, performance, targets, imports, NuGet issues — with slash commands like `/errors`, `/perf`, `/timeline`, `/compare`, `/summary`, `/incremental`, `/buildcheck`, `/search`, `/targets`, `/properties`, `/items`, `/propertyhistory` |
2929
| **Build & Collect** | Build a project and capture a `.binlog` in one step |
3030
| **Binlog Explorer** | Sidebar tree with project → target → task hierarchy, errors, warnings, performance |
3131
| **Build Timeline** | Visual bar charts of target/task durations with click-to-analyze in Copilot |
32+
| **Fix All Issues** | Copilot fixes all build errors/warnings, rebuilds, and loads before/after for comparison |
33+
| **Auto-fix Diagnostic** | Right-click any error/warning in the tree → "Auto-fix with Copilot" to fix it directly |
3234
| **Optimize Build** | Pick optimizations, Copilot applies changes, verify with A/B comparison |
35+
| **Build Analysis Mode** | Chat mode pre-configured with BinlogInsights MCP tools — works with any agent |
36+
| **Language Model Tools** | `binlog_lm_overview`, `binlog_lm_errors`, `binlog_lm_search`, `binlog_lm_perf`, `binlog_lm_compare` — available to @workspace, agent mode, and custom chat modes |
3337
| **CI/CD Integration** | Download binlogs from Azure DevOps Pipelines and GitHub Actions — filter by branch or PR |
34-
| **Problems Panel** | Build diagnostics as native VS Code errors/warnings with per-project CodeLens |
38+
| **Problems Panel** | Build diagnostics as native VS Code errors/warnings with per-project CodeLens and "Ask @binlog" CodeActions |
3539
| **Search** | Search across all build events — targets, tasks, messages, properties |
3640

3741
## Configuration

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "binlog-analyzer",
33
"displayName": "MSBuild Binlog Analyzer",
44
"description": "Analyze MSBuild binary logs with Copilot Chat and MCP tools",
5-
"version": "0.10.30",
5+
"version": "0.10.17",
66
"preview": true,
77
"publisher": "dotutils",
88
"license": "MIT",
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Use `binlog_lm_overview` (or `binlog_overview`). Output: result, duration, project count, error/warning counts, anything visibly unusual. ≤ 8 short lines.
1+
Use `binlog_lm_overview` (or `binlog_overview`). The `projectCount` from overview counts solution-level evaluations, not actual projects — if it's very low (1-2), also call `binlog_projects` to get the real project count. Output: result, duration, actual project count, error/warning counts, anything visibly unusual. ≤ 8 short lines.

src/binlogDocumentProvider.ts

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,20 @@ export class BinlogDocumentProvider implements vscode.TextDocumentContentProvide
2020
this.cache.clear();
2121
}
2222

23+
/**
24+
* Wrapper around mcpClient.callTool that auto-injects binlog_file
25+
* for the primary (first) loaded binlog. Without this, multi-binlog
26+
* mode causes "requires explicit binlog_file" errors in every
27+
* document render call.
28+
*/
29+
private async call(tool: string, args: Record<string, unknown> = {}): Promise<{ text: string }> {
30+
if (!this.mcpClient) { throw new Error('MCP server not connected'); }
31+
if (!args.binlog_file && this.mcpClient.loadedBinlogs.length > 1) {
32+
args.binlog_file = this.mcpClient.loadedBinlogs[0];
33+
}
34+
return this.mcpClient.callTool(tool, args);
35+
}
36+
2337
invalidate(uri: vscode.Uri) {
2438
this.cache.delete(uri.toString());
2539
this._onDidChange.fire(uri);
@@ -82,7 +96,7 @@ export class BinlogDocumentProvider implements vscode.TextDocumentContentProvide
8296

8397
// Build overview
8498
try {
85-
const overviewResult = await this.mcpClient!.callTool('binlog_overview');
99+
const overviewResult = await this.call('binlog_overview');
86100
const ov = JSON.parse(overviewResult.text);
87101
const status = ov.succeeded ? '✅ BUILD SUCCEEDED' : '❌ BUILD FAILED';
88102
const dur = ov.duration || '';
@@ -110,7 +124,7 @@ export class BinlogDocumentProvider implements vscode.TextDocumentContentProvide
110124

111125
// Projects
112126
try {
113-
const projResult = await this.mcpClient!.callTool('binlog_projects');
127+
const projResult = await this.call('binlog_projects');
114128
const projData = JSON.parse(projResult.text);
115129

116130
// Handle both formats: array (BinlogInsights) and object (baronfel)
@@ -141,8 +155,8 @@ export class BinlogDocumentProvider implements vscode.TextDocumentContentProvide
141155
let diagsByProject: Map<string, { errors: number; warnings: number }> | undefined;
142156
try {
143157
const [errResult, warnResult] = await Promise.allSettled([
144-
this.mcpClient!.callTool('binlog_errors'),
145-
this.mcpClient!.callTool('binlog_warnings'),
158+
this.call('binlog_errors'),
159+
this.call('binlog_warnings'),
146160
]);
147161
diagsByProject = new Map();
148162
for (const result of [errResult, warnResult]) {
@@ -188,8 +202,8 @@ export class BinlogDocumentProvider implements vscode.TextDocumentContentProvide
188202
// Diagnostics
189203
try {
190204
const [errResult, warnResult] = await Promise.allSettled([
191-
this.mcpClient!.callTool('binlog_errors'),
192-
this.mcpClient!.callTool('binlog_warnings'),
205+
this.call('binlog_errors'),
206+
this.call('binlog_warnings'),
193207
]);
194208

195209
const parseItems = (r: PromiseSettledResult<any>) => {
@@ -237,7 +251,7 @@ export class BinlogDocumentProvider implements vscode.TextDocumentContentProvide
237251

238252
// Performance
239253
try {
240-
const targetsResult = await this.mcpClient!.callTool('binlog_expensive_targets', { top_number: 10 });
254+
const targetsResult = await this.call('binlog_expensive_targets', { top_number: 10 });
241255
const targetsData = JSON.parse(targetsResult.text);
242256
lines.push('🔥 SLOWEST TARGETS');
243257
lines.push('─────────────────────────────────────────────────────');
@@ -250,7 +264,7 @@ export class BinlogDocumentProvider implements vscode.TextDocumentContentProvide
250264
lines.push('');
251265

252266
try {
253-
const tasksResult = await this.mcpClient!.callTool('binlog_expensive_tasks', { top_number: 10 });
267+
const tasksResult = await this.call('binlog_expensive_tasks', { top_number: 10 });
254268
const tasksData = JSON.parse(tasksResult.text);
255269
lines.push('🔧 SLOWEST TASKS');
256270
lines.push('─────────────────────────────────────────────────────');
@@ -263,7 +277,7 @@ export class BinlogDocumentProvider implements vscode.TextDocumentContentProvide
263277

264278
// Analyzers
265279
try {
266-
const analyzersResult = await this.mcpClient!.callTool('binlog_expensive_analyzers', { limit: 10 });
280+
const analyzersResult = await this.call('binlog_expensive_analyzers', { limit: 10 });
267281
const analyzersData = JSON.parse(analyzersResult.text);
268282
const entries = this.parsePerfEntries(analyzersData);
269283
if (entries.length > 0) {
@@ -300,7 +314,7 @@ export class BinlogDocumentProvider implements vscode.TextDocumentContentProvide
300314

301315
// Get per-project target times
302316
try {
303-
const targetTimesResult = await this.mcpClient!.callTool('binlog_project_target_times', {
317+
const targetTimesResult = await this.call('binlog_project_target_times', {
304318
project: projectName,
305319
});
306320
const targetData = JSON.parse(targetTimesResult.text);
@@ -330,7 +344,7 @@ export class BinlogDocumentProvider implements vscode.TextDocumentContentProvide
330344
} catch {
331345
// Try fallback: binlog_expensive_projects for at least a total time
332346
try {
333-
const buildTimeResult = await this.mcpClient!.callTool('binlog_expensive_projects');
347+
const buildTimeResult = await this.call('binlog_expensive_projects');
334348
const data = JSON.parse(buildTimeResult.text);
335349
const projects = Array.isArray(data) ? data : [];
336350
const match = projects.find((p: any) =>
@@ -348,8 +362,8 @@ export class BinlogDocumentProvider implements vscode.TextDocumentContentProvide
348362
// Get diagnostics and filter for this project
349363
try {
350364
const [errResult, warnResult] = await Promise.allSettled([
351-
this.mcpClient!.callTool('binlog_errors'),
352-
this.mcpClient!.callTool('binlog_warnings'),
365+
this.call('binlog_errors'),
366+
this.call('binlog_warnings'),
353367
]);
354368

355369
const parseItems = (r: PromiseSettledResult<any>) => {
@@ -414,18 +428,18 @@ export class BinlogDocumentProvider implements vscode.TextDocumentContentProvide
414428
}
415429

416430
private async renderProjects(): Promise<string> {
417-
const result = await this.mcpClient!.callTool('binlog_projects');
431+
const result = await this.call('binlog_projects');
418432
return this.formatSection('PROJECTS', result.text);
419433
}
420434

421435
private async renderDiagnostics(type: 'errors' | 'warnings'): Promise<string> {
422436
const tool = type === 'errors' ? 'binlog_errors' : 'binlog_warnings';
423-
const result = await this.mcpClient!.callTool(tool);
437+
const result = await this.call(tool);
424438
return this.formatSection(type.toUpperCase(), result.text);
425439
}
426440

427441
private async renderExpensive(tool: string, title: string): Promise<string> {
428-
const result = await this.mcpClient!.callTool(tool, { top_number: 20 });
442+
const result = await this.call(tool, { top_number: 20 });
429443
return this.formatSection(title.toUpperCase(), result.text);
430444
}
431445

0 commit comments

Comments
 (0)