This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
These rules override all other instructions:
- NEVER commit directly to main - Always create a feature branch and submit a pull request
- Conventional commits - Format:
type(scope): description - GitHub Issues for TODOs - Use
ghCLI to manage issues, no local TODO files. Use conventional commit format for issue titles - Pull Request titles - Use conventional commit format (same as commits)
- Branch naming - Use format:
type/scope/short-description(e.g.,feat/tracing/add-batch-processor) - Working an issue - Always create a new branch from an updated main branch
- Check branch status before pushing - Verify the remote tracking branch still exists. If a PR was merged/deleted, create a new branch from main instead
- Microsoft coding guidelines - Follow Microsoft C# coding conventions and .NET library design guidelines
- Write tests - All new/refactored code requires tests where applicable
- Run validation before commits - Run
dotnet buildand verify no errors before committing - No co-authors - Do not add co-author information on commits or pull requests
- No "generated by" statements - Do not add generated-by statements on pull requests
gh issue list # List open issues
gh issue view <number> # View details
gh issue create --title "type(scope): description" --body "..."
gh issue close <number>| Type | Description |
|---|---|
feat |
New feature |
fix |
Bug fix |
docs |
Documentation only |
refactor |
Code change that neither fixes a bug nor adds a feature |
test |
Adding or updating tests |
chore |
Maintenance tasks |
perf |
Performance improvement |
ci |
CI/CD changes |
Otel4Vsix is a .NET Framework 4.8 library that provides OpenTelemetry support for Visual Studio 2022+ extensions. It offers tracing, metrics, logging, and exception tracking capabilities with minimal configuration.
NuGet Package: CodingWithCalvin.Otel4Vsix
# Restore and build
dotnet build src/CodingWithCalvin.Otel4Vsix.slnx
# Build Release
dotnet build src/CodingWithCalvin.Otel4Vsix.slnx --configuration Release
# Create NuGet package
dotnet pack src/CodingWithCalvin.Otel4Vsix/CodingWithCalvin.Otel4Vsix.csproj --configuration Release --output ./nupkgThe library follows a static facade pattern for ease of use:
- VsixTelemetry.cs - Main static entry point providing
Tracer,Meter,Logger, and exception tracking - TelemetryConfiguration.cs - Configuration options (service name, OTLP endpoint, exporters, etc.)
- Tracing/ActivitySourceProvider.cs - Manages
ActivitySourcefor creating spans - Metrics/MetricsProvider.cs - Manages
Meterfor counters, histograms, gauges - Logging/LoggerProvider.cs - Wraps
ILoggerFactoryfor OpenTelemetry-integrated logging - Exceptions/ExceptionTracker.cs - Captures exceptions manually and via global handlers
- Thread-safe static initialization via
VsixTelemetry.Initialize() - Conditional exporters: OTLP (gRPC/HTTP) and Console
- Global exception handler hooks into
AppDomain.UnhandledException - SourceLink enabled for debugging into NuGet source
- All public APIs have XML documentation
- OpenTelemetry (>= 1.7.0)
- OpenTelemetry.Exporter.OpenTelemetryProtocol
- OpenTelemetry.Exporter.Console
- Microsoft.Extensions.Logging
- Microsoft.VisualStudio.SDK (>= 17.0)
- Merge PRs to main
- Push a version tag:
git tag v1.0.0 && git push origin v1.0.0 - GitHub Action automatically:
- Builds and packs with that version
- Creates GitHub release with changelog
- Publishes to NuGet.org
Problem: Visual Studio 2022+ bundles its own versions of OpenTelemetry and Microsoft.Extensions.* libraries in PublicAssemblies and CommonExtensions. If your extension ships different versions, you'll get MissingMethodException or assembly binding failures.
VS Bundled Versions (as of Dec 2025):
| Library | VS 2022 | VS 2026 |
|---|---|---|
| OpenTelemetry | 1.9.0 | 1.12.0 |
| Microsoft.Extensions.* | 9.0 | 9.0 |
| System.Diagnostics.DiagnosticSource | 9.0 | 9.0 |
Solution:
- Use OpenTelemetry 1.10.0 (compatible with 9.0 dependencies)
- Do NOT use OpenTelemetry 1.14.0+ (requires DiagnosticSource 10.0)
- Ship OpenTelemetry DLLs separately (not merged) so they're found before VS's copies
Problem: Using ILRepack with Internalize="true" corrupts protobuf serialization, causing OTLP backends to reject requests with "failed to parse OTLP request body".
Solution: Disable ILRepack entirely (<ILRepackEnabled>false</ILRepackEnabled>). Ship all OpenTelemetry assemblies as separate NuGet dependencies.
Problem: When configuring OtlpExporterOptions.Endpoint programmatically, the OpenTelemetry .NET SDK does NOT automatically append signal-specific paths (/v1/traces, /v1/metrics, /v1/logs). All signals get sent to the same URL, causing HTTP 400 errors.
Solution: Manually append signal paths in ConfigureOtlpExporter() based on signal type:
var signalPath = signalType switch
{
OtlpSignalType.Traces => "/v1/traces",
OtlpSignalType.Metrics => "/v1/metrics",
OtlpSignalType.Logs => "/v1/logs",
_ => "/v1/traces"
};
endpoint = baseUrl.TrimEnd('/') + signalPath;Problem: If Google.Protobuf is merged via ILRepack or not available at runtime, protobuf serialization fails.
Solution: Reference Google.Protobuf as a regular NuGet dependency (not PrivateAssets="all") so it flows to consumers and ships with the extension.