Skip to content

Commit 696233c

Browse files
Add Copilot repository instructions
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>
1 parent 6ad4f46 commit 696233c

1 file changed

Lines changed: 146 additions & 0 deletions

File tree

.github/copilot-instructions.md

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# Copilot Instructions for PowerShell Editor Services
2+
3+
## Build & Test
4+
5+
Requires .NET SDK 8.0+. Use `dotnet` directly for building and testing — it's faster and
6+
requires no extra tooling. The `Invoke-Build` script requires the `InvokeBuild` and `platyPS`
7+
PowerShell modules (platyPS is `#Requires`'d at the top, so the whole script fails without it),
8+
and is mainly needed to assemble the full PowerShell module for release.
9+
10+
```powershell
11+
# Build (run both; Hosting depends on the core library)
12+
dotnet publish src/PowerShellEditorServices/PowerShellEditorServices.csproj -f netstandard2.0
13+
dotnet publish src/PowerShellEditorServices.Hosting/PowerShellEditorServices.Hosting.csproj -f net8.0
14+
15+
# Run all unit tests
16+
dotnet test test/PowerShellEditorServices.Test/ --framework net8.0
17+
18+
# Run a single test by name
19+
dotnet test test/PowerShellEditorServices.Test/ --framework net8.0 --filter "FullyQualifiedName~CompletesCommandInFile"
20+
21+
# Run tests by trait category
22+
dotnet test test/PowerShellEditorServices.Test/ --framework net8.0 --filter "Category=Completions"
23+
24+
# Run E2E tests
25+
dotnet test test/PowerShellEditorServices.Test.E2E/ --framework net8.0
26+
```
27+
28+
For assembling the full module or running the complete CI suite (including Windows PowerShell
29+
5.1 targets), use `Invoke-Build` with the `InvokeBuild` and `platyPS` modules installed:
30+
31+
```powershell
32+
Invoke-Build Build # full build + module assembly + help generation
33+
Invoke-Build TestPS74 # unit tests via build script
34+
Invoke-Build TestE2EPwsh # E2E tests via build script
35+
Invoke-Build Build -Configuration Release # required before PRs (enforces XML doc comments)
36+
```
37+
38+
`src/PowerShellEditorServices.Hosting/BuildInfo.cs` is auto-generated by the build script and
39+
git-ignored for changes. Do not edit it manually.
40+
41+
## Architecture
42+
43+
PowerShell Editor Services (PSES) is a **Language Server Protocol (LSP)** and **Debug Adapter
44+
Protocol (DAP)** server for PowerShell, consumed by VS Code and other editors.
45+
46+
### Projects
47+
48+
- **`src/PowerShellEditorServices`** (`netstandard2.0`) — Core library containing all LSP/DAP
49+
handlers, services, and the PowerShell execution engine. Namespace:
50+
`Microsoft.PowerShell.EditorServices`.
51+
- **`src/PowerShellEditorServices.Hosting`** (`net8.0`, `net462`) — Entry point layer that loads
52+
PSES into a PowerShell process via `StartEditorServicesCommand`. Uses a custom
53+
`AssemblyLoadContext` (`PsesLoadContext`) on .NET Core to isolate dependencies.
54+
- **`module/PowerShellEditorServices/`** — The shipped PowerShell module. The build assembles
55+
compiled binaries into `bin/Core/` (net8.0) and `bin/Desktop/` (net462). The module manifest
56+
loads the appropriate DLL based on PowerShell edition.
57+
58+
### Key Services (registered in `PsesServiceCollectionExtensions`)
59+
60+
- **`PsesInternalHost`** — The central PowerShell execution host. Also implements
61+
`IRunspaceContext` and `IInternalPowerShellExecutionService`.
62+
- **`WorkspaceService`** — Manages open documents and workspace files.
63+
- **`SymbolsService`** — Provides symbol navigation (go-to-definition, find references).
64+
- **`AnalysisService`** — Integrates PSScriptAnalyzer for real-time diagnostics.
65+
- **`ConfigurationService`** — Manages editor/client settings.
66+
- **`ExtensionService`** — Supports the `$psEditor` API for editor extensions.
67+
68+
### LSP/DAP Handler Pattern
69+
70+
Handlers live under `Services/<Feature>/Handlers/` and follow a consistent pattern:
71+
72+
- Class name: `Pses<Feature>Handler`, marked `internal`
73+
- Inherits from an OmniSharp base class (e.g., `CompletionHandlerBase`, `HoverHandlerBase`)
74+
- Dependencies injected via constructor (`ILoggerFactory`, services)
75+
- Overrides `CreateRegistrationOptions()` and `Handle()`
76+
- Uses `LspUtils.PowerShellDocumentSelector` for document registration
77+
78+
### Server Setup
79+
80+
- `PsesLanguageServer` — Configures and runs the LSP server using OmniSharp
81+
- `PsesDebugServer` — Configures and runs the DAP server
82+
- Both use `Microsoft.Extensions.DependencyInjection` for service registration
83+
84+
## Conventions
85+
86+
### C# Style
87+
88+
- All files require the copyright header: `// Copyright (c) Microsoft Corporation.` /
89+
`// Licensed under the MIT License.`
90+
- `.editorconfig` enforces many rules as **errors**, including unused variables, async/threading
91+
rules (`VSTHRD*`), and modern C# idioms (pattern matching, null checks, expression bodies).
92+
- Roslynator analyzers are enabled for formatting and code quality.
93+
- Use `Microsoft.Extensions.Logging` (`ILogger<T>` via `ILoggerFactory`) for all logging.
94+
95+
### Testing
96+
97+
- **Framework:** xUnit with `Xunit.SkippableFact` for conditionally skipped tests.
98+
- **Host setup:** Use `PsesHostFactory.Create(loggerFactory)` to get an isolated
99+
`PsesInternalHost` for testing. Tests implement `IAsyncLifetime` for async setup/teardown.
100+
- **Traits:** Tests use `[Trait("Category", "...")]` for filtering (e.g., `"Completions"`,
101+
`"Symbols"`).
102+
- **Fixtures:** Test PowerShell scripts live in `test/PowerShellEditorServices.Test/Fixtures/`.
103+
- **E2E tests** are in a separate project (`PowerShellEditorServices.Test.E2E`) and test the
104+
full LSP client-server interaction.
105+
106+
### Multi-targeting
107+
108+
The core library targets `netstandard2.0` for compatibility with both .NET Core and .NET
109+
Framework. The hosting project and tests dual-target `net8.0` and `net462` (Windows PowerShell
110+
5.1). Non-Windows platforms skip `net462` targets.
111+
112+
## Pull Request Labels
113+
114+
Every pull request **must** be labeled before it is opened so it is triaged
115+
correctly and lands in the right changelog section.
116+
117+
Each PR requires:
118+
119+
- **At least one `Area-*` label** describing the part of the codebase it touches
120+
(e.g. `Area-Debugging`, `Area-Language Server`, `Area-Workspaces`,
121+
`Area-Documentation`). This is used for triage and filtering.
122+
- **Exactly one `Issue-*` label** describing the kind of change:
123+
- `Issue-Bug` — a bug fix.
124+
- `Issue-Enhancement` — a new feature or changed behavior.
125+
- `Issue-Performance` — a performance improvement.
126+
127+
The `Issue-*` label is not optional: GitHub's auto-generated release notes use it
128+
to pick the changelog category. See [`.github/release.yml`](./release.yml) for the
129+
authoritative mapping (`Issue-Enhancement` → "Enhancements & Features ✨",
130+
`Issue-Bug` → "Squashed Bugs 🐛"). Any PR **without** an `Issue-*` label falls
131+
through the `"*"` catch-all into "Other Changes 🙏" and is silently
132+
miscategorized, so always set one correctly.
133+
134+
Additionally:
135+
136+
- Add the relevant **`OS-*` label** (`OS-Windows`, `OS-macOS`, `OS-Linux`) when a
137+
change is platform-specific.
138+
- Use the **`Ignore`** label only for changes that should be excluded from the
139+
release notes entirely (e.g. pure CI, test, or docs chores the maintainers do
140+
not want in the changelog). `.github/release.yml` excludes this label from the
141+
changelog.
142+
143+
The full, authoritative set of labels drifts over time — do not hard-code it
144+
here. List the current labels with `gh label list --repo PowerShell/PowerShellEditorServices`
145+
or the repo's [Labels page](https://github.com/PowerShell/PowerShellEditorServices/labels)
146+
and pick the closest matches.

0 commit comments

Comments
 (0)