Skip to content
Open
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
34 changes: 34 additions & 0 deletions .agents/agents/sdk-consumer-setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# sdk-consumer-setup (generic agent spec)

## Goal

Help a consuming repository adopt or troubleshoot `Purview.DotNetProjectSdk` correctly, without breaking existing build behaviour.

## Workflow

1. Confirm the SDK is imported in `Directory.Build.props`/`Directory.Build.targets` via
`<Import Sdk="Purview.DotNetProjectSdk" Project="Sdk.props" />` and the matching `Sdk.targets` import.
2. Check pre-import bootstrap properties are set **before** the `Sdk.props` import when they must affect
evaluation: `NamespacePrefix`, `UsePackageJsonVersion`, `RootPackageJson`.
3. If version resolution looks wrong, verify `package.json` discovery: explicit `RootPackageJson`, then CI
variables, `.git` root, or a nearby `package.json`. `UsePackageJsonVersion=Strict` fails fast instead of
silently skipping resolution.
4. If the bundled `.agents/**` content isn't appearing in the repo root, check `EnableAgentFolderInPackage`
(default `true`) and `AgentPackDestinationFolder` (default `.agents`) — the copy runs before build via
`EnsureAgentFolderInPackageTarget`.
5. For test-framework or project-shape questions, confirm the project follows repo naming and placement
conventions the SDK expects, rather than introducing bespoke structure.
6. Re-run `dotnet build` (or the repo's canonical build command) after each configuration change to confirm
the fix.

## Constraints

- Prefer minimal, targeted property changes over broad `Directory.Build.props` rewrites.
- Do not disable `PurviewAutoSdkPack` or `EnableAgentFolderInPackage` unless the consumer explicitly asks to
opt out.
- Do not duplicate SDK-managed properties in individual project files unless the scenario is intentionally
project-specific.

## Related skill

See `../skills/sdk-configuration-reference/SKILL.md` for the full property reference.
79 changes: 79 additions & 0 deletions .agents/agents/source-generator-framework-writer.agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
name: Source Generator Framework Writer
description: "Specialist for Purview.SourceGeneratorFramework generation code using CodeWriter and XmlCodeWriter-style XML doc extensions; ideal for creating or refactoring generator emitters."
tools:
[
"search/codebase",
"edit/editFiles",
"search",
"execute/getTerminalOutput",
"execute/runInTerminal",
"read/terminalLastCommand",
"read/terminalSelection",
"execute/createAndRunTask",
"execute/runTask",
"read/getTaskOutput",
"vscodeTasks/createAndRunTask",
"vscodeTasks/getTaskOutput",
"vscodeTasks/runTask",
]
---

You are a specialist for `Purview.SourceGeneratorFramework` emitter authoring.

## Primary objective

Produce clear, deterministic, maintainable source-generator emission code using `CodeWriter` and XML extension helpers from `XmlCommentWriter`.

## Background knowledge

Before changing any source generator, analyser, or CodeWriter-related code, load and apply the `source-generator-codewriter-modernization` skill. It contains the full source-generator, analyser, and CodeWriter best-practices guidance for this framework, including incremental pipeline design, value equality, deterministic output, and Roslyn version compatibility.

The most important rules are:

- **Analyser for validation; generator for generation.**
- **Syntax for syntax, symbols for declarations, operations for executable semantics.**
- **Use `ForAttributeWithMetadataName` whenever possible.**
- **Remove `ISymbol`, `Compilation`, `SemanticModel`, `IOperation`, `SyntaxTree`, `SyntaxNode`, and `Location` from incremental pipeline models as early as possible.**
- **Pipeline models must be immutable and value-equatable; use `EquatableArray<T>` for collections.**
- **Avoid `Collect()` until global knowledge is genuinely required.**
- **Never combine `CompilationProvider` into the pipeline merely because it is convenient.**
- **Generate deterministic output and stable hint names.**
- **Test incrementally, not just generated text.**
- **Compile against the oldest Roslyn API version containing the functionality you need.**
- **Create `CodeWriter` inside the output callback and pass it to helpers within that callback; never create it earlier in the pipeline or store it in incremental provider state or custom contexts.**

## Available resources

- `skills/source-generator-codewriter-modernization/SKILL.md` — source-generator, analyser, and CodeWriter best practices for this framework.
- `prompts/refactor-source-generator-to-codewriter.prompt.md` — prompt template for legacy-emitter refactor tasks.

## Must-follow rules

1. Load and apply the `source-generator-codewriter-modernization` skill.
2. Prefer structured declaration APIs over handwritten declaration strings.
3. Prefer XML helper extensions (`XmlSummary`, `XmlParam`, etc.) over raw `///` output.
4. Create `CodeWriter` inside each output callback; never create it earlier in the pipeline or cache it in incremental provider state or custom contexts.
5. Preserve semantic behavior while modernizing implementation style.
6. Keep edits minimal and localized to emitter concerns.

## Refactoring posture

When modernizing legacy code:

- Replace manual indentation/braces with scope APIs.
- Replace signature text with declaration option records.
- Replace ad-hoc XML tags with helper APIs.
- Preserve diagnostics and emitted symbol names.

## Quality gates

- Build/tests pass for impacted projects.
- No scope leaks when materializing generated source.
- Generated artifacts remain deterministic and reviewable.

## Skill routing

When relevant, first load and apply:

- `source-generator-codewriter-modernization`
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
agent: ask
description: "Refactor a legacy source generator emitter from string/StringBuilder to CodeWriter + XmlCodeWriter-style XML extensions with behavior parity."
---

You are modernizing a source generator implementation in this repository. Apply the guidance from the `source-generator-codewriter-modernization` skill for incremental pipelines, value equality, deterministic output, and CodeWriter scope safety.

## Inputs

- Target file(s): `${input:targetFiles:Path(s) to emitter file(s)}`
- Generator type name: `${input:generatorName:Generator class name}`
- Generator version: `${input:generatorVersion:Version string (for generated attributes/header)}`
- Keep output byte-identical where possible: `${input:preserveFormatting:true|false}`

## Task

Refactor the selected legacy emitter implementation from manual `string` / `StringBuilder` output construction to `CodeWriter` and XML documentation extension helpers from `XmlCommentWriter` (XmlCodeWriter-style API usage).

### Requirements

1. Use structured declaration APIs where applicable:
- `WriteClass/WriteStruct/WriteRecordClass/WriteInterface/WriteEnum`
- `WriteMethod`, `WriteProperty`, `WriteField`, `WriteConstructor`
2. Use XML helper extensions instead of raw `///` composition:
- `XmlSummary`, `XmlParam`, `XmlReturn`, `XmlRemarks`, `XmlCode` or `XmlCodeBlock`
3. Use `TypeReferenceOptions` when type text becomes complex (nullability, generics, arrays).
4. Ensure writer lifetime is output-scoped (`generationContext.CreateCodeWriter()` inside callback).
5. Preserve behavior, diagnostics, and generated names.
6. Keep changes minimal and focused; do not reformat unrelated logic.

### Migration strategy

- Identify emitter phases: header, namespace, type declarations, member declarations.
- Replace indentation/braces with scoped APIs.
- Replace signature strings with declaration options.
- Replace XML comments with XmlCommentWriter extension methods.
- Keep semantic equivalence; call out any intentional deltas.

### Verification

- Run relevant tests.
- Confirm generated files still compile.
- Confirm no `CodeWriter` scope leaks (`OpenScopeCount == 0` when materialized).

### Output format

Return:

1. Files changed
2. Why each change was necessary
3. Risks/behavior differences (if any)
4. Verification performed
26 changes: 26 additions & 0 deletions .agents/prompts/sdk-diagnose-agent-folder-copy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# sdk-diagnose-agent-folder-copy (generic prompt spec)

Diagnose why the bundled `.agents/**` folder from `Purview.DotNetProjectSdk` did not appear at the expected
destination in a consuming repository.

## Required behaviour

1. Confirm the NuGet package actually contains `.agents/**` content (inspect the `.nupkg` if available).
2. Confirm the consuming project is packable/buildable and imports the SDK via
`Sdk.props`/`Sdk.targets`, since the copy runs in `EnsureAgentFolderInPackageTarget` before build.
3. Check `EnableAgentFolderInPackage` is not set to `false` anywhere in the build (project file,
`Directory.Build.props`, or command-line `-p:` overrides).
4. Confirm the destination folder: default is `.agents` at the repo root, overridable per-build with
`-p:AgentPackDestinationFolder=<folder>`.
5. Verify repo-root discovery succeeded: explicit `RepoRoot`, then a nearby `AGENTS.md`, then source-control
root metadata.
6. Re-run the build and confirm the destination folder now contains the copied files (including the
generated `.gitignore` for skill/prompt/agent subfolders).

## Suggested output

- A short root-cause explanation (missing import, disabled flag, wrong destination override, or repo-root
discovery miss).
- The exact command used to reproduce/verify the fix (for example
`dotnet build <project> -p:AgentPackDestinationFolder=<folder>`).
- Confirmation that the expected files exist at the resolved destination path.
8 changes: 8 additions & 0 deletions .agents/skills/project-placement-defaults/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Ignore all files
*

# Don't ignore directories, so Git can traverse them
!*/

# Keep this file
!.gitignore
113 changes: 113 additions & 0 deletions .agents/skills/project-placement-defaults/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
---
name: project-placement-defaults
description: "Use when creating, moving, or splitting projects in a repository that uses Purview.DotNetProjectSdk, especially for src/tests placement, test suffix naming, namespace alignment, and automatic project-reference behavior."
---

# Project placement defaults for Purview.DotNetProjectSdk

Use this skill whenever a task asks to add, move, split, or create a project in a repository that uses `Purview.DotNetProjectSdk` and you need placement, naming, and reference decisions to remain consistent with the SDK's automatic conventions.

## Core principle

Preserve the host repository's existing layout first; only introduce new structure when no established pattern exists. In Purview-based repos, prefer layouts that let the SDK's naming and auto-reference rules work without extra overrides.

## Placement heuristics

Use the repository's current structure as the source of truth, with these Purview-friendly defaults:

1. Prefer source projects under `src/`.
2. Prefer test projects under `tests/`.
3. Place new projects beside similar projects (same language, layer, and test type).
4. Keep one test type per project by default.
5. Keep shared helper projects in explicit shared/shared-testing locations when those concepts exist.

When a repo has no clear structure, use these conservative defaults because they align well with the SDK's automatic project-reference search paths:

- Source/library projects under `src/`
- Test projects under `tests/`
- Integration/end-to-end tests in explicit sibling projects/folders such as `tests/Api.IntegrationTests/` or `tests/Api.E2ETests/`

## Purview-specific naming rules

The SDK relies heavily on project names.

- Keep the `.csproj` filename equal to its containing directory name unless `DisableProjectFileNamingConventionCheck=true` is explicitly used.
- Use conventional test suffixes such as `.UnitTests`, `.IntegrationTests`, `.E2ETests`, `.FunctionalTests`, `.ContractTests`, and other supported `*Tests` suffixes.
- Keep shared helper projects on the SDK's exact recognized names when you want shared behavior:
- Shared projects: `Shared`, `SharedFramework`, `SharedInfrastructure`, `SharedInfra`, `SharedUtilities`, `SharedUtils`, `SharedLibrary`, `SharedLib`, `SharedHelpers`
- Shared testing projects: `SharedTestingFramework`, `SharedTestingInfrastructure`, `SharedTestingInfra`, `SharedTestingUtilities`, `SharedTestingUtils`, `SharedTestingLibrary`, `SharedTestingLib`, `SharedTestingHelpers`
- Do not invent near-miss names if you expect the SDK to classify the project automatically.

## Test-type boundaries

Separate tests by behavior and dependency scope:

- **Unit tests**: isolate logic with minimal external dependencies.
- **Integration tests**: verify behavior across component boundaries (I/O, framework integration, build/evaluation behavior).
- **End-to-end/system tests**: verify full workflow behavior across the assembled system.

If specialized test categories exist (for example, analyzer diagnostics vs code-fix integration), keep category-specific tests in distinct projects/folders.

The SDK recognizes many test suffixes, including `Unit`, `Integration`, `E2E`, `EndToEnd`, `Acceptance`, `Functional`, `Performance`, `Load`, `Smoke`, `Stress`, `Regression`, `Security`, `Chaos`, `Scenario`, `System`, `Threat`, `BlackBox`, `WhiteBox`, `Accessibility`, `Interactive`, `Environment`, `Architecture`, and `Contract`.

## Naming and namespace defaults

Align identities with existing repository conventions:

- Project names should follow prevailing patterns in sibling projects.
- Test project names should clearly indicate scope/type with recognized test suffixes.
- `NamespacePrefix` should remain the root identity source for the repo.
- `RootNamespace` usually flows from the logical project identity generated by the SDK; avoid custom namespace overrides unless required.
- When moving files between projects, update namespaces so they match the destination project's conventions.

Do not invent a new naming scheme when an existing one is already in use.

## Project defaults

When creating a new project:

1. Match the SDK/project style used by sibling projects.
2. Reuse central dependency/version management if present.
3. Add only dependencies required for the project's scope.
4. Add the project to the repository solution/workspace entry point.
5. Keep configuration consistent with neighboring projects (target frameworks, nullable, analyzers, warnings).

When working in a Purview-based repo, also assume:

- `TargetFramework` defaults to `net10.0` if not otherwise set, or `netstandard2.0` when the project explicitly declares `IsRoslynComponent=true`.
- Test projects receive framework packages and coverage defaults from the SDK.
- Non-test projects receive SourceLink and telemetry defaults unless explicitly opted out.

## Move/split workflow checklist

When splitting or relocating tests/projects:

1. Create destination project/folder using established layout patterns.
2. Move files physically.
3. Update namespaces/imports/references for the destination.
4. Verify the destination project name still produces the intended `TestingType`, `TargetProjectName`, and `RootNamespace`.
5. Remove stale dependencies from the source project.
6. Update solution/workspace membership and project references.
6. Run build and relevant tests.

## Automatic project-reference behavior to preserve

The SDK automatically searches for project references based on naming and placement.

- Test projects probe for their target project in these relative locations:
- `../$(TargetProjectName)/$(TargetProjectName).csproj`
- `../../$(TargetProjectName)/$(TargetProjectName).csproj`
- `../src/$(TargetProjectName)/$(TargetProjectName).csproj`
- `../../src/$(TargetProjectName)/$(TargetProjectName).csproj`
- Non-test projects automatically look for sibling shared projects via `../Shared*/Shared*.csproj`.
- Test projects automatically look for sibling shared-testing projects via `../SharedTesting*/SharedTesting*.csproj`.

If you move projects away from these conventions, be prepared to add explicit project references.

## Guardrails

- Prefer minimal, targeted diffs.
- Avoid cross-cutting renames unrelated to the move/split intent.
- Keep test intent unchanged while relocating.
- If structure is ambiguous, infer from nearest sibling projects and document the assumption in the change summary.
- When in doubt, preserve compatibility with the SDK's automatic naming, namespace, and project-reference behavior.
8 changes: 8 additions & 0 deletions .agents/skills/sdk-configuration-reference/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Ignore all files
*

# Don't ignore directories, so Git can traverse them
!*/

# Keep this file
!.gitignore
Loading
Loading