From 696233c3295517f8829c8d4ad564fe0fb2568942 Mon Sep 17 00:00:00 2001 From: Andy Jordan <2226434+andyleejordan@users.noreply.github.com> Date: Mon, 15 Jun 2026 18:34:38 -0700 Subject: [PATCH] Add Copilot repository instructions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We had no `.github/copilot-instructions.md`, so agents working in this repo had to rediscover how to build and test, how the projects fit together, and how we label pull requests. This adds a single instructions file covering all of it: - **Build & Test** — `dotnet` directly for the fast inner loop versus `Invoke-Build` (which needs `InvokeBuild`/`platyPS`) for assembling the full module and running the complete CI suite. - **Architecture** — the project layout, key services, the LSP/DAP handler pattern, and how the server is wired up. - **Conventions** — C# style enforced by `.editorconfig`, the xUnit testing setup, and the multi-targeting story. - **Pull Request Labels** — every PR needs at least one `Area-*` label and exactly one `Issue-*` label (plus `OS-*` and `Ignore` when relevant). The `Issue-*` label is what GitHub's auto-generated release notes key off of (see `.github/release.yml`); a PR without one silently falls through to "Other Changes 🙏". The build, architecture, and conventions content previously rode along in #2298; consolidating it here keeps that PR focused on its LSP changes and gives us a single source of truth for the instructions. Drafted by Copilot (Claude Opus 4.8). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/copilot-instructions.md | 146 ++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 .github/copilot-instructions.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 000000000..9f4f60eed --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,146 @@ +# Copilot Instructions for PowerShell Editor Services + +## Build & Test + +Requires .NET SDK 8.0+. Use `dotnet` directly for building and testing — it's faster and +requires no extra tooling. The `Invoke-Build` script requires the `InvokeBuild` and `platyPS` +PowerShell modules (platyPS is `#Requires`'d at the top, so the whole script fails without it), +and is mainly needed to assemble the full PowerShell module for release. + +```powershell +# Build (run both; Hosting depends on the core library) +dotnet publish src/PowerShellEditorServices/PowerShellEditorServices.csproj -f netstandard2.0 +dotnet publish src/PowerShellEditorServices.Hosting/PowerShellEditorServices.Hosting.csproj -f net8.0 + +# Run all unit tests +dotnet test test/PowerShellEditorServices.Test/ --framework net8.0 + +# Run a single test by name +dotnet test test/PowerShellEditorServices.Test/ --framework net8.0 --filter "FullyQualifiedName~CompletesCommandInFile" + +# Run tests by trait category +dotnet test test/PowerShellEditorServices.Test/ --framework net8.0 --filter "Category=Completions" + +# Run E2E tests +dotnet test test/PowerShellEditorServices.Test.E2E/ --framework net8.0 +``` + +For assembling the full module or running the complete CI suite (including Windows PowerShell +5.1 targets), use `Invoke-Build` with the `InvokeBuild` and `platyPS` modules installed: + +```powershell +Invoke-Build Build # full build + module assembly + help generation +Invoke-Build TestPS74 # unit tests via build script +Invoke-Build TestE2EPwsh # E2E tests via build script +Invoke-Build Build -Configuration Release # required before PRs (enforces XML doc comments) +``` + +`src/PowerShellEditorServices.Hosting/BuildInfo.cs` is auto-generated by the build script and +git-ignored for changes. Do not edit it manually. + +## Architecture + +PowerShell Editor Services (PSES) is a **Language Server Protocol (LSP)** and **Debug Adapter +Protocol (DAP)** server for PowerShell, consumed by VS Code and other editors. + +### Projects + +- **`src/PowerShellEditorServices`** (`netstandard2.0`) — Core library containing all LSP/DAP + handlers, services, and the PowerShell execution engine. Namespace: + `Microsoft.PowerShell.EditorServices`. +- **`src/PowerShellEditorServices.Hosting`** (`net8.0`, `net462`) — Entry point layer that loads + PSES into a PowerShell process via `StartEditorServicesCommand`. Uses a custom + `AssemblyLoadContext` (`PsesLoadContext`) on .NET Core to isolate dependencies. +- **`module/PowerShellEditorServices/`** — The shipped PowerShell module. The build assembles + compiled binaries into `bin/Core/` (net8.0) and `bin/Desktop/` (net462). The module manifest + loads the appropriate DLL based on PowerShell edition. + +### Key Services (registered in `PsesServiceCollectionExtensions`) + +- **`PsesInternalHost`** — The central PowerShell execution host. Also implements + `IRunspaceContext` and `IInternalPowerShellExecutionService`. +- **`WorkspaceService`** — Manages open documents and workspace files. +- **`SymbolsService`** — Provides symbol navigation (go-to-definition, find references). +- **`AnalysisService`** — Integrates PSScriptAnalyzer for real-time diagnostics. +- **`ConfigurationService`** — Manages editor/client settings. +- **`ExtensionService`** — Supports the `$psEditor` API for editor extensions. + +### LSP/DAP Handler Pattern + +Handlers live under `Services//Handlers/` and follow a consistent pattern: + +- Class name: `PsesHandler`, marked `internal` +- Inherits from an OmniSharp base class (e.g., `CompletionHandlerBase`, `HoverHandlerBase`) +- Dependencies injected via constructor (`ILoggerFactory`, services) +- Overrides `CreateRegistrationOptions()` and `Handle()` +- Uses `LspUtils.PowerShellDocumentSelector` for document registration + +### Server Setup + +- `PsesLanguageServer` — Configures and runs the LSP server using OmniSharp +- `PsesDebugServer` — Configures and runs the DAP server +- Both use `Microsoft.Extensions.DependencyInjection` for service registration + +## Conventions + +### C# Style + +- All files require the copyright header: `// Copyright (c) Microsoft Corporation.` / + `// Licensed under the MIT License.` +- `.editorconfig` enforces many rules as **errors**, including unused variables, async/threading + rules (`VSTHRD*`), and modern C# idioms (pattern matching, null checks, expression bodies). +- Roslynator analyzers are enabled for formatting and code quality. +- Use `Microsoft.Extensions.Logging` (`ILogger` via `ILoggerFactory`) for all logging. + +### Testing + +- **Framework:** xUnit with `Xunit.SkippableFact` for conditionally skipped tests. +- **Host setup:** Use `PsesHostFactory.Create(loggerFactory)` to get an isolated + `PsesInternalHost` for testing. Tests implement `IAsyncLifetime` for async setup/teardown. +- **Traits:** Tests use `[Trait("Category", "...")]` for filtering (e.g., `"Completions"`, + `"Symbols"`). +- **Fixtures:** Test PowerShell scripts live in `test/PowerShellEditorServices.Test/Fixtures/`. +- **E2E tests** are in a separate project (`PowerShellEditorServices.Test.E2E`) and test the + full LSP client-server interaction. + +### Multi-targeting + +The core library targets `netstandard2.0` for compatibility with both .NET Core and .NET +Framework. The hosting project and tests dual-target `net8.0` and `net462` (Windows PowerShell +5.1). Non-Windows platforms skip `net462` targets. + +## Pull Request Labels + +Every pull request **must** be labeled before it is opened so it is triaged +correctly and lands in the right changelog section. + +Each PR requires: + +- **At least one `Area-*` label** describing the part of the codebase it touches + (e.g. `Area-Debugging`, `Area-Language Server`, `Area-Workspaces`, + `Area-Documentation`). This is used for triage and filtering. +- **Exactly one `Issue-*` label** describing the kind of change: + - `Issue-Bug` — a bug fix. + - `Issue-Enhancement` — a new feature or changed behavior. + - `Issue-Performance` — a performance improvement. + +The `Issue-*` label is not optional: GitHub's auto-generated release notes use it +to pick the changelog category. See [`.github/release.yml`](./release.yml) for the +authoritative mapping (`Issue-Enhancement` → "Enhancements & Features ✨", +`Issue-Bug` → "Squashed Bugs 🐛"). Any PR **without** an `Issue-*` label falls +through the `"*"` catch-all into "Other Changes 🙏" and is silently +miscategorized, so always set one correctly. + +Additionally: + +- Add the relevant **`OS-*` label** (`OS-Windows`, `OS-macOS`, `OS-Linux`) when a + change is platform-specific. +- Use the **`Ignore`** label only for changes that should be excluded from the + release notes entirely (e.g. pure CI, test, or docs chores the maintainers do + not want in the changelog). `.github/release.yml` excludes this label from the + changelog. + +The full, authoritative set of labels drifts over time — do not hard-code it +here. List the current labels with `gh label list --repo PowerShell/PowerShellEditorServices` +or the repo's [Labels page](https://github.com/PowerShell/PowerShellEditorServices/labels) +and pick the closest matches.