Skip to content

Commit e5ce244

Browse files
committed
Add multi-version workspace and comparison tools
1 parent f0c39c1 commit e5ce244

70 files changed

Lines changed: 3646 additions & 1228 deletions

Some content is hidden

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

.github/copilot-instructions.md

Lines changed: 32 additions & 233 deletions
Original file line numberDiff line numberDiff line change
@@ -1,249 +1,48 @@
11
# DecompilerServer Copilot Instructions
22

3-
## Project Overview
3+
Read these files first:
4+
- `ARCHITECTURE.md` for durable technical rules and contracts
5+
- `README.md` for user-facing workflow
6+
- `TODO.md` for backlog
47

5-
This is a **DecompilerServer** project that implements an MCP (Model Context Protocol) server for decompiling and analyzing .NET assemblies, specifically focused on Unity's Assembly-CSharp.dll files. The server provides comprehensive decompilation, search, and analysis capabilities through various endpoints.
8+
## Repository-Specific Rules
69

7-
## Key Technologies & Frameworks
10+
- MCP tools live as static methods under `Tools/`.
11+
- Tools should return via `ResponseFormatter.TryExecute(...)`.
12+
- Discovery/search tools should route with `ToolSessionRouter.GetForContext(...)`.
13+
- `memberId` follow-up tools should route with `ToolSessionRouter.GetForMember(...)`.
14+
- Reuse `TypeSurfaceComparer` for type-surface semantics instead of duplicating compare logic.
15+
- Use `DecompilerService.DecompileEntitySnippet(...)` for focused compare body retrieval.
16+
- Prefer structured JSON output over pre-rendered diff text for overview commands.
817

9-
- **.NET 8.0** - Target framework
10-
- **ICSharpCode.Decompiler** - Core decompilation engine
11-
- **Microsoft.Extensions.Hosting** - Hosting and dependency injection
12-
- **ModelContextProtocol** - MCP server implementation
13-
- **System.Text.Json** - JSON serialization with camelCase naming
14-
- **xUnit** - Testing framework
18+
## Workspace and Compare Expectations
1519

16-
## Project Structure
20+
- Assume multi-context workspace support is the primary model.
21+
- Preserve stable member ID format: `<mvid-32hex>:<token-8hex>:<kind-code>`.
22+
- `compare_contexts` is structural. `changed` means direct member surface changed.
23+
- `compare_symbols(compareMode: "body")` is method-only and should stay opt-in.
24+
- Do not broaden compare semantics casually; update `ARCHITECTURE.md` if a durable contract changes.
1725

18-
```
19-
DecompilerServer/
20-
├── Services/ # Core service implementations
21-
│ ├── AssemblyContextManager.cs # Assembly loading and context management
22-
│ ├── DecompilerService.cs # C# decompilation with caching
23-
│ ├── MemberResolver.cs # Member ID resolution and normalization
24-
│ ├── SearchServiceBase.cs # Base search and pagination functionality
25-
│ ├── UsageAnalyzer.cs # Code usage analysis
26-
│ ├── InheritanceAnalyzer.cs # Inheritance relationship analysis
27-
│ └── ResponseFormatter.cs # JSON response formatting
28-
├── Tools/ # MCP tool implementations (static methods)
29-
│ ├── ResolveMemberId.cs # Member ID validation
30-
│ ├── ListNamespaces.cs # Namespace enumeration
31-
│ ├── SearchTypes.cs # Type discovery with search
32-
│ ├── GetDecompiledSource.cs # Core decompilation to C#
33-
│ ├── GetSourceSlice.cs # Source code range viewing
34-
│ └── GetMemberDetails.cs # Rich member metadata
35-
├── Tests/ # xUnit test suite
36-
├── TestLibrary/ # Test assembly for validation
37-
├── ServiceLocator.cs # Service locator for MCP tools
38-
├── Program.cs # Application entry point
39-
└── *.md # Documentation files
40-
```
41-
42-
## Documentation
43-
44-
### Developer Guides
45-
- **[HELPER_METHODS_GUIDE.md](../HELPER_METHODS_GUIDE.md)** - Comprehensive guide to all service helper methods and implementation patterns for MCP tools. Essential reading for understanding the service architecture and implementing new endpoints.
46-
- **[TESTING.md](../TESTING.md)** - Complete testing framework documentation covering xUnit setup, test data structure, and testing patterns. Required reading for writing tests and understanding the test infrastructure.
47-
- **[TODO.md](../TODO.md)** - Comprehensive list of prioritized TODOs and enhancement opportunities based on thorough code review. Organized by priority and complexity for systematic AI-assisted development. Contains detailed context and reasoning for each improvement.
48-
49-
All guides are actively maintained and provide crucial implementation guidance for developers working on the DecompilerServer.
50-
51-
## Core Architecture Principles
52-
53-
### Member ID System
54-
- **Format**: `<mvid-32hex>:<token-8hex>:<kind-code>`
55-
- **Kind Codes**: T=Type, M=Method/Constructor, P=Property, F=Field, E=Event, N=Namespace
56-
- All member IDs must be stable and consistent across sessions
57-
58-
### Threading & Performance
59-
- Use `ReaderWriterLockSlim` for thread-safe access (fast reads, guarded writes)
60-
- Implement lazy indexing - build minimal maps on first access
61-
- Cache decompiled source with line indexing for efficient slicing
62-
- Always paginate results (default limit: 50, max: 500)
63-
64-
### Error Handling
65-
- Return structured errors: `{ error: { code, message, detail? } }`
66-
- Never throw exceptions across MCP boundaries
67-
- Handle assembly loading failures gracefully
68-
69-
## Code Style & Conventions
70-
71-
### Formatting
72-
- **Important**: Run `dotnet format DecompilerServer.sln` before committing
73-
- During development, focus on functionality over formatting
74-
- The formatter will handle code style consistency
26+
## Testing
7527

76-
### Naming Conventions
77-
- Use PascalCase for public members and types
78-
- Use camelCase for private fields and local variables
79-
- Prefix private fields with underscore (`_fieldName`)
80-
- Use descriptive names for member IDs and handles
28+
- Use xUnit and real compiled test assemblies.
29+
- `Tests/ServiceTestBase.cs` is the base fixture for service-level tests.
30+
- Add dedicated `*ToolTests.cs` files for MCP tool behavior.
31+
- Use `Tests/TemporaryAssemblyBuilder.cs` for controlled version-drift and compare tests.
32+
- When tests need workspace-aware behavior, register `DecompilerWorkspace` in the test service provider.
8133

82-
### JSON Serialization
83-
- Use camelCase property naming
84-
- Ignore null values in output
85-
- Ensure deterministic ordering for stable diffs
34+
## Verification
8635

87-
## Development Workflow
36+
Run after code changes:
8837

89-
### Building & Testing
9038
```bash
91-
# Build the solution
92-
dotnet build DecompilerServer.sln
93-
94-
# Run tests
95-
dotnet test DecompilerServer.sln
96-
97-
# Format code before committing
9839
dotnet format DecompilerServer.sln
40+
dotnet test -c Release --no-restore
9941
```
10042

101-
### Test Strategy
102-
- All service helpers have comprehensive tests using real test assembly
103-
- Use `ServiceTestBase` for integration tests with loaded test.dll
104-
- Validate both functionality and output format
105-
- Test with various C# constructs (generics, inheritance, attributes, etc.)
106-
107-
## Key Implementation Guidelines
108-
109-
### Assembly Context Management
110-
- Maintain single in-memory context with PEFile, UniversalAssemblyResolver, DecompilerTypeSystem
111-
- Load assemblies with `PEStreamOptions.PrefetchEntireImage` (or equivalent in-memory loading) so the source DLL is not kept locked on disk
112-
- Configure resolver with appropriate search directories (Game*_Data/Managed, Unity directories)
113-
- Use proper decompiler settings (UsingDeclarations, ShowXmlDocumentation, NamedArguments)
114-
- `Unload` should clear the current assembly context and caches without disposing the singleton `AssemblyContextManager`; reserve `Dispose()` for service/provider shutdown
115-
116-
### Search & Pagination
117-
- Implement cursor-based pagination for all search endpoints
118-
- Support filtering by accessibility, member types, namespaces
119-
- Return structured results with `{ items, nextCursor, totalEstimate }`
120-
121-
### Source Management
122-
- Cache decompiled C# source with line indexing
123-
- Support ranged retrieval without re-decompilation
124-
- Include proper headers/footers and maintain source document metadata
125-
- When decompiling nested types by name, prefer reflection names such as `Outer+Inner`; dotted names such as `Outer.Inner` can fail in ILSpy lookup paths even when the type exists in metadata.
126-
127-
### IL Handling
128-
- Use ICSharpCode.Decompiler.Disassembler for readable IL output
129-
- Leverage MetadataReader, avoid reflection-only loading
130-
- Provide both IL and decompiled C# views
131-
132-
## Common Patterns
133-
134-
**See [HELPER_METHODS_GUIDE.md](../HELPER_METHODS_GUIDE.md) for comprehensive service helper documentation and implementation patterns.**
135-
136-
### Service Dependencies
137-
Services typically depend on:
138-
- `AssemblyContextManager` - for assembly access
139-
- `MemberResolver` - for ID resolution and validation
140-
- Other services as needed for specific functionality
141-
142-
### MCP Tool Dependencies
143-
MCP tools (static methods) access services via:
144-
- `ServiceLocator.ContextManager` - assembly context access
145-
- `ServiceLocator.MemberResolver` - member ID operations
146-
- `ServiceLocator.DecompilerService` - source decompilation
147-
- `ServiceLocator.ResponseFormatter` - consistent JSON responses
148-
149-
### Response Models
150-
Use consistent model types (defined in shared Models.cs):
151-
- `MemberHandle`, `MemberSummary`, `SearchResult<T>`
152-
- `MemberDetails`, `SourceDocument`, `SourceSlice`
153-
- `UsageRef`, `GraphResult`, `Stats`
154-
155-
### Error Responses
156-
Always return structured error objects rather than throwing exceptions when implementing MCP endpoints.
157-
158-
## Testing Considerations
159-
160-
- Use the TestLibrary project for consistent test data
161-
- Test with various C# language features and constructs
162-
- Validate both service functionality and JSON output format
163-
- Ensure thread safety in concurrent scenarios
164-
- Test pagination and cursor handling
165-
166-
**See [TESTING.md](../TESTING.md) for complete testing framework documentation and best practices.**
167-
168-
### MCP Tool Testing Patterns
169-
When implementing MCP tools (static methods), follow these patterns:
170-
171-
- **ServiceLocator Setup**: Create a service provider in test constructor and register all required services:
172-
```csharp
173-
public ToolImplementationTests()
174-
{
175-
var services = new ServiceCollection();
176-
services.AddSingleton(ContextManager);
177-
services.AddSingleton(MemberResolver);
178-
services.AddSingleton<DecompilerService>();
179-
services.AddSingleton<UsageAnalyzer>();
180-
services.AddSingleton<InheritanceAnalyzer>();
181-
services.AddSingleton<ResponseFormatter>();
182-
183-
_serviceProvider = services.BuildServiceProvider();
184-
ServiceLocator.SetServiceProvider(_serviceProvider);
185-
}
186-
```
187-
188-
- **Service Dependencies**: Always register services in the correct dependency order:
189-
1. `AssemblyContextManager` (core, no dependencies)
190-
2. `MemberResolver` (depends on AssemblyContextManager)
191-
3. All other services (DecompilerService, UsageAnalyzer, etc.)
192-
4. `ResponseFormatter` (standalone)
193-
194-
- **Test Cleanup**: Do NOT override Dispose() with [Fact] attribute - this causes xUnit errors. Let ServiceTestBase handle disposal naturally.
195-
196-
- **SearchService Pattern**: When tools need SearchServiceBase functionality, create a concrete implementation:
197-
```csharp
198-
internal class SearchService : SearchServiceBase
199-
{
200-
public SearchService(AssemblyContextManager contextManager, MemberResolver memberResolver)
201-
: base(contextManager, memberResolver) { }
202-
}
203-
```
204-
205-
## Performance Optimization
206-
207-
- Implement lazy loading for expensive operations
208-
- Use concurrent collections for thread-safe caching
209-
- Build indexes incrementally rather than upfront
210-
- Consider memory usage when caching large decompiled sources
211-
212-
## MCP Tool Implementation Guidelines
213-
214-
### Static Method Pattern
215-
MCP tools must be implemented as static methods with specific attributes:
216-
```csharp
217-
[McpServerTool, Description("Tool description")]
218-
public static string ToolName(parameters...)
219-
{
220-
return ResponseFormatter.TryExecute(() =>
221-
{
222-
// Access services via ServiceLocator
223-
var service = ServiceLocator.GetRequiredService<ServiceType>();
224-
// Implementation logic
225-
return result;
226-
});
227-
}
228-
```
229-
230-
### ServiceLocator Usage
231-
- Use ServiceLocator pattern to provide dependency injection for static MCP tools
232-
- Always check if assembly is loaded before performing operations
233-
- Use ResponseFormatter.TryExecute() for consistent error handling across all tools
234-
235-
## Final Development Step
236-
237-
**Before completing any major work or making the final commit, always review and update `.github/copilot-instructions.md` if:**
238-
- You encountered unexpected patterns or pitfalls during development
239-
- New architectural patterns or testing approaches were discovered
240-
- Additional framework-specific guidance would help future development
241-
- The current instructions have become outdated or incomplete
242-
243-
**When working on improvements, refer to [TODO.md](../TODO.md) for:**
244-
- Prioritized list of enhancement opportunities
245-
- Detailed context and reasoning for each improvement
246-
- Implementation guidelines and testing requirements
247-
- Technical debt items and maintenance tasks
43+
## Documentation Policy
24844

249-
This ensures knowledge from each development cycle is captured for improved efficiency in future work, and provides a systematic approach to project enhancement.
45+
- Keep durable technical content in `ARCHITECTURE.md`.
46+
- Keep `README.md` user-facing.
47+
- Keep `TODO.md` backlog-focused.
48+
- Do not add new helper, testing, or plan documents unless there is a durable need that cannot fit those files.

AGENTS.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
Use .github/copilot-instructions.md for more information. It contains everything this file should have
1+
Read `.github/copilot-instructions.md` for repository-specific working rules.
2+
3+
Read `ARCHITECTURE.md` for the durable technical reference and `TODO.md` for backlog.
4+
5+
Do not reintroduce deleted helper, testing, plan, or implementor docs unless the information is durable and cannot live in `README.md`, `ARCHITECTURE.md`, or `TODO.md`.

0 commit comments

Comments
 (0)