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
7 changes: 5 additions & 2 deletions .github/agents/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# ProjGraph Development Guidelines
# ProjGraph Development Guidelines

Auto-generated from all feature plans. Last updated: 2026-01-13

## Active Technologies

- .NET 10.0 (C# 14+) + Microsoft.CodeAnalysis.CSharp (Roslyn), ProjGraph.Lib.Core (004-config-class-members)

- .NET 10.0 (C# 14+) + `Microsoft.CodeAnalysis.CSharp`, `Spectre.Console` (003-mermaid-class-diagram)

- .NET 10.0 (C# 14+) + `Microsoft.CodeAnalysis.CSharp`, `Microsoft.CodeAnalysis.Workspaces.MSBuild`,
Expand All @@ -28,12 +30,13 @@ tests/

## Recent Changes

- 004-config-class-members: Added .NET 10.0 (C# 14+) + Microsoft.CodeAnalysis.CSharp (Roslyn), ProjGraph.Lib.Core

- 003-mermaid-class-diagram: Added .NET 10.0 (C# 14+) + `Microsoft.CodeAnalysis.CSharp`, `Spectre.Console`

- 002-dbcontext-erd: Added .NET 10.0 (C# 14+) + `Microsoft.CodeAnalysis.CSharp`,
`Microsoft.CodeAnalysis.Workspaces.MSBuild`, `Microsoft.EntityFrameworkCore` (for symbol analysis)

- 001-cli-graph-rendering: Added .NET 10.0 (C# 14+) + Buildalyzer (Parsing), Spectre.Console (CLI), ModelContextProtocol (MCP)

<!-- MANUAL ADDITIONS START -->
<!-- MANUAL ADDITIONS END -->
95 changes: 55 additions & 40 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,43 +13,58 @@ jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
cache: true
cache-dependency-path: Directory.Packages.props

- name: Restore dependencies
run: dotnet restore ProjGraph.slnx

- name: Build
run: |
VERSION=${GITHUB_REF_NAME#v}
dotnet build ProjGraph.slnx --no-restore --configuration Release -p:Version=$VERSION

- name: Test
run: dotnet test ProjGraph.slnx --no-build --configuration Release --verbosity normal

- name: Pack
run: |
VERSION=${GITHUB_REF_NAME#v}
dotnet pack ProjGraph.slnx --configuration Release --output ./artifacts -p:Version=$VERSION

- name: Publish to NuGet.org
run: dotnet nuget push ./artifacts/*.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }} --skip-duplicate

- name: Publish to GitHub Packages
run: |
dotnet nuget push ./artifacts/*.nupkg --source "https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json" --api-key ${{ secrets.GITHUB_TOKEN }} --skip-duplicate

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
files: artifacts/*
generate_release_notes: true
draft: false
prerelease: false
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Extract version from tag
id: get_version
run: |
VERSION=${GITHUB_REF_NAME#v}
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Version: $VERSION"

- name: Update Directory.Build.props version
run: |
sed -i "s/<Version>.*<\/Version>/<Version>${{ steps.get_version.outputs.version }}<\/Version>/" Directory.Build.props
echo "Updated Directory.Build.props:"
grep "<Version>" Directory.Build.props

- name: Update server.json version
run: |
sed -i "s/\"version\": \"[^\"]\+\"/\"version\": \"${{ steps.get_version.outputs.version }}\"/g" src/ProjGraph.Mcp/.mcp/server.json
echo "Updated server.json:"
grep "\"version\"" src/ProjGraph.Mcp/.mcp/server.json

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
cache: true
cache-dependency-path: Directory.Packages.props

- name: Restore dependencies
run: dotnet restore ProjGraph.slnx

- name: Build
run: dotnet build ProjGraph.slnx --no-restore --configuration Release

- name: Test
run: dotnet test ProjGraph.slnx --no-build --configuration Release --verbosity normal

- name: Pack
run: dotnet pack ProjGraph.slnx --configuration Release --output ./artifacts

- name: Publish to NuGet.org
run: dotnet nuget push ./artifacts/*.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }} --skip-duplicate

- name: Publish to GitHub Packages
run: |
dotnet nuget push ./artifacts/*.nupkg --source "https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json" --api-key ${{ secrets.GITHUB_TOKEN }} --skip-duplicate

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
files: artifacts/*
generate_release_notes: true
draft: false
prerelease: false
4 changes: 0 additions & 4 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
<Version>0.4.0</Version>
<Authors>HandyS11</Authors>
<Company>HandyS11</Company>
<PackageIcon>icon.png</PackageIcon>
<PackageProjectUrl>https://github.com/HandyS11/ProjGraph</PackageProjectUrl>
<RepositoryUrl>https://github.com/HandyS11/ProjGraph.git</RepositoryUrl>
<RepositoryType>git</RepositoryType>
Expand All @@ -32,9 +31,6 @@
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>

<ItemGroup Condition="'$(MSBuildProjectName)' == 'ProjGraph.Cli' OR '$(MSBuildProjectName)' == 'ProjGraph.Mcp'">
<None Include="$(MSBuildThisFileDirectory)icon.png" Pack="true" PackagePath=""/>
</ItemGroup>

<!-- Code Analyzers -->
<ItemGroup>
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,10 @@ AI: [Generates the database schema]

- **CLI Package**: [ProjGraph.Cli on NuGet](https://www.nuget.org/packages/ProjGraph.Cli)
- **MCP Package**: [ProjGraph.Mcp on NuGet](https://www.nuget.org/packages/ProjGraph.Mcp)

## 📚 Documentation

- [Architecture Overview](./ARCHITECTURE.md) - Solution structure and design decisions
- [Contributing Guide](./CONTRIBUTING.md) - How to contribute to the project
- [Security Policy](./SECURITY.md) - Security reporting guidelines

35 changes: 35 additions & 0 deletions specs/004-config-class-members/checklists/requirements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Specification Quality Checklist: Configure Class Member Visibility

**Purpose**: Validate specification completeness and quality before proceeding to planning
**Created**: 2026-02-16
**Feature**: [spec.md](../spec.md)

## Content Quality

- [x] No implementation details (languages, frameworks, APIs)
- [x] Focused on user value and business needs
- [x] Written for non-technical stakeholders
- [x] All mandatory sections completed

## Requirement Completeness

- [x] No [NEEDS CLARIFICATION] markers remain
- [x] Requirements are testable and unambiguous
- [x] Success criteria are measurable
- [x] Success criteria are technology-agnostic (no implementation details)
- [x] All acceptance scenarios are defined
- [x] Edge cases are identified
- [x] Scope is clearly bounded
- [x] Dependencies and assumptions identified

## Feature Readiness

- [x] All functional requirements have clear acceptance criteria
- [x] User scenarios cover primary flows
- [x] Feature meets measurable outcomes defined in Success Criteria
- [x] No implementation details leak into specification

## Notes

- Feature numbered correctly as 004.
- Clarifications on member grouping and relationship visibility incorporated.
46 changes: 46 additions & 0 deletions specs/004-config-class-members/contracts/mcp-tool.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "GetClassDiagram",
"description": "Generates a Mermaid class diagram for the types defined in a specific C# file, with options to discover inheritance and related types in the workspace.",
"parameters": {
"type": "object",
"properties": {
"filePath": {
"type": "string",
"description": "Absolute path to the .cs file to analyze."
},
"includeInheritance": {
"type": "boolean",
"description": "Whether to search the workspace for base classes and interfaces.",
"default": false
},
"includeDependencies": {
"type": "boolean",
"description": "Whether to search for and include other classes used as properties or fields.",
"default": false
},
"includeProperties": {
"type": "boolean",
"description": "Whether to display properties and fields in the class diagram.",
"default": true
},
"includeFunctions": {
"type": "boolean",
"description": "Whether to display functions/methods in the class diagram.",
"default": true
},
"depth": {
"type": "integer",
"description": "How many levels of relationships to follow.",
"default": 1
},
"showTitle": {
"type": "boolean",
"description": "Whether to include the title in the diagram.",
"default": true
}
},
"required": [
"filePath"
]
}
}
28 changes: 28 additions & 0 deletions specs/004-config-class-members/data-model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Data Model: Class Member Visibility

## Entity: AnalysisOptions (Extension)

The `AnalysisOptions` class in `ProjGraph.Lib.ClassDiagram` will be extended with the following fields:

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| IncludeProperties | bool | true | When true, includes properties and fields in the type definition. |
| IncludeFunctions | bool | true | When true, includes methods in the type definition. Constructors are not currently extracted by the analyzer and are out of scope. |

## Entity: MemberDefinition (Reference)

Existing entity in `ProjGraph.Core.Models`.

| Field | Type | Category mapping |
|-------|------|------------------|
| Kind | MemberKind | Property, Field -> "Properties" |
| Kind | MemberKind | Method -> "Functions" |

Note: The `MemberKind` enum contains `Field = 0`, `Property = 1`, `Method = 2`. There is no `Constructor` value — constructors are not extracted by `TypeAnalyzer` and are out of scope.

## Validation Rules

1. Mapping for `MemberKind`:
- `MemberKind.Property` and `MemberKind.Field` MUST be filtered by `IncludeProperties`.
- `MemberKind.Method` MUST be filtered by `IncludeFunctions`.
2. Discovery Rule: Hiding a property MUST NOT prevent the identification of an Association relationship if the property's type is a local or workspace type.
68 changes: 68 additions & 0 deletions specs/004-config-class-members/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Implementation Plan: Configure Class Member Visibility

**Branch**: `004-config-class-members` | **Date**: 2026-02-16 | **Spec**: [spec.md](spec.md)
**Input**: Feature specification from `/specs/004-config-class-members/spec.md`

## Summary

This feature improves the `GetClassDiagram` tool by allowing users to toggle the visibility of class properties and functions. The goal is to provide cleaner, more focused diagrams for large codebases. The technical approach involves extending `AnalysisOptions` in `ProjGraph.Lib.ClassDiagram` and updating `TypeAnalyzer` to filter members before building the model, while maintaining relationship discovery in `TypeProcessor`.

## Technical Context

**Language/Version**: .NET 10.0 (C# 14+)
**Primary Dependencies**: Microsoft.CodeAnalysis.CSharp (Roslyn), ProjGraph.Lib.Core
**Storage**: N/A
**Testing**: xUnit, FluentAssertions
**Target Platform**: .NET Core (Windows, Linux, macOS)
**Project Type**: Library/MCP Server
**Performance Goals**: < 5s for medium-sized workspaces; SC-004: > 50% character reduction in diagrams when members are hidden.
**Constraints**: MCP 1.0 Compliance, Zero Warnings, Strict SemVer
**Scale/Scope**: Workspace-wide class analysis and rendering.

## Constitution Check

*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*

- [x] **I. Modern .NET 10 Baseline**: Targeting .NET 10.0+?
- [x] **II. MCP Native Interoperability**: Tool functionality exposed via MCP?
- [x] **III. Library-First Core**: Logic in libraries, not just CLI/MCP?
- [x] **IV. Absolute Testing Requirement**: Tests planned for unit, integration, and MCP contract?

## Project Structure

### Documentation (this feature)

```text
specs/004-config-class-members/
├── plan.md # This file (/speckit.plan command output)
├── research.md # Phase 0 output (/speckit.plan command)
├── data-model.md # Phase 1 output (/speckit.plan command)
├── quickstart.md # Phase 1 output (/speckit.plan command)
├── contracts/ # Phase 1 output (/speckit.plan command - MUST include MCP schema)
└── tasks.md # Phase 2 output (/speckit.tasks command - NOT created by /speckit.plan)
```

### Source Code (repository root)

```text
src/
├── ProjGraph.Core/ # Shared Domain Models (MemberDefinition, MemberKind)
├── ProjGraph.Lib.ClassDiagram/ # Core Analysis and Rendering Logic
└── ProjGraph.Mcp/ # MCP Server interface (Tool parameters)
```

tests/
├── ProjGraph.Tests.Contract/ # MCP Contract Tests
├── ProjGraph.Tests.Integration.Mcp/ # MCP Integration
└── ProjGraph.Tests.Unit.ClassDiagram/ # Analysis Logic Unit Tests

**Structure Decision**: Logic primarily resides in `ProjGraph.Lib.ClassDiagram.Application.AnalysisOptions` and `Rendering`.

## Complexity Tracking

> **Fill ONLY if Constitution Check has violations that must be justified**

| Violation | Why Needed | Simpler Alternative Rejected Because |
| ----------- | ------------ | ------------------------------------- |
| [e.g., 4th project] | [current need] | [why 3 projects insufficient] |
| [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] |
37 changes: 37 additions & 0 deletions specs/004-config-class-members/quickstart.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Quickstart: Configuring Class Member Visibility

## Objective

Generate a class diagram that focuses only on high-level relationships by hiding detailed properties and methods.

## Usage with MCP

To generate a diagram with only classes and their relationships (no members):

```json
{
"name": "GetClassDiagram",
"arguments": {
"filePath": "C:/path/to/YourController.cs",
"includeProperties": false,
"includeFunctions": false
}
}
```

To see only the behavioral API (methods):

```json
{
"name": "GetClassDiagram",
"arguments": {
"filePath": "C:/path/to/YourService.cs",
"includeProperties": false,
"includeFunctions": true
}
}
```

## Default Behavior

If omitted, `includeProperties` and `includeFunctions` default to `true`, providing the same detailed output as before.
Loading
Loading