Repository navigation
feat: add analyze tool for project-scoped cop diagnostics - #32
Merged
Merged
Conversation
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Fix 1: separate enrichment project from project scope filter; file/folder scoped calls without projectPath now auto-resolve the containing project via FindContainingProject (longest prefix match) and omit the project scope filter so the file/folder is the only scope - Fix 2: add IncludeUnlocated to AnalyzeFilter; Filter returns dropped count; succeeded=false warning always fires with raw+filtered counts; dropped-unlocated hint added when applicable - Fix 3: rename CompileFailed to ProxyCallFailed with descriptive message - Fix 4: extract Error() helper in AnalyzeTool for error envelope - Fix 5: replace hand-rolled ParseLocation scanner with [GeneratedRegex] Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Fix 1: make droppedUnlocated warning independent of succeeded flag - Fix 2: extract BuildWarnings to CompileDiagnosticsParser, replace tautological tests with four cases calling product code - Fix 3: validate explicit projectPath against known projects, return UnknownProject error with listed projects - Fix 4: collapse project-scope-filter if/else-if/else into single expression Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…shape ApplyFixThenCompileTests passed `onlyErrors` as a top-level al_compile argument, which almcp ignores; it only worked because an absent `options` object also defaults to `onlyErrors: false`. Nest it under `options` and say so in the docs that tell callers to pass `onlyErrors: false`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
analyzeMCP tool that wrapsal_compilewithonlyErrors=false,enableCodeAnalysis=trueand no diagnostic cap, then enriches each diagnostic with the owning analyzer name and whether a native code fix exists.CompileDiagnosticsParser— a pure, stateless parser for almcp'sal_compileresponse JSON that handles camelCase/PascalCase, numeric/string severities, theSourceFile(path@line:col)location format (including paths with parentheses and@), and message warnings.CreateProxyoverload toAlMcpFixturefor integration tests that need diagnostics from more than one AL project.What changed
src/ALCops.Mcp/Models/AnalyzeResult.cs— record types for the tool's JSON output:AnalyzeDiagnostic,AnalyzeSummary,AnalyzeResult.src/ALCops.Mcp/Services/CompileDiagnosticsParser.cs— static parser:Parse(CallToolResult and string overloads),ParseLocation,ExtractWarnings,IsCompilerDiagnostic,Enrich,Filter,Sort,Build. No BC types, no I/O.src/ALCops.Mcp/Tools/AnalyzeTool.cs— the MCP tool endpoint. Resolves the proxy viaIServiceProviderso it becomes{error:"ProxyUnavailable"}under--no-proxyinstead of a schema leak. Parameters:filePath,folderPath,projectPath,severities,analyzers,ruleIds,limit.tests/ALCops.Mcp.Tests/CompileDiagnosticsParserTests.cs— 26 pure unit tests covering location parsing, JSON deserialization (camelCase, PascalCase, numeric severities, missing code, unknown properties), CallToolResult extraction (structured wins, non-JSON fallback, no-JSON throws), warning extraction, compiler-diagnostic detection, enrichment, filtering (file path, folder prefix, project+file AND, unlocated, severities, analyzers, ruleIds), sorting and build (truncation, summary, key order).tests/ALCops.Mcp.Tests/AnalyzeToolTests.cs— 3 no-almcp unit tests (ProxyUnavailable when no proxy, ProxyUnavailable when almcp unavailable, schema check), 7[AlMcpFact]integration tests against a two-project workspace (project-scoped, default scope, explicit ProjB, filtered by rule+severity+project, limit truncation, Compiler analyzer filter, invalid limit).tests/ALCops.Mcp.Tests/AlMcpProxyTests.cs— addedCreateProxy(CapturingLogger, IReadOnlyList<string>)overload for multi-project fixtures.AGENTS.md,README.md,src/ALCops.Mcp/README.md— updated tool count from four to five, addedanalyzeto tool tables, documentedanalyzeas the preferred verification call, noted theal_compileonlyErrorsdefault.Behaviour changes
analyzeavailable whenalmcpis present (not under--no-proxy).ForwardAsync.McpHost.csis untouched;analyzeis auto-discovered viaWithToolsFromAssembly().Test plan
dotnet build --configuration Release— 0 warnings, 0 errorsdotnet test --configuration Release— 216 passed, 0 failed, 0 skippedProxyUnavailablewith message mentioning--no-proxyand "not available"servicesandcancellationTokenare hidden from the input schemalimit: 1producestruncated: truewithtotalCount > 1analyzers: ["Compiler"]returns onlyAL####diagnosticsCloses #31
Side observation (fixed in this PR)
ApplyFixThenCompileTestspassedonlyErrorsas a top-levelal_compileargument, which almcp ignores; the flag lives inside theoptionsobject. The tests still worked because an absentoptionsobject also defaults toonlyErrors: false(and disables the diagnostics cap), not because warnings survive an errors-only filter. The tests now passoptions: { onlyErrors: false }and the README/AGENTS.md wording names theoptionsobject.🤖 Generated with Claude Code